What happens when you blur a DOM Element

2019-07-26 08:01发布

I am having a hard time finding any documention on what is "suppose" to happen whenever a DOM element is blured.

My naive assumption was that the browser whould traverse up the DOM to find the next focusable element - but given the following jsfiddle, that is obviously not what happens.

jsfiddle-example

<!-- HTML ----------------------------- -->
<body>
    <div id="root" tabindex="0">root
        <div id="p1" tabindex="0">p1
            <div id="p2" tabindex="0">p2
            </div>
        </div>
    </div>

</body>

/* Javascript */
var root = document.getElementById("root");
var p1 = document.getElementById("p1");
var p2 = document.getElementById("p2");


root.addEventListener('keydown', function(event) {
    console.log("root keydown"); 
}, false);

p1.addEventListener('keydown', function(event) {
    console.log("p1 keydown"); 
}, false);

p2.addEventListener('keydown', function(event) {

    console.log("p2 keydown - blurring p2, hoping that focus will move up the dom to p1"); 
    event.stopPropagation();

    p2.blur();
    if (document.activeElement !== p1)
        console.log("well, that didn't work out so well :( ");
    console.log("focused element = ");
    console.log(document.activeElement);

}, false);



p2.focus();
console.log("focused element = ");
console.log(document.activeElement);

So is there a definition of what should happen? What I see happening with Chrome is that the activeElement jumps to the body - and skips all of the focusable items along the way. It is unclear if body is even focused, or is just the default handler for activeElement if nothing else is focused.

Given a complex object-oriented javascript application, in which p2 does not know about p1, but assumes that anything higher up in the DOM will gain focus, am I really suppose to manually traverse up the DOM on every blur() event and search for focusable elements and focus them myself?

4条回答
forever°为你锁心
2楼-- · 2019-07-26 08:35

The closest thing to a specification about this is probably the description of focus in HTML5 CR (which is work in progress, “a draft document and may be updated, replaced or obsoleted by other documents at any time”, but in practice close to a consensus). It says: “There may be no element focused; when no element is focused, key events received by the document must be targeted at the body element, if there is one, or else at the Document's root element, if there is one. If there is no root element, key events must not be fired.”

Since the blur() method is defined (in DOM 2 HTML spec) simply as removing focus, it means leaving a page in a state where no element is focused. But this may look like the body element were focused: if you have, say, a keypress attribute on it, it gets triggered. This however differs from the focused state. For example, in this situation, the body element does not match the CSS selector :focus.

The conclusion is that you should normally avoid using blur() and do focus() on some suitable focusable element instead, as suggested in other answers. An exception is a situation where you just want to discard all keyboard events. Then blur() is OK, provided that your code does not assign any keyboard event handlers to the body element.

查看更多
Emotional °昔
3楼-- · 2019-07-26 08:40

If you just want to make sure that one element gets focused when another gets blurred:

/* Javascript */
var root = document.getElementById("root");
var p1 = document.getElementById("p1");
var p2 = document.getElementById("p2");

p2.addEventListener('blur', function(event) {
    p1.focus();
    activeEl();
}, false);

p2.focus();
activeEl();
function activeEl() {
    console.log("focused element = ");
    console.log(document.activeElement);
}

Fiddle: http://jsfiddle.net/2cWcA/

You could extend this so that when any element is blurred, it's parent's focus method is called.

查看更多
Anthone
4楼-- · 2019-07-26 08:48

My understanding is that blur just means unfocus. In other words, the focused element loses focus, and it's undefined what, if anything, gains focus. The fact that activeElement becomes body is probably just a side effect. Rather than setting it to null it's set to the body, to indicate that the document in general still has focus.

查看更多
再贱就再见
5楼-- · 2019-07-26 08:49

Actually document.ActiveElement() focuses an element. In javascript focus is done like document.getElementById('myAnchor').focus() MoreOver the focus event triggers when a visitor focuses on an element.

Not all elements are focusable by default. For example, INPUT and all types or form fields support this event, A supports it. As a counterexample, DIV doesn’t support focus.

The list of elements types which support focusing is slightly different between browsers.

Thanks

查看更多
登录 后发表回答