javascript - 两个 jQuery 事件处理程序的内容在功能上应该是等效的,但表现出不同的行为

标签 javascript jquery

我有两个相同的文档片段对象,我使用 jQuery 为每个对象附加了一个单独的事件监听器,as you can see in my fiddle.

两个事件监听器的内容应该在功能上是等同的,但出于某种原因,只有第一个事件监听器的行为符合预期。

这是我创建文档片段的函数:

function createDocFrag(htmlStr) {
    var frag = document.createDocumentFragment();
    var temp = document.createElement('div');
    temp.innerHTML = htmlStr;
    while (temp.firstChild) {
        frag.appendChild(temp.firstChild);
    }
    return frag;
} 

该函数接受一个 HTML 字符串作为其参数——这里是所述文档片段的标记:

<div class='product current'>
    <div class='collapsed'>
        <p class='name'></p>
        <p class='price'><span></span></p>
        <div class='info'><p>i</p></div>
    </div>\
    <div class='expanded'>
        <ul>
            <li class='base'><span> GHz Base</span></li>
            <li class='turbo'><span> GHz Turbo</span></li>
            <li class='cores'><span> Cores</span></li>
            <li class='threads'><span> Threads</span></li>
        </ul>
    </div>
</div>

下面是两个事件监听器:

$(fragment1).find(".info").on("click", function(){
    $(this).parents(".product").toggleClass("expand");
});

$(fragment2).find(".info").on("click", function(){
    $(fragment2).find(".product").toggleClass("expand");
});

很想知道是什么导致了这种行为(或缺乏这种行为),因此非常感谢对这个主题的任何澄清。谢谢!

最佳答案

忘记我的第一次尝试。使用创建 DOM 片段的函数确实让我很吃惊。

它不起作用的原因是片段在附加到 body 元素后未定义。第一个起作用的唯一原因是它使用相对于被单击元素的 DOM 导航。将此添加到第一个点击处理程序中以检查:

alert($(fragment1).html());   // Undefined!!!

备选方案:

我建议以更“jQuery”的方式做事并在页面中使用模板。这样做的好处是更容易在 HTML 中维护 HTML。

JSFiddle: http://jsfiddle.net/7j9bex15/2/

将您的模板放在一个未知类型的虚拟脚本 block 中,以便浏览器忽略它。我使用 text/template:

<script id="fragment" type="text/template">
    <div class='product current'>
        <div class='collapsed'>
            <p class='name'></p>
            <p class='price'><span></span></p>
            <div class='info'><p>i</p></div>
        </div>
        <div class='expanded'>
            <ul>
                <li class='base'><span> GHz Base</span></li>
                <li class='turbo'><span> GHz Turbo</span></li>
                <li class='cores'><span> Cores</span></li>
                <li class='threads'><span> Threads</span></li>
            </ul>
        </div>
    </div>
</script>

通过 block 的id引用html:

var fragment = $('#fragment').html();

并使用委托(delegate)的事件处理程序,附加到一个不变的祖先元素来捕获动态添加内容上的点击事件:

$(document).on('click', '.info', function(){
});

使用closest(不是parents)找到第一个最接近的匹配祖先,然后像以前一样toggleClass:

$(this).closest(".product").toggleClass("expand");

关于javascript - 两个 jQuery 事件处理程序的内容在功能上应该是等效的,但表现出不同的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32230188/

相关文章:

javascript - 在无限循环中运行函数

javascript - 使用 sendGrids @sendgrid/mail npm 库进行点击跟踪

jquery - 复制时隐藏文本区域(JQuery)

javascript - unslider 背景不拉伸(stretch)(包括 fiddle )

javascript - 尝试过滤和组合 JSON 项目

javascript - Bootstrap范围 slider 更改事件

javascript - 从长字符串生成短哈希

javascript - 如何在不同页面保留搜索过滤器的值

javascript - 未捕获的 ReferenceError : require is not defined - Chart. js

javascript - 如何修复轮播,每次转换后图像似乎都会跳跃。即整个框架先变小然后变大