【问题标题】:JavaScript Blur event not working on items added after the DOM is loadedJavaScript Blur 事件不适用于加载 DOM 后添加的项目
【发布时间】:2016-12-03 09:35:59
【问题描述】:

我正在尝试在一个项目中将尽可能多的 jQuery 转换为原生 JavaScript,部分是为了学习更多的 JS。

下面是我的一些代码,当焦点和模糊使其再次变小时扩展文本区域。

除了在加载 DOM 后插入到 DOM 中的一个 textarea 字段之外,它工作得很好,我怎样才能在不使用 jQuery 的情况下使其也适用于这些项目?

(function() {

    var descriptions = document.querySelectorAll('.edit_description');

    for (var i = 0; i < descriptions.length; i++){
        descriptions[i].addEventListener('blur', handler, false);
        descriptions[i].addEventListener('focus', handler, false);
    }

    //descriptions.addEventListener('blur', handler, false);
    //descriptions.addEventListener('focus', handler, false);

    function handler(event) {
        if (event.type === "blur") {
            // It's a blur event
            this.setAttribute("style","height:18px;");
            this.style.height = "18px";
        }
        else {
            // It must be a focus event
            this.setAttribute("style","height:10em;");
            this.style.height = "10em";
        }
    }
})();

这个 jQuery 版本完美地工作,即使是在 DOM 已经加载之后添加的文本字段也是我需要重现的,但是在不依赖其他库(如 jQuery)的原生 JavaScript 中......

$(document).on("focus", "textarea.edit_description", function() {
    $(this).addClass("expanding")
    $(this).animate({
        height: "10em"
    }, 500);
});
$(document).on("blur", "textarea.edit_description", function() {
     $(this).animate({
         height: "18px"
     }, 500);
     $(this).removeClass("expanding")
});

【问题讨论】:

  • 为我们提供小提琴。
  • 如果您在页面加载/文档准备就绪时运行此代码,那么其他新元素不存在,那么为什么它会有一个处理程序?添加元素时需要添加处理程序。
  • 事件委托应该是您正在寻找的模式。

标签: javascript jquery


【解决方案1】:

将处理程序附加到文档并检查event.@987654321@ 以查看它是否具有适当的类。

function handler(e) {
  // check that the event target has the desired class
  if (e.target.classList.contains("edit-description")) {
    console.log("%s %o", e.type, e.target);
  }
}

// add handlers using the useCapture argument
document.addEventListener("blur", handler, true);
document.addEventListener("focus", handler, true);

// add another input to the DOM
var input = document.createElement("input");
input.id = "b";
input.className = "edit-description";
document.body.insertBefore(input, document.body.children[1]);
&lt;input id="a" class="edit-description"&gt;

请注意,我们为 addEventListener() useCapture 参数指定了 true。这对于事件委托(在这种情况下)是必要的,因为 blurfocus 不是冒泡事件。

另见:Element.@987654323@

【讨论】:

    【解决方案2】:

    为什么要为此使用 javascript?你反对 CSS 解决方案吗?您可以使用:focus 选择器定位焦点元素:

    .edit-description {
      height: 1em;
      display: block;
    }
    .edit-description:focus {
      height: 10em;
    }
    <textarea class="edit-description"></textarea>
    <textarea class="edit-description"></textarea>
    <textarea class="edit-description"></textarea>

    【讨论】:

    • 我不是,它实际上让我忘记了,因为我最近已经习惯了用 JS 完成它。我必须注意的一件事是,这将是安装在 SugarCRM 中的模块的一部分,因此有些人/企业拥有恐龙计算机/浏览器,所以我只需要确保它可以在很久以前运行......我想象一下,谢谢分享!
    • @jasondavis - 由于您希望支持旧版浏览器,请注意 IE8 及以下版本不支持 EventTarget.addEventListener()。您需要 include a detection for EventTarget.attachEvent() 并将其用于 IE8 及以下版本(请注意,它使用的事件名称与 .addEventListener() 不同,并且它已从 IE11 中完全删除)。
    • @jasondavis 我相信支持:focus 回到IE8。
    猜你喜欢
    • 2010-10-04
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    相关资源
    最近更新 更多