Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

touch events not working #87

Open
graforlock opened this issue Sep 9, 2017 · 7 comments
Open

touch events not working #87

graforlock opened this issue Sep 9, 2017 · 7 comments

Comments

@graforlock
Copy link
Member

graforlock commented Sep 9, 2017

None of the following touch events are firing at the moment, when set in bel:

ontouchstart
ontouchmove
ontouchend
ontouchcancel

Steps to reproduce (extending the minimal example):

// list.js
var bel = require('bel');
var log = x => () => console.log(x)

module.exports = function (items) {
  return bel`<ul 
    onpointerup=${log('pointerup')} 
    onpointermove=${log('pointermove')} 
    ontouchstart=${log('touchstart')}
    ontouchmove=${log('touchmove')}
    ontouchend=${log('touchend')} 
    ontouchcancel=${log('touchcancel')}>
    ${items.map(function (item) {
      return bel`<li>${item}</li>`
    })}
  </ul>`
}

// app.js
var createList = require('./list.js')
var list = createList([
  'grizzly',
  'polar',
  'brown'
])
document.body.appendChild(list)

The pointer events are successfully called upon click, but not the touch ones.

What is weirder is the fact that (in console):

document.querySelector('ul').ontouchstart;
// () => console.log(x)

returns a valid callback, but this callback - so it is indeed registered, just never fires.

@bcomnes
Copy link
Collaborator

bcomnes commented Sep 9, 2017

So I just tested this on safari with remote inspector on an iPhone 7 and got the following results:

screen shot 2017-09-09 at 2 26 19 pm

Using a trivially modified version of your app:

// list.js
var bel = require('bel');
var log = x => () => console.log(x)

function createList (items) {
  return bel`<ul
    onpointerup=${log('pointerup')}
    onpointermove=${log('pointermove')}
    ontouchstart=${log('touchstart')}
    ontouchmove=${log('touchmove')}
    ontouchend=${log('touchend')}
    ontouchcancel=${log('touchcancel')}>
    ${items.map(function (item) {
      return bel`<li>${item}</li>`
    })}
  </ul>`
}

// app.js

var list = createList([
  'grizzly',
  'polar',
  'brown'
])
document.body.appendChild(list)

So like you said, the touch event handlers are getting registered, and do work on mobile devices!

That doesn't mean we are necessarily out of the woods yet though. When I looked into touch events a few years ago, iirc, there was significant complexity around touch events regarding when and where they work, especially on desktop where your primary interaction event are click handlers.

If we can identify desired / correct behavior and explicitly identify where bel isn't behaving correctly then we know we have a bug in bel. What I'm trying to say is, I'm not convinced there isn't an issue yet but not clear where it might be due to my own uncertainty of correct behavior here. I do think the event name missing from the nanomorph event list is an issue that should be corrected most likely.

@bcomnes
Copy link
Collaborator

bcomnes commented Sep 9, 2017

@bcomnes
Copy link
Collaborator

bcomnes commented Sep 9, 2017

I'm remembering now that the complexity I remember regarding touch events had to do with differences between how iOS and chrome responsive design mode fired touch and click events. I suspect this might be partially at play here.

@graforlock
Copy link
Member Author

graforlock commented Sep 9, 2017

If you put that manually in the inspector's element html (or just in plain html template somewhere), so the result is as follows :

<ul ontouchstart="console.log('start')"> ... some list here ... </ul>

It works perfectly fine in chrome. It also works with ulElement.addEventListener('touchstart', log).

So, I don't really know what is the root cause here. Seems odd, but it must be to do with how its registered/copied by bel if both of the above work.

EDIT: So, looks like touchstart is registered a bit differently. For example in Chrome:

  • bel (not working) generated element:
    ulElement.ontouchstart <- returns a function assigned in templating
    ulElement.getAttribute('ontouchstart') <- returns null

  • vanilla (working) html attribute:
    ulElement.ontouchstart <- returns null
    ulElement.getAttribute('ontouchstart') <- returns assigned function

Also, regular DOM elements don't seem to have these by default, contrary to the onclick, onmousestart etc, so they are implemented and interfaced in a different way than normal elements.

Here's what worked for example:

var bel = require('bel');

window.log = (e) => console.log('message');

module.exports = function (items) {
  const el = bel`<ul>
    ${items.map(function (item) {
      return bel`<li>${item}</li>`
    })}
  </ul>`;
  el.setAttribute('ontouchstart','log()');
  return el;
}

But in this case one cannot capture event. The issue seems to be Chrome (possible inspector) only, in Firefox it works with whatever bel is doing.

@bcomnes
Copy link
Collaborator

bcomnes commented Sep 11, 2017

Anyone know a workaround for chrome?

@graforlock
Copy link
Member Author

graforlock commented Sep 11, 2017

Nothing I tried worked so far, I believe Chrome desktop is the only one affected. Filed issue for Chrome itself but it'd takes ages before they move their ass.

For the time being, maybe we can detect and fix such cases? I could look into it in bel but have baby coming any day, so most likely won't come up with a PR.

Here's the thing @bcomnes @yoshuawuyts @shama anyone of you got a touch screen laptop device with latest Chrome to check out whether its just a inspector issue, or general Chrome desktop thing?

@yoshuawuyts
Copy link
Member

yoshuawuyts commented Sep 14, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants