Trigger event from inside event hander has different behavior in IE10 - javascript

I want to trigger a blur within a keypress. IE10 works differently from Chrome/FF. It appears that IE will finish the keydown handler before calling the blur handler, whereas Chrome and FF will trigger the blur handler right when the blur occurs and then go back to finish the keypress handler.
I'm wondering if this is a bug and if there is a good workaround in IE to work like Chrome and FF.
See the code below.
$(document).ready(function () {
document.getElementById("txtInput").addEventListener('blur',
function (event) {
console.log('blur');
});
document.getElementById("txtInput").addEventListener('keydown',
function (event) {
console.log('down 1');
document.getElementById("txtInput").blur();
console.log('down 2');
}
);
});
http://jsfiddle.net/244raf1u/
Output from Chrome:
down 1
blur
down 2
Output from IE
down 1
down 2
blur

Try this:
$(document).ready(function () {
$("#txtInput").blur(function (event) {
event.preventDefault();
console.log('blur');
});
$("#txtInput").keypress(function (event) {
console.log('down 1');
$(this).blur();
console.log('down 2');
});
});
Check out the changes I made in this updated fiddler here.
I had to change the way you were calling the blur() trigger, and then added a simple event.preventDefault() in the blur() handler to prevent a second firing in IE. It seems like IE was trying to move focus off of that input after running the keypress handler.
Also by using this notation: ($("#txtInput")[0]) you are actually referring to the original element object and not the jQuery object, which may be causing issues in IE where the other two are catching the error.
Hopefully this will help!

I found a couple solutions. First is to use the focusout instead of blur. Blur doesn't bubble, focusout does. Not sure why that matters, but the events are probably implemented differently. Unfortunately, that's not an option for me.
The other solution was to have two keydown handlers. The first triggers the blur and anything I want to happen before the blur. The 2nd handler does the processing after the blur, but I have to set a 50ms timeout because all keydown handling occurs before the blur handling.

Related

jQuery.trigger('click') results in "change" Event in IE8

$('#myRadioButton').change(function(event) {
var eventType = event.type;
$(this).trigger('click'); // In IE8 only, this results in endless loop
});
The code snippet above results in a change event being fired in IE8 and hence an endless loop is started when my radio button is selected. This is not the expected behaviour, as a 'click' event certainly is not a 'change' event. In other browsers and IE9+ the code works as expected (i.e., not an endless loop).
The variable eventType equals "change" in IE8, both for initial, user triggered 'change' event, but also for the subsequent calls to itself.
What is the reason for this behavior and how to stop IE8 from being a jerk and act like a normal browser?
Best regards!
Reason - no idea sorry.
'Work Around' :-
function radioChange() {
$(this).off('change', radioChange);
$(this).trigger('click');
$(this).on('change', radioChange);
}
$('#myRadioButton').change(radioChange);
trigger is synchronous, so removing the change, then triggering the click, then re-attach the change should work.

mouseup event on document.documentElement does not fire with alert

I need to detect mouseup event after mousedown on the document.
I have tried to add an event listener to document and document.documentElement with no success.
I need possibly a cross platform solution without jquery.
Notes: problem appears on not all browsers using alert().
http://jsfiddle.net/0f7vrzh7/8/
document.documentElement.addEventListener('mousedown', function(){
alert('mousedown');
});
document.documentElement.addEventListener('mouseup', function(e){
alert('mouseup')
});
In certain browsers the first alert would stop the second event. It works even with alert in IE11 for example. In the browsers where you experience this issue the alert box blocks the UI before the mouseup event is processed or propagated to the element you have the event handler attached to. Change to console.log() statements in your event handlers and the events are fired as you expect them to. Updated fiddle.
it's yours alert block the mouseup event. try with
document.documentElement.addEventListener('mousedown', function(){
document.getElementById("test").style.backgroundColor = "#ff0";
});
document.documentElement.addEventListener('mouseup', function(e){
alert('mouseup')
});
http://jsfiddle.net/0f7vrzh7/16/

How to prevent touchend event after dragend?

