【问题标题】:why does the same event recognise different activeElements?为什么同一个事件会识别不同的activeElements?
【发布时间】:2021-10-20 19:23:53
【问题描述】:

如果我点击一个按钮,activeElement 就是这个按钮。
如果我留下一个输入框,activeElement 就是窗口。
如果我通过单击按钮离开输入框,activeElement 是...两者?
为什么onfocusout 事件没有注册与按钮相同的activeElement? 无论如何我可以从 inputbox-leave-event 的函数调用中访问 c​​lick-on-button 事件吗?
即我可以问,“你离开我是为了那个糟糕的按钮吗?”

<button  type="button" onclick = "myFunction()">   button   </button><br>
<input   type="text" onfocusout= "myFunction()">  </input>

<script>
function myFunction() { 
  console.log(document.activeElement);
} 
</script> 

【问题讨论】:

    标签: javascript html simultaneous


    【解决方案1】:

    您可以在 myFunction() 中为按钮添加事件监听器

    function myFunction() { 
      // console.log(document.activeElement);
      var btn = document.getElementById("btn");
      btn.addEventListener("click", function (event) {
            console.log(event);
      });
    } 
    <!DOCTYPE html>
    <html>
        <body>
            <button id="btn" type="button">button</button><br>
            <input type="text" onfocusout="myFunction()" />
        </body>
    </html>

    【讨论】:

    • 每次输入失去焦点时都会添加一个额外的事件处理程序......不是一个好的解决方案
    【解决方案2】:

    Document 接口的activeElement 只读属性返回DOM 中当前具有焦点的元素。

    如果 activeElement 当时有文本选择,通常会返回一个 HTMLInputElement 或 HTMLTextAreaElement 对象。如果是这样,您可以使用对象的selectionStartselectionEnd 属性来获取更多详细信息。

    另外,确实可以在离开输入元素时触发按钮点击,只需要确保处理好onfocusout函数,并使用函数内部的代码触发点击事件,可以参考here.

    function onMouseUp(e) {
      const activeTextarea = document.activeElement;
      const selection = activeTextarea.value.substring(
        activeTextarea.selectionStart, activeTextarea.selectionEnd
      );
      const outputElement = document.getElementById('output-element');
      const outputText = document.getElementById('output-text');
      console.log({ id: activeTextarea.id, selection});
    }
    
    const textarea1 = document.getElementById('textarea1');
    const textarea2 = document.getElementById('textarea2');
    textarea1.addEventListener('mouseup', onMouseUp, false);
    textarea2.addEventListener('mouseup', onMouseUp, false);
    <textarea name="textarea1" id="textarea1" rows="7" cols="40">This is Text Area One.</textarea>
    <textarea name="textarea2" id="textarea2" rows="7" cols="40">This is Text Area Two</textarea>

    【讨论】:

    • 如果你仔细阅读问题,问题是为什么同一个事件识别不同的activeElements?如果你仔细看我的回答,我已经回答了这一点,并衍生和补充了其他用法。这个例子是为了演示如何使用补充语法。
    • 另外,在回答中,我还解释了离开输入时的事件名称以及如何触发按钮点击的语法链接
    • 所以你的评论在我看来真的是莫名其妙。你真的仔细阅读了问题和我的回答吗?
    【解决方案3】:

    活动中的relatedTarget 会告诉你它要去哪里

    当然,首先你必须使用addEventListener 来访问event

    但我认为这表明了你想看到的东西

    它肯定会告诉你

    “你离开我是为了那个糟糕的按钮吗?”

    const button = document.querySelector('button')
    const input = document.querySelector('input')
    
    function buttonHandler(e) {
      console.log('button clicked');
    }
    
    function inputHandler(e) {
      console.log('leaving input for', e.relatedTarget?.tagName || 'window');
    }
    input.addEventListener('focusout', inputHandler);
    button.addEventListener('click', buttonHandler);
    <button type="button">   button   </button><br>
    <input type="text"> </input>

    【讨论】:

    • 谢谢@Bravo!尝试您的解决方案,我看到 e.relatedTarget 成功监控了 activeElement 下一步的去向。完美的!但为什么它不适合相反的情况呢?为什么按钮单击事件的 e.relatedTarget = 输入离开事件?为什么它是空的?
    • 如果我从按钮调用的函数依赖于输入离开事件完成的函数调用结果,会出现问题吗?
    • @AndreiCleland - 我不太了解 - 也许一些示例代码会有所帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    • 2019-02-12
    • 2014-02-13
    • 1970-01-01
    • 2018-11-20
    • 2016-05-09
    相关资源
    最近更新 更多