Edge does not see button press on mouseleave / mouseenter - javascript

Left mouse button was pressed or not - Edge always shows .buttons and .button as 0. .which is always 1.
Other browsers work fine. Other events like click work fine in Edge too. Trouble is with mouseleave and mouseenter.
So how can I detect in Edge on mouseleave event if left mouse button was pressed or not?
P.S. I can solve it with ugly flag like "isClicked" and update it in all related events like mousedown, mouseup. But it is ugly and bug prone.

The #1 best answer: Tell your users that you do not support MS Edge.
If that is not an option, then you'll need to track the mouse button status yourself, like
var leftPressed;
function init() {
document.body.addEventListener("mousedown mouseup") {
//update leftPressed
}
}

Related

Android browsers long hold disable/ mouse up after 1second of mousedown

I am trying to build a one touch game on HTML5 canvas. It's a running game made with the help of this tutorial:
http://blog.sklambert.com/html5-game-tutorial-game-ui-canvas-vs-dom/
I changed the existing controls from space bar to a mouse click. It works perfectly across all the platforms except Android devices mobile browsers.
In Android devices, the touch makes the user jump. If there is a long hold in the touch, the user keeps jumping even when the touch is released. This problem does not happen in iPhones or iPads or desktops.
Can I make a Javascript function where a mouse down for a certain number of seconds is cut ? Something like:
if(mousedown for 1sec)
mouseup;
Let me know if you can think of another approach.
You can use touch events rather than mouse for touch enabled devices. Refer: https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Using_Touch_Events
function is_touch_device() {
/* Function code taken from http://stackoverflow.com/a/4819886/3946520 */
return 'ontouchstart' in window // works on most browsers
|| navigator.maxTouchPoints; // works on IE10/11 and Surface
};
if(is_touch_device()) {
canvas.addEventListener('touchstart', handleTouchStart, false);
canvas.addEventListener('touchend', handleTouchEnd, false);
}
else {
// Bind Mouse Events
}
function handleTouchStart(e) {
// This code runs when user touches the canvas i.e. on touch start
}
function handleTouchEnd(e) {
// This code runs when user removes finger from canvas i.e. on touch end
}
Also note that there can be scenario where the user puts two or more fingers on the canvas. Each of them will fire 'touchstart' event. So you'll have to handle that.
You can refer to http://www.javascriptkit.com/javatutors/touchevents.shtml for a good tutorial on touch events.

How to make work jquery "swipe" with scroll on iPad?

I have two divs, standing next to each other. In addition to click event I added a swiperight and swipeleft to do something. But when I add these swipe events, scroll doesn't work anymore on iPad. On PCs there's no problem!
Is there any other way to make them compatible with each other on iPad (touch screen devices)?
Merci!
Found a solution:
http://stephband.info/jquery.event.swipe/
Swipe events are a thin wrapper built on top of move events (stephband.info/jquery.event.move). Move events, by default, override native scrolling, as they assume that you want to move something rather than scroll the window. To re-enable scrolling, call e.preventDefault() inside a movestart handler.
In the example above, we want to be able to swipeleft and swiperight, but scroll up and down. Inside a movestart handler, the direction of the finger is moving is calculated and the event is prevented if it is found to be moving up or down::
jQuery('.mydiv')
.on('movestart', function(e) {
// If the movestart is heading off in an upwards or downwards
// direction, prevent it so that the browser scrolls normally.
if ((e.distX > e.distY && e.distX < -e.distY) ||
(e.distX < e.distY && e.distX > -e.distY)) {
e.preventDefault();
}
});

translateX = event.offsetX setter on mousemove event return 1 - sometimes

Quick and simple question, about a some sort of scrubber thing. See the fiddle below.
When binding to the mousemove event (using jQuery), and setting the transformX property when moving in the positive direction, there is about a 1/2 change it returns 1.
$floater.css('transform', 'translateX('+event.offsetX+'px)');
Same setup with left offset - No issues!
Browser inconsistencies:
Firefox does nothing
IE does the same as Chrome
Heads up, IE decided to crash on opening my fiddle
Fiddle:
http://jsfiddle.net/n3Z3Y/3/
This happens because when mouse cursor is over your 'floater' div you lose mouseover on the container parent. A quick fix could be to return false when mouse is over your floater div. Fiddle updated here.
$floater.on('mousemove', function(event) {
event.stopPropagation();
event.preventDefault();
// cross browser propagation stopping...
return false;
});

Custom cursor outside of browser window

