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+.
Related
Hi, particulary I am having a problem with HighCharts / HighStock not scrolling on the x-axis to display hidden data such as the times contained here:
It works just fine in Chrome browser on my Desktop. Whenever I scroll the overthrow-polyfill.js error shows itself. This is not a library I included myself as I can't find any mention of overthrow in all my code.
Sidenote: I do have angular touch and fastclick in the mix as well, but removing them did not help either
I've got the same problem on mobile device. After couple of hour i have found that scrolling is available just on mousemove event, but not on touch event. To fix this I have added the same listeners on touch events.
Highcharts.Pointer.prototype.onContainerTouchStart = Highcharts.Pointer.prototype.onContainerMouseDown;
var onContainerMouseMove = Highcharts.Pointer.prototype.onContainerMouseMove;
Highcharts.Pointer.prototype.onContainerTouchMove = function(e) {
onContainerMouseMove.call(this, e);
if ("touchstart" === this.chart.mouseIsDown) {
this.drag(e);
}
};
Say I have a help icon with some help text on mouse over.
<span title="To do X, do Y.">?</span>
In Firefox 37 at least, clicking on the help icon will disable the tooltip until the user mouses away and back over again, instead of showing it quicker.
Is there any way to make the browser display the tooltip when a user clicks as well as mouses over?
Things I tried with no luck:
onclick="this.onmouseover();" => TypeError: this.onmouseover is not a function
onclick="(function (self) { var e = document.createEvent('Events'); e.initEvent('mouseover', true, false); self.dispatchEvent(e); }(this)); => no effect
onclick="(function (self) { var temp = self.title; self.title = ''; self.title = temp;}(this))" => no effect
I don't think there's any way to manipulate how "title" works. You'd have to do it custom (or with 3rd party code). I tried moving the element out from under the cursor for 1ms and then back, but it doesn't work as it seems the native title tooltip timer doesn't begin until the mouse moves (at least in Chrome).
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 am having some frustrating javascript timing issues.
FYI, the page is a jsp file and attached to said page is a separate js file and the jQuery CDN file. For troubleshooting purposes, I eliminated all unnecessary content and code and pasted what I needed into separate jsp and js files to troubleshoot this specific problem.
If I could display the html and js someplace, that would be great. But for now, I'll describe it. The page has two buttons, one to load an image and one to toggle a "zoom" feature (more on that later). The user clicks a button, which loads an image using the DOM, specifically innerHTML. This image is surrounded by horizontal and vertical scrollbars. When the user turns on the "zoom" feature, the image records the mouse-click position in an onclick event. So, with this on, the user clicks on the image and a bigger version of the same image is loaded, again, using the DOM and innerHTML. The very last step, the most important one, using the mouse position, the scrollbars will focus and center on the point clicked (using scrollLeft and scrollTop).
This all works flawlessly in IE. However, in non-IE browers (i.e. FireFox), it takes a couple of clicks for the scroll adjustment to catch up to the innerHTML. That is, when the user "zooms" for the first time, the image loads but the scrollbars don't adjust. It takes two more successive clicks for it to work the same as in IE. I was researching innerHTML and it is slower in FireFox than IE.
How can I fix this? Has anybody else tried to load an image in FireFox using JavaScript and immediately adjust the scroll positioning on the image? Again, it works the first and each time after that in IE. But non-IE browsers are having issues.
I've tried using innerHTML, replaceChild, appendChild, nothing I tried so far fixes it.
Thank you.
Update: I wanted to see if this issue is anything inside the scrollbars or just images; so, I replaced the image with < p > ... < p > and programmed it to scroll immediately after the **first* image is loaded, via a user-initiated onclick event. Interestingly, it worked. I then replaced the text with the image and it was broken again.
So, after an image is loaded using the DOM (i.e. innerHTML), any attempts to programmatically scroll in non-IE browsers will break. If you programmatically scroll once more, though, it will behave normally.
Update2: I tried employing methods to programmatically cancel the event at the end of the call and immediately call the function again, but that didn't fix the issue.
Then, I tried loading the image using jquery and that seemed to work. I adapted it from two other stackoverflow articles: Can I get the image and load via ajax into div and img onload doesn't work well in IE7 (to circumvent a caching issue).
Here is the code I used:
image = new Image();
image.src = "sample.gif?d=" + new Date(); // passing unique url to fix IE (see link above)
image.onload = function () {
$("#imgcontainer").empty().append(image);
// document.getElementById("imgcontainer").appendChild(image); // This worked, too
// $("#imgcontainer").html("<img src=\"sample.gif?d=" + new Date() + "\"></img>"); // Failed
// document.getElementById("imgcontainer").innerHTML = "<img src=\"sample.gif?d" + new Date() + "\"></img>"; // Failed
$("#imgcontainer").scrollTop(25);
};
image.onerror = function () {
$("#imgcontainer").empty().html("That image is not available.");
}
$('#imgcontainer').empty().html('Loading...');
The key, I believe, was using the onload method. I tried employing jQuery.html() inside the onload method and it didn't work. So, that confirms there was definitely a timing issue related to innerHTML and how and when the image is loaded into the DOM. And the onload method, in combination with either the DOM's native appendChild method or jQuery's equivalent appendChild implementation, fixed the problem.
Update3:
Regarding mrtsherman's suggestion below--
Here is my code:
var outerDIV, innerDIV, html;
outerDIV = document.createElement("div");
outerDIV.id = "content";
document.getElementById("body_id").appendChild(outerDIV); // attach div to body
innerDIV = document.createElement("div");
innerDIV = "ImageHolder";
image = new Image();
image.src = "sample.gif?d=" + new Date();
document.getElementById("content").appendChild(innerDIV);
document.getElementById("ImageHolder").style.height=image.height + "px";
document.getElementById("ImageHolder").style.width=image.width + "px";
html = "<img src=\"sample.gif\"></img>";
$("#content").scrollTop(100);
$("#ImageHolder").html(html);
I created an inner div to place the image. After creating said div, I adjusted it's size, based on the dimensions of the image. I adjusted the scrolling in js and then attached the image to the DOM, via innerHTML, and it did not scroll. I changed the width and height to some fixed size larger than the image and it scrolled. But that is not the desired affect, to make a container bigger than the image. Thank you for your help.
Update4:
What is the equivalent of the code I wrote in Update2 when using document.createElement("img"), instead of new Image()? The onload event is not having the same affect as in the Image object; the onload event is an important ingredient, here.
Thank you.
If you know the new images dimensions then I would send those first. Then you can resize a container for the image, adjust scrollbars and then get the image.
Please see the original question, Update2, for the solution I employed.