Why doesn't dragging images using JavaScript work in Firefox? - javascript

I'm using the code below for dragging an image (#StndSoln1). It works perfectly in Chrome and all, but not in Firefox. Here startDrag() is the function which i attached to the mousedown event listener. Could anybody please help me.
function initialFunction(){
document.getElementById("StndSoln1").addEventListener('mousedown',startDrag,false);
document.getElementById("StndSoln1").addEventListener('mousemove',drag,false);
document.getElementById("StndSoln1").addEventListener('mouseup',stopDrag,false);
}
function startDrag()
{
if (!moveFlag){
currentTraget=document.getElementById("StndSoln1");
offsetX=currentTraget.offsetLeft;
offsetY=currentTraget.offsetTop;
ImgPlaced=false;
moveFlag=true;
x=window.event.clientX;
y=window.event.clientY;
event.preventDefault();
}
}
// Fn for drag the current target object...
function drag(){
if (moveFlag && !ImgPlaced){
currentTraget.style.left=(offsetX+window.event.clientX-x)+"px";
currentTraget.style.top=(offsetY+window.event.clientY-y)+"px";
}
}

I actually had a similar problem, so I can try to help even without the code you're using.
See, the Firefox developers had this bright idea of making it so that, when you drag an image, you can "move" it around and possibly drop it in an Explorer window to quickly and easily download it, or to the tab bar to open the image in a new tab. The obvious downside of this is that it results in a default behaviour that other browsers don't have.
The simple solution is to make sure that all your events are properly cancelling the default action (event.preventDefault, return false, that kind of thing). Should that fail too, then you should use a <div> element with a background-image instead of an <img> element.

Related

How do you capture mouseout on window?

QUESTION DOES NOT ALREADY HAVE AN ANSWER (if you can provide code that works instead of googling my question and linking to whatever answer comes up for the sweet sweet internet points then I will accept it as an answer. But since I have already been to all of those questions don't pretend like they work unless you can provide actual code that you have tested)
If you just do
$(window).on("mouseout", function() { alert("OUT"); });
you can mouseout on the left or right side of the window and it doesn't fire the event. I made a jsfiddle here but it actually works fine because there is a border around the iframe.
So what is the best way to know if a mouse has left the window? I can put a 1px border around the page (composed of 4 divs). I can monitor x/y and tell if the mouse is on an edge. But ideally $(window).on("mouseout", foo) would tell me when the mouse has left the window.
This answer is working: https://stackoverflow.com/a/3187524/2831645
Using jQuery you can rewrite the code like this:
$(window).on("mouseout", function(e) {
if(!e.relatedTarget || e.relatedTarget.nodeName == 'HTML') {
alert('left window');
}
});
The code has been tested on latests Firefox & Chrome.

Race Condition using onclick attribute

I am trying to call the below 1x1 pixel (sact.atdmt.com) when a link is clicked on. It's actually just returns a 1x1 image but is used to ping our servers and essentially count a click in this instance.
test
The above code only works in IE. I can't figure out why it doesn't work in Chrome or Firefox. I think there is some kind of race condition where the href is being resolved before the onclick function has a change to execute but it's only present in these browsers.
Are there any fixes for this?
Thanks,
Fix the syntax error and add return false;
<a
href="http://www.google.com/"
onclick="javascript:img1=new Image(); img1.src='http://sact.atdmt.com/action/adofat_ImageTest27_1'; img1.height='1'; img1.width='1'; return false;"
>test</a>
BTW if you're not displaying the image then you don't need to set height/width of the image
Ejay's answer works just fine, but I feel obligated to mention that I usually stay away from onclick=. This is because screen readers won't reliably register onclicks as an actual click event.
So if you are interested... here is the safe way of doing this.
The JS
function imageClickHandler(){
var img1;
var img1=new Image();
img1.src='http://sact.atdmt.com/action/adofat_ImageTest27_1';
img1.height='1';
img1.width='1';
}//end function
document.getElementByID("TheExampleLink").addEventListener("click",imageClickHandler,false);
The HTML
test
I hope this helps, and you consider not using onclick. :)

How can you tell which element was selected with a crossrider contextMenu

The data returned by the callback for appAPI.contextMenu is currently only the following:
pageUrl
linkUrl
selectedText
srcUrl
There doesn't seem like there's a way to tell what was actualy right clicked on, only a little information about it. I could for example search all images and find the one with the matching srcUrl, but what if the same image appears multiple times?
I could try catching right click events in extension.js and try to match them with context menu events, but this seems quite round about.
What's the expected method to find the selected element (after receiving the event in the page)?
Lets say for example I want to be able to right click an image and display:none it.
Currently, the Crossrider platform does not support the feature you require and I think your workaround is reasonable. However, I have forwarded your suggestion to the Crossrider development team, who will consider it for future releases.
[Disclosure: I am a Crossrider employee]
As a workaround, this actually seems quite reliable although I haven't tested much. TBH I was expecting coherency issues:
//in extension.js (background.js just forward context menu events)
var lastRightClicked = null;
window.addEventListener("contextmenu", function(e) { //I guess a mousedown event would work here too
lastRightClicked = e.target;
}, true);
appAPI.message.addListener({channel:"contextmenu"}, function(message) {
if (message.menuitem == "Hide")
lastRightClicked.style.display = "none";
});

Firefox seems to ignore event.preventDefault()

