【问题标题】:What happens when you blur a DOM Element模糊 DOM 元素时会发生什么
【发布时间】:2013-11-10 07:04:28
【问题描述】:

我很难找到任何有关“假设”在 DOM 元素模糊时会发生什么的文档。

我天真的假设是浏览器会遍历 DOM 以找到下一个可聚焦元素 - 但鉴于以下 jsfiddle,这显然不会发生。

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);

那么有什么应该发生的定义吗?我看到 Chrome 发生的事情是 activeElement 跳转到 body - 并跳过所有可聚焦的项目。尚不清楚 body 是否甚至是焦点,或者只是 activeElement 的默认处理程序,如果没有其他焦点。

给定一个复杂的面向对象的 Javascript 应用程序,其中 p2 不知道 p1,但假设 DOM 中更高的任何东西都会获得焦点,我真的想在每个 blur() 事件上手动遍历 DOM并搜索可聚焦的元素并自己聚焦?

【问题讨论】:

    标签: javascript html dom dom-events onblur


    【解决方案1】:

    最接近规范的可能是 HTML5 CR 中的 description of focus(正在进行中,“一个草稿文档,可能随时被其他文档更新、替换或废弃”,但实际上接近共识)。它说:“可能没有元素集中;当没有元素被聚焦时,文档接收的关键事件必须针对 body 元素(如果有),否则针对 Document 的根元素(如果有)。如果没有根元素,则不能触发键事件。”

    由于blur() 方法被定义(在DOM 2 HTML 规范中)简单地定义为移除焦点,这意味着使页面处于没有元素被聚焦的状态。但这可能看起来像 body 元素被聚焦:如果你有一个 keypress 属性,它就会被触发。然而,这与聚焦状态不同。例如,在这种情况下,body 元素与 CSS 选择器 :focus 不匹配。

    结论是,您通常应该避免使用blur(),而是在一些合适的可聚焦元素上使用focus(),正如其他答案中所建议的那样。一个例外是您只想丢弃所有键盘事件的情况。那么blur() 就可以了,前提是您的代码没有将任何键盘事件处理程序分配给body 元素。

    【讨论】:

    • 我认为这充分解释了我的困惑来自哪里。我错误地假设“某事”必须始终具有焦点 - 特别是如果 DOM 中的元素有“提示”它们是可聚焦的(tabindex = 0)。我仍然认为这是完全合乎逻辑的,但我开始了解到,DOM 事件模型并没有太多合乎逻辑的东西。我来自一个框架世界,其中唯一的输入是键盘输入(或远程控制),对我来说似乎很奇怪,没有任何焦点。
    【解决方案2】:

    如果您只是想确保一个元素在另一个元素变得模糊时获得焦点:

    /* 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);
    }
    

    小提琴:http://jsfiddle.net/2cWcA/

    你可以扩展它,这样当任何元素被模糊时,它的父级的focus 方法就会被调用。

    【讨论】:

    • 问题是我的例子被过度简化了......实际上,我正在处理一个更大的仅键盘架构 - p2 不知道 p1。因此,即使 p2 上有一个模糊处理程序,它也不知道聚焦 p1。但是,看起来我必须自己处理焦点层次结构。
    【解决方案3】:

    我的理解是blur 只是意味着不专注。换句话说,被聚焦的元素失去了焦点,并且不确定是什么(如果有的话)获得了焦点。 activeElement 变成 body 的事实可能只是一个副作用。而不是将其设置为null,而是将其设置为正文,以表明该文档通常仍然具有焦点。

    【讨论】:

    • 没有查看 webkit 源代码,这似乎和任何猜测一样好,但是,如前所述,我仍然惊讶于没有焦点的概念是可以接受的——尤其是当其他元素是可聚焦的并且附加了事件监听器。
    【解决方案4】:

    实际上 document.ActiveElement() 关注一个元素。 在 javascript 中,焦点就像 document.getElementById('myAnchor').focus() MoreOver 当访问者关注某个元素时触发焦点事件。

    默认情况下,并非所有元素都是可聚焦的。例如,INPUT 和所有类型或表单字段都支持这个事件,A 支持它。作为反例,DIV 不支持焦点。

    支持聚焦的元素类型列表在浏览器之间略有不同。

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 2011-08-25
      • 2017-02-07
      • 2021-08-23
      • 2010-11-10
      相关资源
      最近更新 更多