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 + Mouse enabled Windows #68

Open
guaka opened this issue Jul 18, 2014 · 38 comments
Open

Touch + Mouse enabled Windows #68

guaka opened this issue Jul 18, 2014 · 38 comments

Comments

@guaka
Copy link

guaka commented Jul 18, 2014

It doesn't work on Windows 8 with Chrome 35.0.1916.153m

@donquixote
Copy link

The "open" class is not added.
Nothing special showing on the console.
Tried http://cameronspear.com/demos/bootstrap-hover-dropdown/, doesn't work either.

@cheesington
Copy link

I'm getting the same thing. I think the problem is that touch is enabled in windows 8, and chrome is registering itself as a touch-enabled browser. Line 22 detects this and ejects without adding the hover functionality:

if('ontouchstart' in document) return this; // don't want to affect chaining

I'm not sure what the answer is, but I'm fairly sure this is the problem.

@tszming
Copy link

tszming commented Jul 31, 2014

@cheesington do you mean on a Windows 8 PC without touch support but Chrome think it is a touch enabled browser? Then it is a Chrome's bug.

On the other hand, how about on a PC with touch + mouse support, can this plugin handle this case?

@cheesington
Copy link

@tszming: You know, that's a good point. It's possible that chrome on a touch-enabled windows 7 computer would exhibit the same problem -- my assumptions about windows 8 are based on the previous comments and experience with my touch-enabled windows 8 machine, and could be overly specific.

I can say that my computer has both touch and mouse support, and exhibits the problem.

@donquixote
Copy link

Hi.
I am only reporting in 3rd person, but from the information I get, I would confirm that the touch thing is the right direction to investigate.
There are two scenarios:

  1. A machine which has touch and mouse. E.g. a touch-enabled laptop with a mouse connected.
  2. A machine which has only mouse, but which behaves as if it also had touch.

We should have a sensible behavior for both.

@CWSpear
Copy link
Collaborator

CWSpear commented Jul 31, 2014

It makes sense that it's what @cheesington is pointing out, but removing it isn't necessarily the answer.

The over-arching issue here is we want it to be disabled on a device that you would use touch on, as it interferes. The problem being hybrids, i.e. Surface Pro w/ Windows 8.

@CWSpear
Copy link
Collaborator

CWSpear commented Jul 31, 2014

Oh, and I don't have Windows 8, so testing it is slightly nontrivial for me. I know there are ways, but I don't have anything set up.

@guaka guaka changed the title It doesn't work on Windows 8 with Chrome 35.0.1916.153m Touchscreen enabled Windows 8 behavior on Chrome 35.0.1916.153m Aug 22, 2014
@guaka
Copy link
Author

guaka commented Aug 22, 2014

On this win8 laptop with touchscreen I get:

Chrome ('ontouchstart' in document) == true
Firefox ('ontouchstart' in document) == false
IE ('ontouchstart' in document) == false

I'd like to add some code that continues with the hover code anyway if it's a desktop or laptop machine and not a tablet or mobile phone.

@CWSpear
Copy link
Collaborator

CWSpear commented Aug 22, 2014

@guaka Do you have one of those Surfaces or other touchscreen-enabled laptops?

Several solutions have been proposed to fix those. I really don't like the approach of looking at the screen width as the breakpoints are customizable. But I dislike #75 the least, so I am considering an approach like that one.

@guaka
Copy link
Author

guaka commented Aug 22, 2014

I only have one Windows 8 machine, with touchscreen and keyboard.

Screen width should not be a factor ideally.

@CWSpear
Copy link
Collaborator

CWSpear commented Aug 22, 2014

What should be the factor then?

@guaka
Copy link
Author

guaka commented Aug 22, 2014

I'm reading this interesting and highly relevant SO question now:
Detecting that the browser has no mouse and is touch-only

On Fri, Aug 22, 2014 at 7:09 PM, Cameron Spear notifications@github.com wrote:

