I'm trying to dynamically change the cursor style when the mouse is over an element. The cursor should be either "move" or "default" depending on a boolean returned by a method.
The code is something like this:
$("#elemId").mousemove(function(event) {
if(cursorShouldBeMove()) {
$(this).css({'cursor':'move'});
} else {
$(this).css({'cursor':'default'});
}
}
This code works like a charm in IE8,FF3,Chrome and Safari.
Only Opera fails to handle it correctly.
I'm using Opera 9.6.4
Does anyone have an idea how to solve this?
I prepared a sample for testing;
var cursorStatus = true;
setInterval(function() { cursorStatus = !cursorStatus; }, 500);
function cursorShouldBeMove() {
return cursorStatus;
}
$(function() {
$("#elemId").mousemove(
function(event) {
$(this).css("cursor", cursorShouldBeMove() ? "move" : "default");
}
);
});
If you move your mouse from outside of #elemId to inside of it for a few times you will see that the cursor will change. But if you position your mouse in #elemId and move your mouse, cursor not changes.
The code is very simple. I think it's a bug of Opera.
I tested this code also with;
Firefox 3.5.1 (worked)
Internet Explorer 7 (worked)
Google Chrome 2.0 (worked)
Safari 3.2 (worked)
(Windows versions)
Opera is real funny with cursors. I find that you have to move the mouse over the element twice before it actually works.
Can see here that you need to hover over the Hello World twice to get the cursor to change.
Same issue described here
Related
the code below works perfectly in chrome, but does not work in safari (desktop & mobile)
const messageBody = document.querySelector(`.chatContainer`);
messageBody.scrollTop = messageBody.scrollHeight;
messageBody is a div with overflow-y: scroll
Every time an item is added to the div, it scrolls to the bottom.
Any idea how to make it work in safari?
I have found to problem, it was a problem in my react code.
Every time I added a new element to my array, all of my components were rerendered. This was because I was overwrittin the existing id I gave them.
The code that worked in chrome did not work in safari, because safari executed the code before all of the components were rendered.
ScrollPosition.prototype.restore = function () {
if (this.readyFor === 'up') {
this.node.scrollTop = this.node.scrollHeight -
this.previousScrollHeightMinusTop;
}
}
this.previousScrollHeightMinusTop = this.node.scrollHeight-this.node.scrollTop;
reference-
http://kirbysayshi.com/2013/08/19/maintaining-scroll-position-knockoutjs-list.html
I have many 300x200px divs(.contentUser) rendering representing users.
contentUser:hover(over)
->shows another div(.contetnButtonWrap) sliding in with buttons.
contentUser:hover(out)
-> contentButtonWrap slides out again
This works fine with CSS on any device I have tested so far except iPad(no hover). I tried with :active but it didn't work
So on iPad instead of hover(over) I use onclick:
function alternativeHover() {
var userDivs = document.getElementsByClassName('contentUser');
[].forEach.call(userDivs, function(e){
e.onclick = function() {
var target = e.getElementsByClassName('contentButtonWrap');
e.style.backgroundSize='450px 300px';
e.style.outline='3px solid green';
target[0].style.left=0;
};
});
};
I have 3 questions:
Is this really the best that can be done in this case?
How to handle the hover(out), its a div so it doesn't grab focus so I can not use onblur! And I would not like to have to check pixels on mousemove or anything like that.
Why doesn't hover work on iPad if it works on Android smartphones and iPhones?
I'm having issues with the combination of CSS transforms and touch event hit testing. This only reproduces for me in Chrome on Android 4 (stable and beta). iOS Safari, as well as Chrome desktop with touch emulation both appear to be working fine.
I'm almost positive this has to be a bug, so I think I'm mostly looking for workarounds here.
The issue is that hit testing for touch only seems to work for where the element was before the transform, not the final position. You can see an example on my jsfiddle (only on Android 4 Chrome):
jsfiddle: http://jsfiddle.net/LfaQq/
full screen: http://jsfiddle.net/LfaQq/embedded/result/
If you drag the blue box half way down the screen and release it will snap back to the top. Now, if you try dragging from the top half of the page again, no touch will register. The touch events aren't even fired on the element. However, if you attempt to touch the bottom of the element, it works fine. You can then try moving it up from the bottom, and observing that hit testing no longer works on the bottom, but works on the top.
This is how I'm handling the events:
function handleTouch(e) {
console.log("handle touch")
e.preventDefault();
switch(e.type){
case 'touchstart':
console.log("touchstart");
touchOriginY = e.targetTouches[0].screenY;
break;
case 'touchmove':
console.log("touchmove");
el.innerHTML = e.targetTouches[0].screenY;
var p = e.targetTouches[0].screenY - touchOriginY;
el.style[TRANSFORM] = 'translate3d(0,' + p + 'px' + ',0)';
break;
case 'touchcancel':
console.log("touchcancel");
// Fall through to touchend
case 'touchend':
//console.log("touchend");
//el.style[TRANSITION] = '.4s ease-out';
el.style[TRANSFORM] = 'translate3d(0,0,0)';
break;
}
}
el.addEventListener('touchstart', handleTouch);
el.addEventListener('touchend', handleTouch);
el.addEventListener('touchmove', handleTouch);
el.addEventListener(TRANSITION_END, function(e) {
console.log("transition end")
el.style[TRANSITION] = '';
});
I don't have any problems with the transforms in touchmove, as those aren't new touches to be detected anyways.
Any suggestions?
This is an unusual bug in Chrome.
Essentially the hit targets for an element is recorded during a layout pass by the browser. Each time you set innerHTML, the browser will relayout and the last time this is done, is before the touchend event is fired. There are a couple of ways around it:
OPTION 1: You can set a touch handler on the body element and check the target of touch event to see if it is touching the red block. Tip of the cap to Paul Lewis for this approach.
http://jsfiddle.net/FtfR8/5/
var el = document.body;
var redblock = $('.splash-section');
function handleTouch(e) {
console.log("handle touch")
if(e.target != redblock) {
return;
}
....
OPTION 2: Set an empty touch callback on the document seems to fix the problem as well - according to some of the linked bug reports, this causes the hit testing to be done on the main thread which is a hit on performance but it properly calculates the hit targets.
http://jsfiddle.net/LfaQq/2/
document.body.addEventListener('touchstart', function(){});
OPTION 3: Set innerHTML after the transition has ended to force a relayout:
el.addEventListener(TRANSITION_END, function(e) {
console.log("trans end - offsettop:" + el.offsetTop);
el.style[TRANSITION] = '';
el.innerHTML = 'Relayout like a boss!';
});
I've created a bug report here and Rick Byers has linked to a related bug with additional info: https://code.google.com/p/chromium/issues/detail?id=253456&thanks=253456&ts=1372075599
I'm just a lowly uC programmer who's trying to put together a little web interface for his boss. I've got everything working so far except being able to select a square on a canvas using touch input.
This is on a Samsung Slate 7 tablet running Windows 8 and IE10
I've distilled the code down to pretty much the bare essentials here:
var cxt;
var c;
window.onload = function () {
c = document.getElementById('displayCanvas');
cxt = c.getContext('2d');
/*
c.addEventListener("MSPointerUp", mouseUp, false);
c.addEventListener("MSPointerMove", mouseMove, false);
c.addEventListener("MSPointerDown", mouseDown, false);
*/
c.addEventListener("touchend", mouseUp, false)
c.addEventListener("touchmove", mouseMove, false);
c.addEventListener("touchstart", mouseDown, false);
}
function mouseDown(downE) {
window.console && console.log("down");
};
function mouseMove(moveE){
window.console && console.log("move");
}
function mouseUp() {
window.console && console.log("end");
}
I get both the start and end events, using both the MSPointer and the "normal" javascript touch events, however the "move" event doesn't register.
I'm sure it's something really simple I'm missing here, thanks for helping me out!
I'm assuming you are interacting with the HTML page in desktop IE on Windows 8. In desktop IE, the MSPointerMove is not firing on that canvas because the default behavior when the user moves their finger around on the screen is to pan the content. If you style the canvas with the following snippet your MSPointerMove event should be detected.
style="-ms-touch-action: none"
Here's a great article on how to get touch working on many browsers. http://blogs.msdn.com/b/ie/archive/2011/10/19/handling-multi-touch-and-mouse-input-in-all-browsers.aspx
The Samsung Slate 7 tablets have a bug in older versions of the drivers that might be relevant. I saw another answer tagged [internet-explorer-10] that had the details. Have you updated your driver?
I have a div with border and in its right-bottom corner I have image for resizing:
So when user presses mouse on the image, he (or she) can drag mouse and resize the div.
This works fine in all browsers but FireFox.
In FireFox something strange happens: after the user presses mouse and starts dragging, the cursor changes to:
So the cursor changes to this one and mouse move events are not coming, when the mouse is dragged.
I am wondering, what causes this behaviour. I thought maybe FireFox thinks that the user is trying to select text by pressing and dragging the mouse. But I cancelled text selection using this code:
resizeImageImg.onselectstart = "return false;";
resizeImageImg.ondragstart = "return false;";
resizeImageImg.style.WebkitUserSelect = 'none';
resizeImageImg.style.KhtmlUserSelect = 'none';
resizeImageImg.style.MozUserSelect = 'none';
resizeImageImg.style.MsUserSelect = 'none';
resizeImageImg.style.OUserSelect = 'none';
resizeImageImg.style.UserSelect = 'none';
resizeImageImg.setAttribute ("unselectable", "on");
resizeImageImg.setAttribute ("draggable", "false");
(for both: the div and the resize image)
But this did not solve the problem. FireFox still does not let resizing and changes cursor to "not-allowed".
Can anybody please help?
Thank you all, I found the solution.
I replaced:
resizeImageImg.ondragstar = "return false;";
by
resizeImageImg.ondragstart = function () { return false; };
and it started working in FireFox as well.
What happens here is that if you want to process mouse-move events when your mouse-down event came from an image, then you have to make you image not-draggable. But this is not enough to use
resizeImageImg.setAttribute ("draggable", false);
(at least in FireFox) becasuse events ondragstart are still coming. I understood this when I set:
resizeImageImg.ondragstart = function () { alert ("ondragstart"); return false; };
So I realized that FireFox does not obbey setAttribute ("draggable", false) - whilst other browsers do.
Andy, here is the solution I have come up with. I have gone to great effort to make it quick and easy to use.
You can view the file here:
http://files.social-library.org/stackoverflow/imageResizer.html
It is simple to use. Create your image and specify a width and height. Then, once the page loads call the function imageResizer.init(imageObject) sending the image object as a parameter. It will then set the image up with the dragger.
This works in firefox, chrome and internet explorer 8+.