I'm working on a page where I have a draggable item (a map inside a container). When you click and drag with the mouse, the map moves and everything is fine. I then wanted to add the same functionality for touch devices (such as a smartphone or a tablet). I searched the net and found a working script that "changes" touch input to mouseinput and thus making it possible to drag the map without dragging the entire page (which is standard behaviour). This is done using the line
event.preventDefault()
It is even possible to have click events as well by timing how long apart the touches are. I am no coding genius and all this programming was done by others. You can see the discussion at Javascript Drag and drop for touch devices (I have used the original code in the top answer as well as the timing code in the answer just below the top answer).
So far, so good. It is now possible to drag the map around and click any links on it or the page just as you would, if you were using a mouse. This works on all touch browsers I have tried (I haven't tried a lot, but the ones I've tried work). The only problem is, that you cannot drag the page itself around, since the default behaviour of the touch has been disabled. This is a problem when the content of the page (for instance the size of the map container) is larger than the browser window.
Luckily an answer was provided for this as well (it is the bottom-most answer on the page I linked to above): replacing
event.preventDefault()
with
if (touches.length > 1) event.preventDefault();
the default scrolling/resizing etc. of a touch works if you use one finger, but if you use more than one finger, the default behaviour is prevented. In other words: If you use two fingers, you can drag the map around without dragging the page (just as before), but if you use one finger, you can drag the page around! I really like this solution as it seems quite elegant to me.
Well, I added the line and tested on the default browser on my HTC Incredible phone (way to small screen but it is what I have). The default browser is just called "Internet". Everything works perfectly!
So, I test on Firefox and Opera, and unfortunately, they are not working perfectly. It seems that once the
event.preventDefault()
is inside the "if" statement, it is completely ignored, so when I drag the map, it IS dragged (as the touch is still converted to a drag of the mouse), but the page itself is also dragged, regardless of the number of fingers I use. In short: The page behaves as if no
event.preventDefault()
is triggered.
I have looked around for several hours and have come to suspect that the event variable needs to be initialized or imported for Firefox and Opera to be able to use it, as described here: jQuery event.preventDefault() not working in Firefox (JSFiddle included)
My question (at long last): Could this be right, and how do I go about "importing" the event into the "if" statement?
The code is here (the init() function is triggered by body onload)
<script type="text/javascript">
var clickms = 400;
var lastTouchDown = -1;
function touchHandler(event)
{
var touches = event.changedTouches,
first = touches[0],
type = "";
var d = new Date();
switch(event.type)
{
case "touchstart": type = "mousedown"; lastTouchDown = d.getTime(); break;
case "touchmove": type="mousemove"; lastTouchDown = -1; break;
case "touchend": if(lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms){lastTouchDown = -1; type="click"; break;} type="mouseup"; break;
default: return;
}
var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);
first.target.dispatchEvent(simulatedEvent);
if (touches.length > 1)
{
event.preventDefault();
}
}
function init()
{
document.addEventListener("touchstart", touchHandler, true);
document.addEventListener("touchmove", touchHandler, true);
document.addEventListener("touchend", touchHandler, true);
document.addEventListener("touchcancel", touchHandler, true);
}
</script>
Edit: I should add that I have tried inserting an alert statement into the if statement, just to see whether Firefox or Opera actually register that a two-finger gesture is performed. The alert is triggered without problems, so perhaps the problem is that once Firefox or Opera has started a two-finger gesture, the standard behaviour of the gesture (draggring or resizing the page) cannot be stopped, at least not in this way.
I seem to have solved the problem (at least on the browsers at my disposal for testing)
What I did was changing
if (touches.length > 1) {
event.preventDefault();
}
to
if (event.touches.length > 1) {
event.preventDefault();
}
It's now possible to drag the draggable element around using two fingers without having the rest of the page move. It's still possible to drag the map with one finger on Firefox and Opera, but this is a minor thing, as soon as you adopt a "use only two fingers when you want to drag" attitude.
The only small issue is that both Firefox and Opera seem to jump back and forth between which fingertip they choose to focus on, making the draggable element jitter somewhat, especially when the fingers are a bit apart. This behaviour is not displayed in the "Internet" browser.

jQuery Image Gallery stops working in IE7&8 after using for small period of time

I have the following code I am using for a photo gallery. In Internet Explorer 7 & 8 the gallery stops working. The image fades out after several clicks and the new image does not fade in. After this occurrence happens (about 6 or so clicks) the gallery does not function at all. All other browsers work flawlessly. I have also used this code in several other pages with no problems.
$("#list-image-carousel").find('a').click(function(e) {
e.preventDefault();
var src = $(this).attr("href");
$("#main-img").find('img').fadeOut(400,
function() {
$("<img/>").attr("src", src).load(function() {
$("#main-img").find('img').attr("src", this.src).fadeIn(400);
})
})
});
Any ideas are greatly appreciated. Thanks in advance!
Here's one possibility: it looks like you're establishing the "load" handler on your temporary image element after you're initializing the "src". That's a problem in IE - reverse the order of those things and see if that helps.
$("#main-img").find('img').fadeOut(400,
function() {
$("<img/>").load(function() {
$("#main-img").find('img').attr("src", this.src).fadeIn(400);
}).attr("src", src);
})
If the image is in the cache, then when you assign the "src" attribute IE will immediately ready the element. If there's no "load" handler defined at that point, it won't queue up the event at all.
Also, just as a note, the construct
$('#main-img').find("img")
could be written:
$('#main-img img')
Doing it like that is a little shorter, but in truth it may or may not actually be faster. Probably would be, I think.

Categories