Catching tab key navigation - javascript

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.

Related

How do I check if a event is triggered or when to use keypress versus keyup?

I've added page navigation to the window using the keypress event and noticed it's not working on some browsers. If I use keyup in those browsers the event is triggered.
So my question can be solved by knowing either:
For most browser compatibility do I use keyup or keypress? Can I
use both?
How do I test if an event is supported? For example, if I know the
brower supports keypress I'll add a handler for it. If it supports
keyup, I'll add a handler for that. I can add the event handler
dynamically.
History:
In ES4 there was a willTrigger method but I don't see that method in the DOM.
Update:
I found a possible answer here. It says that in some browsers keypress is dispatched where is does not make any distinction when mentioning keyup.
To quickly differentiate between keypress and keyup, keyup will fire only once, no matter how long a key is pressed down for , whereas the keypress event can fire multiple times. You can use both (I don't see why not - you'd use them for different things) , and basic support for the events is present cross-browser (although figures for mobile browser support is not fully known). There are jquery equivalents of both the .keyup()/ onkeyup and .keypress() / onkeypress
Hope this helps

Detect if CKEditor used a keyup event, or prevent its propagation

In short
Is there a way in which, when listening to a native event, I can detect if the event was somehow used by CKEditor before it propagated to my listener, or prevent it from propagating at all?
Use case
I'm listening to the keyup event using jQuery, to detect when escape is pressed. When it is, the user is prompted if they want to discard changes, and the CKEditor instance is destroyed and its element removed from the DOM.
$('body').on('keyup', function(e){
if(e.which==27){
CKEDITOR.instances.myDiv.destroy();
$('#myDiv').remove();
}
});
The problem here is that CKEditor allows the user to interact with certain UI elements using the escape key. For instance to close a dialog window or drop-down list.
So my event should only execute its code if CKEditor did not already use the event to close a UI element of its own.
Attempt
I tried to listen to the dialogShow and dialogHide events to detect if a dialog window is open, and my action should thus be ignored. This didn't work for two reasons:
CKEditor handles the event first, so by the time the event propagates to my listener, no dialog windows are open and my code is executed.
Even if it would work, it wouldn't for drop-down lists as they do not trigger the dialog* events.
Ideas
I don't know enough about the workings of CKEditor to come up with a solution, but I think I'm looking for something along the lines of:
A setting in CKEditor to prevent event propagation: CKEDITOR.instances[0].noEventPropagation = true
An indication in the original event object: if(event.CKEditorWasHere){/*do nothing*/}
A plugin providing functionality that I can use.
Worst case scenario: A setTimeout in the dialogHide event which I'll use to suppress my own events for a short time.
So
Maybe I'm completely overlooking something. This seems to me like a common problem which should have a simple solution.
Thanks for your time.

Internet Explorer Fires Change Events On Keypress

IE fires the change event on a select menu when using the arrows to navigate the menu. This is not the case in non-IE browsers. Non-IE browsers only fire the event when clicking on the option, or pressing enter after navigating to the item with the arrows. Is there a way program around this? I need the event to not fire when navigating with the keys.
I would add my own change event listener and handle things that way if I could. Without knowing all of the details it's hard to say but I'd look there first because the event cannot be cancelled. Outside of that approach, IE is going to fire the event when the value changes so not much you can do about that. Here is a link to the change/onchange in IE. It actually says this in the doc.
To invoke this event, do one of the following:
Choose a different option in a select object using mouse or keyboard navigation.
Alter text in the text area and then navigate out of the object.
It stinks but one of those you have to account for when using a select field.
The solution that worked for my situation was the following.
bind to the blur event instead of the change event.
This introduced another issue, where when I initially load the page the select fires a change event, and I need the code in my blur binding to take effect. Binding to change and having it trigger blur caused massive recursion. The solution was to create an init function that ran at startup.
initData : function(){
var t = this,
formSelects = 'select';
jQuery.each(formSelects, function(){
// do my code here that normally happens in blur.
})
}

Listen for deletion of input value

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.

Does the onchange event propagate?

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)

Categories

Resources