What should be the factor then?


Reply to this email directly or view it on GitHub.

@CWSpear
Copy link
Collaborator

CWSpear commented Aug 22, 2014

The guy (Wyatt) with the +200 bounty points says

Tracking the current capabilities of a given user is complex, unreliable, and of dubious merit

And then talks about progressive enhancement. I argue (and actually always have) that we do away with dropdowns altogether and find a solution that is more progressive-enhancement friendly! Then we don't even need this plugin!

The top voted answer (Dan) is certainly an approach we could use, but still isn't 100% accurate and dang hacky.

@Ronald-Diemicke
Copy link

So I'm running into this issue as well... and I'm on a macbook pro running a Windows 8 VM with Chrome. No touch what so ever - so this is a pretty big issue.

I'd like to suggest that the hover event should occur regardless of if the device is touch enabled or not. If a user has a touch screen, there's no hover event, so they shouldn't ever see it. If a user uses a mouse, they'll get the hover event. Why even try to detect this?

@CWSpear
Copy link
Collaborator

CWSpear commented Sep 5, 2014

There is a hover event, tho. Go to http://codepen.io/CWSpear/pen/AuHgi and tap on the text. It turns red.

Tested on Android.

@Ronald-Diemicke
Copy link

What I'm saying is that the hover event is useless for touch screen users. You can prove this by going to your codepen with the canary build of Chrome as it has emulation for touch events.

@CWSpear
Copy link
Collaborator

CWSpear commented Sep 5, 2014

So you're saying that hover event are useless for touch screen users, so we should just disable the hover event for them...? That's what we do, and you just said it's a pretty big issue.

I think you're confusing what my plugin does with what BS does natively. Add data-toggle="dropdown" to the HTML to allow click (and thus touch) to still toggle the menu.

@Ronald-Diemicke
Copy link

What I'm saying actually the opposite. Don't disable the hover event for touch screen users.

You don't need to disable it because it already doesn't work for them. What's happening is Win8 is giving a false positive saying 'hey you have a touch screen' regardless of if they do or not so its impacting the user experience for them.

If you just remove the check that decides if it should remove the touch event, I think everything would be ok.

@CWSpear
Copy link
Collaborator

CWSpear commented Sep 5, 2014

The issue then, is that both the hover and click events are fired the the menu with open/close instantly (it appears to do nothing or flickers).

@Ronald-Diemicke
Copy link

Wouldn't a timer solve this problem:
If hover is detected, pass the click to open the menu and now wait until the menu is closed until the hover state can be fired again.

I haven't really dug into your code, so bare with me if this a gross over simplification of what's going on.

@CWSpear
Copy link
Collaborator

CWSpear commented Sep 5, 2014

That's not really a viable solution. For one, this plugin just handles hover and it's BS core than handles click (and maybe if they have an explicit touchend/touchstart event?).

Even if we could, there are issues about click delay (many mobile browsers will wait ~300ms (it's not an exact or standard number as far as anyone can tell) before firing click events (has to do with double clicks).

The "unhover" or mouseleave is also fired when you touch elsewhere on the last thing you touched that fired a hover event. There is no "unclick" event to listen to.

Sure, maybe you could hack away at it enough, handling all these issues, but you are greatly complicating the code, opening unknown additional issues and then you'll find another phone or system handles touch/clicks differently and it's totally broken on there.

Or you just make people with touch enabled devices have to click on the menus to open then.

By the way, this is only a tiny of a fraction of why the Bootstrap team refuses to add hover events to their dropdowns and why this plugin was created in the first place. I actually agree with Bootstrap on this one and have personally never used this plugin.

However, I am dedicated to maintaining this plugin. I am always happy to see Pull Requests. No "real solutions" have been proposed to me. Most are very hacky/break other things. At this point, I couldn't even really accept a PR without proper tests to prove that all current functionality is unaffected and even if something does break and we continue to iterate, we badly need tests to make sure we're not regressing.

I've asked multiple times with help with tests (officially here: #69), but no one has stepped up. Until then, this issue will probably continue to remain open.

Mobile is a major consideration and a lot of issues refer to mobile and how to "better" handle it. It's not something I'm neglecting and it's not something I haven't given a lot of thought to and even tried implementing a few different things. It's not an easy issue to tackle.

Currently, I feel until the other things I mentioned happen (i.e. most importantly testing), the best way to handle this is to disable hover on touch-enabled devices and fall back to just clicking on the menu to open it.

@CWSpear
Copy link
Collaborator

CWSpear commented Sep 5, 2014

I will admit it's my fault for not creating tests earlier. There are dozens of edges cases I've fixed throughout the life of this plugin, and it's paramount that we don't regress.

I don't have a lot of experience with this types of tests, hence the calls for help. I will get around to it eventually (like probably after everyone's convinced that hover dropdowns was a bad idea ;-)), but not any time soon without assistance.

