I ran into an issue that may be a bug in Chrome, but I was hoping some more seasoned developers could take a look at the problem. I'm using the dom-drag JavaScript library by youngpup (https://github.com/aboodman/dom-drag/blob/gh-pages/dom-drag.js) and noticed that it's not functioning correctly in Chrome. The error is occurring on line 86.
For some reason Chrome is registering a document.onmousemove event even if the mouse has not been moved. I've tried it on every other browser and Chrome is the only one causing the the event to be triggered when a user single clicks. Would this be considered a bug and if so, could anyone recommend a workaround to resolve the issue?
I was using drag.js, and I faced the same problem. I can see that from the link that PlantTheldea gave 2 years ago, chrome didn't fixed it.
In my side, I had draggable items in my DOM that should accept the click event handler. But onmousemove event was triggered during click event if the mouse was not moving. This bug was happening with Chrome.
So I suppose that other people may face the same issue. Here is how I solved it with drag.js:
1 - Go to your onmousemove handler
2 - Check if there are movement in X or Y. If there is any movement then you return true.
Example with the handler of drag.js that I edited:
// onmousemove handler for the document level
// activated after left mouse button is pressed on draggable element
handler_onmousemove = function (e) {
if(e.movementX === 0 && e.movementY == 0){
// No movement detected
return true; // We can continue with other handlers as click
}
Hope it can help.
Related
I am experiencing the following issue: After a particular jQuery library loads, if you click on a number input arrow, the input value keeps increasing (or decreasing) until the focus is shifted outside the input element.
Binding an input event to the element showed it keeps triggering, which led me to believe some piece of code kept setting element.value in a loop. But that did not happen.
I've tracked the issue down to calling event.preventDefault() on a mouseup event.
See:
document.body.addEventListener('mouseup', (e) => {
e.preventDefault();
});
<input type="number">
Why does this happen?
I had trouble finding information by searching what causes these infinitely increasing inputs.
Only after finding the cause myself, I've found out about a similar bug that happened with preventing the default of mousemove (https://stackoverflow.com/a/37521764/6849064). Although, this one does not seem to happen anymore.
Looks like this is a Chrome (and Edge) bug. But as https://stackoverflow.com/a/65253876/6849064 said, it is actually default behavior which makes sense in the way he said it. I myself failed to find this standard behavior documented anywhere. One way to fix the problem is to stop bubbling of the event up to the document,
document.querySelector('input').addEventListener('mouseup', (e) => {
e.stopPropagation();
});
And the other is, well, not preventing default behavior.
The following issue has nothing to do with jQuery. The issue is the code is doing exactly what you wanted it to do.
In the code <input type="number" /> has got 2 events. One is 'mousedown' and second is 'mouseup'.
Consider following example: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_event_preventdefault2
The same is represented in the example above.
What you are doing is cancelling the 2nd part, ie mouseup so if you do mousedown and cancel mouseup, then the number will:
Go on increasing if you push uparrow
Go on decreaseing if you push downarrow
The only, surprise is this would have perfect sense if you would have written the code adding event to input rather than body, but anyways seems browser by default is increasing or decreasing number -- based on event-bubbling to body.
Note: The issue is replicated below, while no jQuery has been added!
document.body.addEventListener('mouseup', (e) => {
e.preventDefault();
});
<input type="number">
We have a one page app which uses iron pages and express-router to navigate. In the browser and on android it works perfectly, on iOS however, we have a bug. The problem occurs if we switch pages by a button press. If the button is exactly over an input text field element (read: in the same position, but on the next iron-page) the input element gains focus directly after the page switch.
We used to have this problem as well with two buttons in the same position but this was solved by changing all on-clicks to on-taps.
Things we have tried so far:
Adding event.stopPropagation to the on-tap event
Including fastclick.js to prevent click delays (this worked partially when on-clicks were still in place but was made obsolete with on-tap)
Note that we have experienced this problem since Polymer 1.0 all through 1.5.
I reproduced your symptoms on an iPad Air 2, and trying e.stopPropagation(), e.preventDefault(), and returning false all had no effect. I'm not sure whether this is actually a Polymer problem.
I have a couple [hacky] workarounds to employ during the page-switch:
Option 1: Delay the page-change by 400ms. If your button has a ripple effect, the delay is masked by the animation.
codepen
Option 2: Disable the input and re-enable it after a 400ms delay. This prevents the input from picking up the tap event, but has the disadvantage that the disabled state could be noticeable (perhaps a lesser evil than your current problem).
codepen
Thanks #tony19, for the input.
We wanted to avoid delays, so I researched a bit more and ultimately fixed the problem. To answer my own question: the ultimate solution did lie in the FastClick library.
Basically what happens is that the tap event is fired immediately, but it doesn't replace the click event. Rather, the click event still fires, but with the original 300ms delay. This delayed click event thus fires on the newly displayed 'page' and triggers the input-field (or button had it been there) at the same x-y coordinates.
Adding the FastClick library once again solves this thanks to some updates in the library. However, it breaks some items that need the original click, such as Google Autocomplete. A basic solution to exclude FastClick is to instead apply it as:
FastClick.attach(document.body, {
excludeNode: 'something', });
This, however, only works for that node and not possible children. As such, to fix everything for input fields with Google's Autocomplete as well is done using:
// Disable FastClick for the children of a google auto-
// complete component.
var needsClick = FastClick.prototype.needsClick;
FastClick.prototype.needsClick = function(target) {
if ( (target.className || '').indexOf('pac-item') > -1 ) {
return true;
} else if ( (target.parentNode.className || '').indexOf('pac-item') > -1) {
return true;
} else {
return needsClick.apply(this, arguments);
}
};
// Remove click delay on iOS. As such, removing differences
// in timing between click and tap, thereby avoiding the
// fall-through problem.
FastClick.attach(document.body);
I will now close this thread, but I thought it'd be nice to leave this as reference for anyone else experiencing the problem.
Understand that it affected Polymer 1.0 to 1.5. Just to confirm that we experienced the same behaviour in Polymer 1.6 and the following fixes it.
_onTap: function(event) {
event.preventDefault();
event.stopPropagation();
}
I have a problem.
The code works fine in Firefox but in Chrome it messes up.
The code is rather basic.
There's a div with a background. Upon jquery's mousedown upon that div I set a function to run at an interval. Upon mouseup the interval is cleared. Simple, right?
So problem is this. Say the user right-clicks in Chrome and brings up the context menu. Or they drag the div. The mouseup event is no longer registered.
Any ideas?
I had an idea where I'd just get the status of the mouse button. But that seems to be impossible to do without a mouse even firing.
function mouseD(e){
mouseE = e;
timer = setInterval(scroller, 50);
$(document).mouseup(function(){
clearInterval(timer);
});
//mouseB = e.button;
//mouseW = e.which;
//console.log(e.button + " D " + e.which);
}
imgbox.mousedown(mouseD);
EDIT:
So I managed to solve the context menu and dragging problems by disallowing such acts. The user just can't do it anymore. But if the user right- and left-clicks at the same moment the mouseup never registers.
Check out this website: it goes into detail about Mouse Events with different browsers.
http://unixpapa.com/js/mouse.html
First of all, these are the versions I am currently using:
jqGrid 4.3.2 with the fix for Chrome (posted by "Oleg" in jqGrid does not render correctly in Chrome/Chrome Frame). For some reason 4.3.2 and 4.4.0 did not solve the width issue for me as described in the post. The issue just popped up in IE in addition to Chrome.
jQuery 1.7.2
jQuery UI 1.8.9
The problem I am having is that when I try to resize one of the columns in the grid by dragging the mouse it seems to trigger the click event on the header to the left of the separator when I let go of the mouse button. This event then triggers reordering of the rows, so it is not very nice.
It only happens in IE (9), it works fine in Firefox and Chrome.
I think this is very strange, since I have not found anyone else who describes the same issue with jqgrid, and I don't think I do any "hacks" that would potentially give this behaviour.
Hope someone could point me in a direction here.
I did not find exactly what the root cause for my problem was, but managed to solved it by suspending the click handler in jqgrid for 10 milliseconds after the mouseup event on the column resize action. The click handler allready had a check for a variable called ts.p.disableClick, so I figured I might as well use this one. The only thing I needed to change was from this:
$(document).mouseup(function () {
if (grid.resizing) { grid.dragEnd(); return false;}
return true;
});
, to this:
$(document).mouseup(function () {
if (grid.resizing) {
// Disabling the click handler for 10 millisec.
ts.p.disableClick = true;
setTimeout(function() {
ts.p.disableClick = false;
}, 10);
grid.dragEnd(); return false;
}
return true;
});
You may call this a hack, but suspending the click handler for just 10 ms should not affect the user in any way, so I think it should be safe.
Hopefully this could be helpful if someone encounters a similar problem.
I was playing with drag n drop in full forms (so no instant upload). I though small part was gonna be highlighting a certain fieldset when hovered over with a file. Enter dragover and dragenter events (and dragleave etc).
Turns out it's not such a small part. The Fiddle: http://jsfiddle.net/rudiedirkx/epp74/
Try it out: drag over a fieldset and move around a bit. The first over triggers the fieldset's dragenter event (fieldset is yellow). The moving around after that (within the same fieldset) triggers dragenters and dragleaves (fieldset no more yellow), which is bad.
Which is why I wanted to make what IE made for mouseover and mouseout a long time ago: mouseenter and mouseleave (they trigger just once). For drag events, the exact same thing applies: they should trigger only once in the exact same way. JS libraries spoof these IE events by using Event.fromElement and Event.toElement (and compare them against the event owner element). (See jQuery or Mootools source for specifics.)
To make the same for drag events, I need the same fromElement and toElement. You can see in the Fiddle, I try, but I can't find them.
Anybody know where they are? Why they're not available?
I'm using Chrome primarily, which doesn't have a fromElement in the dragenter event, but does have a toElement in the dragleave event. In Firefox it's slightly worse (but more logical): both are empty.
Any and all ideas are so very welcome.
edit
After a little more debugging I've found out that Chrome's toElement in dragleave isn't always correct. It's never 'bigger' thanthis, but sometimes it should be: when I leave the fieldset (this) to its parent form (toElement). When I do that, both this and toElement are the fieldset (which is incorrect, right?).
edit Solution:
I ended up with something like this: http://jsfiddle.net/rudiedirkx/Lwd3md71/ which ignores elements in the event, and uses the event coordinates to find the element under the mouse. To make it trigger max once per animation frame, it uses requestAnimationframe, which results into 31-59 fps.
Firefox provides the relatedTarget event property, but Chrome and Safari don't. Sadly, this issue has been open for a couple years as this Chrome bug and this Webkit bug.
Edit: The issue has been fixed in Chrome.
There is a way of faking the relatedTarget for a "dragleave" event, which is to set a variable from the accompanying "dragenter" event -- since dragleave is always preceded by dragenter, a variable set in the latter will be available to the former:
var relatedTarget = null;
document.addEventListener('dragenter', function(e)
{
relatedTarget = e.target;
}, false);
document.addEventListener('dragleave', function(e)
{
console.log('target = ' + e.target + ' relatedTarget = ' + relatedTarget);
}, false);
It won't work the other way round, but you don't really need dragenter for anything else if you use it this way -- i.e. the dragleave alone is enough to tell you when the mouse is moving into, or entirely out of, a particular element.