I'm working on a mobile site and struggling with events firing when I don't want them to.
For the sake of simplicity, it's written something like this (in jQuery):
el.on('touchend', function(ev) {
ev.preventDefault();
// fire an ajax call
};
However, sometimes a user would hit the item when scrolling the page, causing the ajax request to fire (thus changing the page state).
I couldn't think of a way around it (ev.stopPropagation() didn't work) , so I decided watch for dragstart and dragend events.
el.on('dragstart', function() {
el.off('touchend');
});
el.on('dragend', function(ev) {
ev.stopPropagation(); // <-- seems to do nothing
// add back the event above (the function is set to a var)
});
If I alert inside the touchend callback, I get confirmation that the touchend event did in fact fire after I stopped dragging.
Does anyone have any idea how to prevent any other events from firing? I'm hoping I'm just being blind and missing something obvious.
You can't stop an event from firing, you can only prevent the default behavior for that event from happening.
If you're worried about the state of your page changing before the touchend event fires, you should just change your function to check for and then account for the state change.
I think in a case like this you should use event.stopImmediatePropagation();

Does event.stopPropagation in a checkbox click event prevent the change event from firing in IE8 and earlier?

It appears that event.stopPropagation() in a checkbox click event prevents the associated change event from firing in IE before IE9.
(The following code is in jsFiddle)
<input type="checkbox" value="Y" checked>Test
<div id="output">Logging...</div>
With the following jquery block the change event doesn't fire in IE8 and earlier but it does fire in IE9 (and Chrome):
$(document).ready(function() {
$("input").click(function(event) {
event.stopPropagation();
$("#output").append("<pre>click</pre>");
});
$("input").change(function(event) {
$("#output").append("<pre>change</pre>");
});
});
Chrome and IE9 give:
Logging...
change
click
change
click
change
click
Whereas IE8 and earlier gives:
Logging...
click
click
click
However, if I put specific 'before IE9' handling then all works as expected:
With the following jquery block:
$(document).ready(function() {
$("input").click(function(event) {
event.stopPropagation();
$("#output").append("<pre>click</pre>");
// fix event bubbling before IE9
if ($.browser.msie) {
if (parseInt($.browser.version, 10) < 9) {
$(this).trigger("change");
}
}
});
$("input").change(function(event) {
$("#output").append("<pre>change</pre>");
});
});
Is this expected behaviour?
This is a well-known IE8 bug which has nothing to do with event bubbling: the change event only fires on checkboxes when the focus leaves them.
(Compiling the comments on Tgr's answer so I can accept an answer.)
If the "event.stopPropagation()" line is removed from the click event the change event is fired as expected in IE8, so this isn't the well-known IE8 bug mentioned by Tgr.
#Tgr confirmed that:
jQuery tries to normalize most browser quirks, including this one: it simulates a change event on click and eats the one fired on blur (see jQuery.event.special.change). stopPropagation probably interferes with that.

jQuery live('click') firing for right-click

I've noticed a strange behaviour of the live() function in jQuery:
normal
live
$('#normal').click(clickHandler);
$('#live').live('click', clickHandler);
function clickHandler() {
alert("Clicked");
return false;
}
That's fine and dandy until you right-click on the "live" link and it fires the handler, and then doesn't show the context menu. The event handler doesn't fire at all (as expected) on the "normal" link.
I've been able to work around it by changing the handler to this:
function clickHandler(e) {
if (e.button != 0) return true;
// normal handler code here
return false;
}
But that's really annoying to have to add that to all the event handlers. Is there any better way to have the event handlers only fire like regular click handlers?
It's a known issue:
It seems like Firefox does not fire a
click event for the element on a
right-click, although it fires a
mousedown and mouseup. However, it
does fire a click event on document! Since .live catches
events at the document level, it sees
the click event for the element even
though the element itself does not. If
you use an event like mouseup, both
the p element and the document
will see the event.
Your workaround is the best you can do for now. It appears to only affect Firefox (I believe it's actually a bug in Firefox, not jQuery per se).
See also this question asked yesterday.
I've found a solution - "fix" the the live() code itself.
In the unminified source of jQuery 1.3.2 around line 2989 there is a function called liveHandler(). Modify the code to add one line:
2989: function liveHandler(event) {
2990: if (event.type == 'click' && event.button != 0) return true;
This will stop the click events from firing on anything but the left-mouse button. If you particularly wanted, you could quite easy modify the code to allow for "rightclick" events too, but this works for me so it's staying at that.
You can actually rewrite it as:
function reattachEvents(){
$(element).unbind('click').click(function(){
//do something
});
}
and call it when you add a new dom element, it should have the expected result (no firing on the right click event).
This is an unfortunate consequence of how live is implemented. It's actually uses event bubbling so you're not binding to the anchor element's click event, you're binding to the document's click event.
I solved this by using mousedown events. In my situation the distinction between mousedown and click didn't matter.

Categories

Resources