I'm using event delegation to listen for events lower in the DOM, but it's not working for an onchange event on a select box. Does the onchange event propagate or bubble up the DOM?
Googling has failed in finding a conclusive answer.
According to specification, change, submit, reset should bubble and focus and blur should not bubble.
This behavior is implemented properly in all web browsers except IE < 9, that is, change, submit, reset do bubble properly in IE >= 9.
See https://stackoverflow.com/a/4722246/227299 for a jQuery workaround on old IE versions
http://www.quirksmode.org/dom/events/change.html
http://quirksmode.org/dom/events/submit.html
In jQuery 1.4+ the change event bubbles in all browsers, including IE.
$('div.field_container').change(function() {
// code here runs in all browers, including IE.
});
I haven't dealt with this for quite a while, but last time I did, I remember that Firefox recognized the event on the <SELECT> element, while IE6 recognized only events on the <OPTION> tags. As far as I remember.
IE7 was not out at that time.
So if this is the case, it makes even more sense to not write the event handler inline and apply it on DOM ready instead, lest you are going to have a lot of polluted, repetitive code.
Not sure if I get the question, but if you mean this, then NO.
<div id="foo">
<select onchange="alert('hi');">
<option>Hello</option>
<option>World</option>
</select>
</foo>
Where the div id="foo" would have an onchange event... bubbling up from the select list?
on a related note, just an FYI you can't attach an event to the options within the select list in IE (well, you can but it won't fire)
Related
I am writing a HTML editor, anyone can plug this plugin into their site and make use of it.
Plugin Usage
$(".editable").htmleditor();
Onclick on this elements I will change the element into contenteditable and my editor menu will be opened near the element like aloha editor.
Problem
Scenario 1
<div class='editable' onclick='loadUrl('https://facebook.com')'>
</div>
Scenario 2
<div class='editable' id='openNewWindow'></div>
<script>
$("#openNewWindow").click(function(e){
e.preventDefault();
e.stopPropagation();
});
</script>
Aforementioned scenarios I won't receive the event. It makes my plugin not reliable. I tried couple of solutions.
Solutions I tried
Removed all elements in a body and reinserted into it again to remove attached event handlers. It works but the UI is distorted while inserting in some sites.
Added onclick='return false' attribute in all elements. It works for some elements only.
How to unbind all attached event handlers and prevent the default event of an element?
In Scenario 1, the user of your plugin has both made an element editable, and also made clicking on it navigate away from the current page. That doesn't make much sense, but it's their business. In this situation they can't realistically expect your plugin to run.
In Scenario 2, you need to process the click event before it's handled elsewhere. Removing or suppressing existing handlers is not a good idea: it may make other parts of the page fail, and is annoying to your users in any case.
Instead, you can make your handler run in the event capture phase like this:
editableElement.addEventLister("click", myHandler, true); // note the "true"
Now your handler will run before all handlers added using JQuery (and most handlers that people add via any means), which run in the event bubble phase. Note that this technique only works in modern browsers (i.e., not IE < 9).
For reference: What is event bubbling and capturing?
I have a page that has some td elements in a table that the user can click and drag to reorder. The page is built using prototype. In everything but IE9, this works, but in IE9, when I try to click and drag, I just highlight some of the things on the page. My suspicion is that the handler isn't actually attaching to the td element.
Is there a way to check what listeners are attached to an element in IE9?
(The code is also not in a place that I can share it, which is why I have not posted any.)
Edit: It turns out I was actually using prototype 1.6.1, and the problem was ultimately caused by that not knowing that IE9 and IE10 are less awful than < 9. It's going to be a much bigger fix than I thought.
The latest PrototypeJS (1.7.1) stores the event observers in an Event Cache
So for example a <div> with id 'mydiv'
<div id="mydiv"></div>
After you create an observer via the observe() or on() methods like this
$('mydiv').observe('click',function(){
alert('Click Happened');
});
The click property of the Event cache will be set like below
Event.cache[$('mydiv')._prototypeUID].click
However this might not be the source of your problem as you said it is working in all other browsers except IE9 - is there a way you can extract some of the code and put it into a JSFiddle and then post the link?
I need to reliably detect the state change of radio buttons/checkboxes on my page in order to watch if the form was modified or not. Now, this is a completely separate script, I cannot modify anything that controls the form.
Right now, I can see only two ways of doing this:
onchange event handler, which helps with textboxes, textareas and selects, but is not fired for checkboxes/radiobuttons
onclick event handler, which is not reliable, because users often use hotkeys to change the values of these elements.
What am I missing here? Is there a way to reliably detect that checkbox was checked/unchecked?
UPDATE: As you guys pointed out, change event is really fired on checkboxes/radiobuttons, despite the fact that w3schools says it is only for text inputs
However, my problem turned out to be that the values of checkboxes/radiobuttons are set via setAttribute in scripts and in that case the event is not fired.
Is there anything I can do in this case?
See: http://www.quirksmode.org/dom/events/change.html.
It says that all major browsers support change event but the IE's implementation is buggy.
IE fires the event when the checkbox or radio is blurred, and not when it is activated. This is a serious bug that requires the user to take another action and prevents a consistent cross-browser interface based on the change event on checkboxes and radios.
I think you can overcome IE's bug with this trick. blur() elements when they focued! (Use something like $('input[type=radio]').focus(function(){$(this).blur();}); in jQuery or use pure javascript)
Ok, after some digging, here is what I found out. Note, this is applicable to Firefox, and, probably to Firefox only. Since in this case I was dealing with internal application, this was enough for me.
So, basically, in order to reliably detect changes in checkbox/radiobutton state in Firefox, you need to do two things:
Set up custom Firefox's event handlers CheckboxStateChange and RadioStateChange for checkbox and radiobutton respectively. These events will be fired when the user changes the inputs or when it is modified via script, using setAttribute, however, these events are not fired, when the state is changed in the script, using checked or selected properties of these elements, this is why we need ...
Watch the changes of the checked property using Object.watch
Standard onchange event is no good, since it only fired when user changes the value directly.
Damn, this thing is broken...
If people get interested, I'll post some code.
One of the most recommended ways to listen for a change of a input text field is to bind that field to a key up event. That works fine in most cases. But there are cases where this is not working. In Firefox for example one has the option, when text is already selected, to delete it by using the context menu. And this doesn't fire a key up event. I haven't found any event that is fired for that text field when doing this.
Any suggestions how I can react on this (in pure Javascript or jQuery)?
See the oninput event, and my write up about it here.
oninput fires for all forms of text input - including cut, paste, undo, redo, clear, drag and drop and spelling corrections. It's a HTML 5 event which isn't supported in Internet Explorer 8 and lower (but it is in the latest IE 9 preview). However, Internet Explorer supports a proprietary event on all DOM objects - onpropertychange. This fires whenever the value of an input element changes.
I didn't notice you'd tagged with jquery — since you did, it's probably worth mentioning that I wrote a plugin to implement the oninput event cross browser. You can find it here.
The best way is to store the value on a focus event and recheck the value on a blur event. Listening to key events fires a lot of usually redundant processes. Most of the time, you are only interrested in a field value when the user is done inputting (or deleting) it.
This works cross browser, though delegating focus/blur can be an issue in some browsers. The easiest way is to apply blur/focus listeners to the element directly.
Only exceptions are implementations like autosuggest/complete and even then you might want to debounce key input so it only fires when the user idles for a few hundred miliseconds.
I want to catch which element is on focus when users use tab key to move their focus. For example, there is a form and users can use tab key to move forward to next form element. I'd like to know which element is the current on focus.
Thanks,
Paul
For many event types one can use event delegation, whereby one captures the event on some containing element as it bubbles up the document hierarchy, and then establishes the element on which the event originated. Unfortunately, the focus, blur, and
change events do not bubble.
However, in DOM implementations that implement the standard DOM Events model, one can instead use the capture phase, which intercepts the event on its way down to the element where it will fire.
This doesn't work in (surprise, surprise) Internet Explorer (IE), which still doesn't have an implementation of the standard event model, even in IE8. However, IE has its own focusin and focusout events, which do bubble.
The end result is that, as usual, one has to write one's code so as to deal with the way proper browsers work, and also with the way IE works.
Luckily this is one of those cases where ppk (aka Peter-Paul Koch) of quirksmode.org has already done the hard work: his article Delegating the focus and blur events should tell you all you need to know, as well as providing a succinct explanation of how event delegation works.
use the onFocus event on the form elements, so
<form>
<input id="fred" type="text" onFocus="alert('focused this');"/>
</form>
check out http://www.w3.org/TR/html4/interact/scripts.html#adef-onfocus
there are javascript events that are related to focus. The onfocus and onblur (opposite of focus) events can be used to update a variable that says which form element is currently in focus.