I have a element on my website which is freely resizable. This is done by 4 handles on the edges. On hovering these handles and while resizing the element I want to show the respective resize arrows.
Currently I implemented this behavior by setting the css cursor style of the body/root to these arrows. The problem about it is the limit to the client area of the browser window. It would be visually more consistent and less confusing, if the arrow cursor would be visible everywhere while the mouse is hold down.
Google Maps is doing the same thing with their hand cursor while moving the map. So my question is how to achive this effect on my own.
My current (relevant) source:
function startObjectScaling(e){
e.stopPropagation();
e.preventDefault();
document.documentElement.style.cursor = this.style.cursor;
window.addEventListener("mouseup", stopObjectScaling, false);
}
function stopObjectScaling(e){
e.stopPropagation();
document.documentElement.style.cursor = '';
window.removeEventListener("mouseup", stopObjectScaling);
}
[...]
var tg = document.getElementById("transformGadget");
var handle = tg.firstChild.nextSibling;
for(var i=0;i<4;i++){
handle.addEventListener("mousedown", startObjectScaling, false);
handle = handle.nextSibling;
}
There is a special function implemented in the more modern browsers for this purpose. The name is setCapture(). It redirects all mouse input to the object the method was called on. Now a simple css cursor definition on that element is enough to archive the desired effect. After mouse release this effect stops (for security for sure). It can also be stopped manually by calling releaseCapture
example:
<style type="text/css">
#testObj {
/* this cursor will also stay outside the window.
could be set by the script at the mousedown event as well */
cursor: hand;
}
</style>
[...]
document.getElementById('testObj').onmousedown = function(e){
// these 2 might be useful in this context as well
//e.stopPropagation();
//e.preventDefault();
// here is the magic
e.target.setCapture();
}
if the arrow cursor would be visible everywhere while the mouse is hold down.
You're relying on a potential OS quirk to create your behavior. This is not something you can ASSUME will always hold true. However, once you start a mousedown, the cursor at that point will normally stay the same, no matter where you move the mouse to, UNTIL something else (another window that you may mouse over? the desktop? a system-interrupt?) changes the cursor.
In other words, don't rely on this behavior. Find something else that will work for you. If you must do this, re-examine your business requirements.

Mobile Safari - "touchend" event not firing when last touch is removed?

The "gesture" I'm trying to capture is a tap when but only when an element (other or same) already has a touch on it. So, touch (1) presses the button down while touch (2) taps to selected options, touch (1) releases and button is depressed.
The problem I'm having is with the last bit. The "touchend" event is not being fired when I release the last finger? So I have no way of depressing the button?
..also the "touchend" event always has touches.length = 0?
Here is some code so you can see what I mean. I think this may be a bug in mobile safari?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Multi-touch problem</title>
<style>
#touchpane{
width:900px;
height:500px;
background-color:#333;
}
</style>
</head>
<body>
<div id="touchpane" click="void();"></div>
<script>
var tp = document.getElementById("touchpane");
tp.addEventListener('touchstart', function(e){
e.preventDefault();// to stop copy and paste
console.log("touchstart " + e.touches.length );
}, false)
tp.addEventListener('touchend', function(e){
console.log("touchend " + e.touches.length );
// not called when last finger removed?
}, false)
tp.addEventListener('touchcancel', function(e){
console.log("touchcancel");
}, false)
</script>
</body>
</html>
I can help you with one problem, but I don't know why the "touchend" isn't firing when both fingers leave the screen, when I run your code above, the "touchend" fires when either finger leaves the screen (on an iPhone 4)
1) While the "touchend" javascript event for iPhone does have the "touches" property, it's always going to be empty when the last finger leaves the screen, because "touches" for the iPhone represents fingers currently touching the screen, and "touchend" only fires after a finger leaves the screen. So on "touchend" "e.touches.length" will always be 0 when the last finger is lifted.
2) You can access which touches have changed in the "touchend" event by using the "changedTouches" property. This is problematic because it's behaviour is not very consistent.
If you touch the screen with one finger, then another, and then you remove one finger, a number of things could happen.
If you when you have removed the second finger, nothing has changed about the first finger, your event object in "touchend" will have "touches.length = 1" (the finger still on the screen) and "changedTouches.length = 1" (the finger that left the screen).
However, if you are moving the first finger (even a bit) when you remove the second finger, then on "touchend" your event object will have "touches.length = 1" (the finger still on the screen) and "changedTouches.length = 2" (the finger that left the screen + the movement of the first finger).
I found this article very helpful:
http://m14i.wordpress.com/2009/10/25/javascript-touch-and-gesture-events-iphone-and-android/
TouchEvent of the type touchend always have e.touches.length of 0
The missing last touchend event could be dependent on the targets of the touches. If both fingers lift at the same time AND both have the same target then only one touchend will fire, but it will have both touches in the e.changedTouches object. If the targets are different then you will see two touchend events, each with the associated touch in the changedTouches object.
Furthermore, and most puzzling, is that when you lift one of two fingers you will get the same behavior as if you had lifted both. Then when the remaining finger moves it will fire another touchstart, with that finger's original identifier in the touches. The result is that there is no way to tell at the time of the touchend which touch has ended until after an arbitrary amount of time (when the remaining finger moves).
To verify this you need to document the touchLists in each event.
The only workaround I found is a cludge where I cache the touchstart events, setInterval for half a second, then hope that the remaining finger has fired a touchstart I can use to reconcile the state. Good Grief!

Categories