I have a element which contains an element. I've found that in Internet Explorer and Firefox, the mouseover event doesn't fire when I move over the element inside the button. In Chrome it does. Which browser(s) is behaving correctly and where might I go to report the bug? (this might not be the correct place to ask the question)
<button><img id="TheImage" src="Images/Action.gif" /></button>
<script type="text/javascript">
window.addEventListener("load", function() {
document.getElementById("TheImage").addEventListener("mouseover", function(event) {
console.log(event);
});
});
</script>
I want the event to fire and it seems like it should since that's the behavior on every other parent element.
It may be related to bug in FF:
https://github.com/mootools/mootools-core/issues/2662
Though it should works good in IE.
Related
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("p").on("click", function(event){
console.log("print originalEvent name", event.originalEvent.constructor.name)
});
});
</script>
<p>Click this paragraph.</p>
I recently found that when using mouse click on Safari, "event.pointerType" is undefined where as in chrome it is coming as "mouse" .
I need to do a similar check in safari browser to pass my condition.
I tried couple of things, like using pointerDown eventListener but due to some limitations(like my pointerDown listner code is inside a different jQuery.On listener and due to that it is not triggering on first click and also only either of those listeners are executing skipping the other which should not happen in my case. As i do not have control on jQuery listener trigger i am not able use all eventListener options for this approach to work).
So after some debugging I found on Safari Browser for mouse click events the value of below is coming as "MouseEvent" which works for my requirement. But can i rely on this value for this and is it ok to use the constructor name here.
$(document).on("click", ".my-btn-class", function(evtParam){
if(evtParam.originalEvent && evtParam.originalEvent.constructor &&
evtParam.originalEvent.constructor.name === "MouseEvent"){
//do my logic
}
})
I have the following jQuery which works in all major browsers except Opera:
jQuery(document).ready(function () {
jQuery("#GetResults").live("click", function(e){
e.preventDefault(); //Opera doesn't execute anything here
});
};
Which is supposed to fire when clicking the following link:
<a id="GetResults" href="Folder/File/javascript:void(0);">Get Results</a>
Only Opera ignores this. Any ideas?
Edit:
I've just discovered that if I substitute out .live() for .bind() everything functions as expected. I can't find any documentation relating to .live() bugs in Opera though, and it does work in jsFiddle which would point at something environmental. What could be causing this behavour?
This needs clarification. The answers above are correct, but nobody clearly explained where your problem comes from.
In fact I think that you could probably reproduce the problem in other browsers too.
That's because of how .live works:
It binds to the event on document and waits for a particular event to bubble up to there. Then it checks if the event.target is what you wanted to handle. *
If you click on a link element it's quite possible that the browser goes to the new page before the event bubbles high enough to trigger your code. In an app with lots of HTML and event handlers all the browsers should have problems. Opera just starts displaying the new page and destroys the previous quicker in this case. It really depends on a particular situation more than on the browser. For example: you probably won't see this happen if you had a high network latency while connecting to the site.
To prevent default action on a a element you have to use .bind like in the old days ;) when a eveloper had to be aware of what he loads with AJAX and bind new events to that in a callback.
* There is more to that and .live is more complicated. I just described what is needed here.
What happens when you attach the handler using:
$ (something).bind ("click", function (e) {
// do something
})
You can also try to attach the handler using .click() method.
The following code works as expected in Opera 11.50.
<!doctype html>
<title></title>
<a id="GetResults" href="http://google.com">Get Results</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script>
jQuery(document).ready(function () {
jQuery("#GetResults").live("click", function(e){
alert('doing something');
e.preventDefault(); //Opera doesn't execute anything here
});
});
</script>
Either it is a corrected bug, or something more subtle.
Can you check whether the above works on your version of Opera / jQuery?
Read this article: http://jupiterjs.com/news/why-you-should-never-use-jquery-live
try use delegate instead
Not sure if you want to do it, or if it will work for you. I had similar issues with Opera 9.5 and e.preventDefault() not working, the only solution I found was to just return false...
jQuery(document).ready(function () {
jQuery("#GetResults").live("click", function(e){
e.preventDefault();
return false;
});
};
There are two aspects of an event bubbling worth considering in this case: propagation and the default action.
Propagation refers to the event bubbling. First the anchor tag gets the click event, then its parent element, then its parent's parent, and so forth, up to the document element. You can stop an event from propagating at any time by calling e.stopPropagation().
The default action is what the browser will do if nothing is done to prevent it. The most well-known case is when an anchor with an href is clicked, the browser will try to navigate there. There are other examples too, though, for example when you click and drag an image, many browsers will create a ghost image you can drop on another application. In both cases, you can stop the browser from doing the default action at any time by calling e.preventDefault()
As mentioned in other answers to this question, jQuery's .live() feature sets a handler at a high level element (like document) and takes action after events have propagated up. If a handler in between the anchor and the document calls e.stopPropagaiton() without calling e.preventDefault() it would stop the live handler from responding, while still allowing the browser to navigate (the default action).
I doubt this is what's happening, since it would affect all browsers, but it's one possible explanation.
Ensure that document.ready event happens before you click on link.
Try to put all lives in the top of the document.ready wrapper. It may help, if you have a lot of javascript code.
I have some javascript click handlers that don't do what I want in IE8. What I want to do is call a handler on the first click and then call another handler on all subsequent clicks. The way I do that is put the original handler in the onclick attribute and then use that handler to erase the onclick attribute and use Event#observe to set up the handler that is called on subsequent clicks but for some reason IE8 refuses to cooperate. Instead of the following program flow
click->call originalHandler->erase originalHandler->set newHandler
I get the unexpected program flow
click->call originalHandler->erase originalHandler->set newHandler->call newHandler
I can't figure out why a single click event fires both handlers. Here's the snippet of the offending code, the pastie link and a link to a page that consistently reproduces the bug on my laptop with ie8.
//weird behavior in the latest prototype version with ie8
function originalHandler(event) {
Event.stop(event); //this doesn't help either, the event still triggers newHandler
var button = $('button');
alert("first click");
button.writeAttribute({onclick:null});
function newHandler(event) {
//this should only show up on the second click
//but it shows up on the first click as well
alert('second click');
}
button.observe('click',newHandler);
}
So to get the desired behavior I have to add an extra layer of indirection which seems really weird. So the following code fixes the issue with IE8 but breaks firefox and chrome behavior because now "second click" doesn't show up until the third click. Here's the pastie for the version that works on IE8 and the link to the page that behaves correctly on IE8 but requires an extra click on chrome and firefox.
function originalHandler(event) {
Event.stop(event);
var button = $('button');
alert("first click");
button.writeAttribute({onclick:null});
var newHandler = function(ev) {
button.stopObserving();
button.observe('click',function() {alert("second click");});
}
button.observe('click',newHandler);
}
Any ideas on how to fix this bug and get consistent behavior across all browsers?
I also asked on the prototype mailing list and the answer I got was that basically what's happening is that IE8 calls the DOM0 handler and then calls DOM2 handlers which is what I set up with Element#observe and the way around it is to set up a delay so that the DOM2 handler is not set up until the first event bubbles all the way up without any DOM2 handlers in the way. Oh how I hate cross-browser compatibility.
I have designed a website with a menu that is initially invisible. When the user clicks on a button, the menu becomes visible. There are two ways for the user to hide the now visible menu:
Click the button that caused the menu to become visible
Click anywhere on the web page that isn't the menu
The way I have coded the second option is to tie an onclick event to the window element, and have it compare where the user clicked to the menu's position to determine if the menu should be hidden. This works great in Firefox and Safari, but it fails in Mobile Safari.
I noticed that the window onclick event only fires when I click on another element with an onclick event already assigned. If I click on an element with no event(s) assigned, the window's onclick event never fires. If I click on the button which displays the menu, it fires along with the event tied to the button.
Is it possible to assign events to the window element in Mobile Safari?
I'v been encountering this same problem. Here is what worked for me. (Note: I am working within a Modernizr and jQuery context)
First, I add a custom Modernizr class using Modernizr's addTest Plugin API to test for iOS, which will add the class appleios or no-appleios accordingly.
Because in my research the body seems to fire events on it's own agenda, I am taking a little precaution by wrapping all the document's content with an element in an iOS context. Then I add an event handler to this element.
$(".appleios body").wrapInner('<div id="appleios-helper" />');
$("#appleios-helper").bind("mouseup", function(){return;});
What was suggested earlier in this thread is using void(0). I did some quick testing, and found that void(0) as the event just wasn't causing touches on the body to be recognized. When I plugged in my own "empty" function in the form of function(){return;} things started working.
This all hinges on the fact that no events are fired in Mobile Safari unless the element explicitly has events to fire (Safari Web Content Guide.) By inserting this empty event on the wrapper, things will bubble up to the body.
If you're doing strait JavaScript with none of these libraries, the same effect could be achieved in the HTML markup
<html>
...
<body>
<div id="appleios-helper" onmouseup="function(){return;}">
...
</div>
</body>
</html>
This worked for me to hide tooltips when touching anywhere on the document's body. Your mileage may vary.
Simply adding the dummy onclick handler to the html body works for me:
<body onclick="void(0)">
Note that I am using usual live event handlers as shown below:
function liveHandler( event ) {
var target = event.target; ...}
window.addEventListener(evtype, liveHandler, true);
// evtype such as 'mousedown' or 'click'
// we use the capturing mode here (third parameter true)
This is an old question, but I struggled with the same thing today.
I found that using touchstart event works.
I solved it like this:
var isTouchDevice = 'ontouchstart' in document.documentElement;
if (isTouchDevice) {
// Do touch related stuff
$(document).on('touchstart', function (event) {
// Do stuff
});
} else {
// Do non-touch related stuff
$(document).on('click', function () {
// Do stuff
});
}
You could just add onclick="void(0);" to some <div> that covers the whole page so that no matter what, you are always clicking on an element that has an onclick event. Not a great solution, though.
I'd prefer not having the onclick event be tied to the window. Why don't you create a container <div> that has that event on it. Then handle it just like you currently are.
You can also:
$('body').css('cursor', 'pointer');
No idea what those "engineers" at Apple are doing. LOL.
This has problems though. You wouldn't want to do this on every touch device. Only touch devices that don't also have a pointing device (Laptops with Touch Screens, for example).
Source: http://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
The conclusion of the article is this:
So I don’t understand why all this is the case, but it most certainly is the case. If you’re having bubbling problems, just add an empty-function event handler anywhere between the body and the element, and you’re set to go. But it shouldn’t be necessary.
The problem is as follows.
onbeforeunload works like a charm in Firefox and has e.explicitOriginalTarget.activeElementthat shows what element has been clicked to cause it.
window.onbeforeunload = function(e){
if (e.explicitOriginalTarget.activeElement){
return;
}
In Chrome the 'e' object looks identical when you close the window or click the link.
Is there any way to determine the target in chrome?
Late response, I know, but you can always try this (confirmed working in IE):
target = document.activeElement;
alert(target.href);
Just showing you that you can grab the active element and then just parse the href to figure out what is happening.
Another option:
$("a").on("click", function(){
window.last_clicked = $(this);
});
Then simply refer to last_clicked from within your onbeforeunload handler. This is the best cross-browser compatible solution I've found, since document.activeElement is unreliable.
No. The target of the event is the window or document, not the link. Unlike Firefox, Chrome provides no helpful bonus properties on the event object. Your best bet may be to have an click event handler on the body that examines the event target to see if it's a link, but that's not foolproof: the link may have its own click event handler that prevents the default action, or the user may follow the link using the keyboard, in which case no click event will be fired.