@guaka
Copy link
Author

guaka commented Sep 17, 2014

We're getting confused customers on the phone because of this issue.
I'd rather just see the hover event supported everywhere instead of what's happening now.
What about an optional "ignoring any touchscreen capabilities and hover anyway" setting?

@CWSpear
Copy link
Collaborator

CWSpear commented Sep 17, 2014

Some phones won't open (it actually opens then closes) the menu if hover & click is enabled.

Have you tried enabling click so that they can still click on menus to open them?

@guaka
Copy link
Author

guaka commented Sep 17, 2014

But it's clearly not a phone, so what if there's a setting like this "if on desktop: ignore any touchscreen capabilities and hover anyway"?

@CWSpear
Copy link
Collaborator

CWSpear commented Sep 17, 2014

You're always welcome and encouraged to fork and implement this yourself.

@CWSpear CWSpear added the bug label Oct 23, 2014
@vladimirmartsul
Copy link

+1
Confirm ASUS Transformer Book T100TA (with touch screen), Windows 8.1, Google Chrome current Stable & other Chromium-based browsers - hover doesn't work.
Firefox, IE - work ok.

@amerikan
Copy link

I have this problem too. We have a Dell laptop with touchscreen, though I'm we are using a mouse. When visiting the plugin's demo page, it doesn't work. It happens on Windows 8.1 on Chrome only.

@amerikan
Copy link

Here is some good info on the topic:
Modernizr/Modernizr#869
http://www.html5rocks.com/en/mobile/touchandmouse/

@amerikan
Copy link

I created this jsfiddle https://jsfiddle.net/ps7o1n5j/2/ and tested the touch/click events. Results as follow:

iOS 8.3

Safari:
Touch: true
Mouse: true <--- iOS has click event???

Windows 8.1 Dell laptop with touchscreen support and mouse

Firefox:
Touch: false <----- why you lie firefox?
Mouse: true

IE:
Touch: false <--- why you lie IE?
Mouse: true

Opera:
Touch: true
Mouse: true

Chrome:
Touch: true
Mouse: true

Mac OSX 10.10.3 no touchscreen

Safari:
Touch: false
Mouse: true

Chrome:
Touch: false
Mouse: true

Firefox:
Touch: false
Mouse: true

So I would say there's a bug on the actual browsers, Firefox and IE on Windows 8.1.

@CWSpear
Copy link
Collaborator

CWSpear commented Apr 15, 2015

So I've been hoping for a different approach, but I'm afraid the best approach I've seen/come up with is:

var isTouchOnly = true;
$(document).on('mousemove.bdh', function () {
  isTouchOnly = false;
  $(document).off('mousemove.bdh');
  console.debug('MouseMove detected, this device has a mouse');
});

Basically, we don't need a way to detect for touch it seems, but a way to detect for mice. As long as no touch devices implement mousemove as that article you based says they don't... that should work.

I've had multiple other solutions presented and so far, I haven't found anything that I either like better or else it simply doesn't work.

@amerikan
Copy link

@CWSpear seems like that's a good solution to me. Will you make that change?

@CWSpear
Copy link
Collaborator

CWSpear commented Apr 15, 2015

Issues with this approach:

It'd be best not to even attach the mouseenter/mouseleave (aka hover) listeners if the device is "touch only."

However, with this approach, we don't know on page load if the device isTouchOnly, so we can't really assume isTouchOnly === true on load like this approach assumes.

The best we can do is:

$this.hover(function (event) {
  if (isTouchOnly) return;
  ...
}, function (event) {
  if (isTouchOnly) return;
  ...
});

Very messy and means we have a totally DOA event handler that the system has to listen to that literally does nothing.

Before someone suggests it: I'm not okay with putting in some sort of timeout check to wait to see if we get a movemouse event. It's possible someone doesn't move their mouse (thus triggering the mousemove event) for a while, and it'd be so hard for the end-developer to debug this if they didn't know it was there. And users could potentially see differing behaviors that would be very frustrating.

But at this point, I don't know what else we could do, and the cost of an event handler on today's phones is not going to probably causes issues in the vast majority of situations.

So again, to reiterate: we need to know if the user has a mouse, and if they don't, don't even activate this plugin at all. But we don't have any way of knowing they have a mouse unless they use it, so our base assumption has to be "no mouse" which creates a contradiction of sorts.

@CWSpear
Copy link
Collaborator

CWSpear commented Apr 15, 2015

Another possible solution would be to not activate the plugin on $(document).ready, but on the first mousemove event.

However, this again, could cause problems for debugging for developers. I promise you'll I'll get a dozen tickets of issues of developers that are ajaxing in content and sometimes it works and sometimes it doesn't and it ends up being it's because of when they first move their mouse!

@CWSpear CWSpear modified the milestone: v3.0 Apr 28, 2015
@CWSpear
Copy link
Collaborator

CWSpear commented Apr 28, 2015

Also want to point out the more recently suggestion solution doesn't really work, because apparently touch-only devices still emit mousemove!

@CWSpear CWSpear changed the title Touchscreen enabled Windows 8 behavior on Chrome 35.0.1916.153m Touch + Mouse enabled Windows Apr 28, 2015
@CWSpear
Copy link
Collaborator

CWSpear commented Apr 28, 2015

So I played around some with PointerEvents using the jQuery PointerEvent Polyfill (PEP). It's many times larger than this plugin, but in my initial testing and getting some buddies to check in Chrome on touch-enabled Windows 8 desktops... the results are very promising.

Only recently, Chrome has decided to reverse their stance on PointerEvents and attempt to try and support them. That may be a long way off, but in the meantime, we have the polyfill (and Safari is still dragging their feet on the matter of PointerEvents). It's still a very long ways off before we'd release this as we're determined on creating proper tests and such, and availability is limited.

@NeXTs
Copy link

NeXTs commented Apr 6, 2016

Hey there!
It's almost middle of 2016 but I still ran into this issue.
Take a look this link http://www.virtuosoft.eu/code/bootstrap-dropdown-hover/ , this guy seems to be fixed this problem

@jrchamp
Copy link
Contributor

jrchamp commented Jan 5, 2017

@NeXTs It looks like that guy is doing mouse detection, which is probably a better approach than detecting touch and disabling. It's the same thing that @CWSpear was talking about doing a few posts up. Seems like mousemove did not work because it was being emulated by the touch events, but maybe mouseenter does? Otherwise that guy is going to have similar issues...

The downside to always attaching the listener is that at best it is "dead on arrival" for touch-only devices - it does not do anything except be wasteful. In #141, someone suggested using media queries, e.g. @media (hover) { }; we might be able to do a Modernizr-style check with @media (any-hover) {} to see if there is a reason to attach the listeners.

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

No branches or pull requests

10 participants