如果我的点击侦听器未弹出,如何使用点击侦听器定位动态添加的HTML元素的父对象?

时间:2019-02-24 20:28:45

标签: javascript jquery html dom

我有一个类似的函数,该函数从AJAX中获取数据并将其呈现到DOM。

function populateProfile(arr) {
let items = ``;

for (let i = 0; i < arr.length; i++) {
    const { title, sport, members, membersLimit, description, _id } = arr[i];
    const { lat, long } = arr[i].location;

    items = items.concat(`
        <div id="${_id}" class="post-item">
            <div class="post-item-list">
                <ul>
                    <li><h4>${title}<h4></li>
                    <li>Sport: ${sport}</li>
                    <li>Max players: ${membersLimit}</li>
                    <li>Current players: ${members}</li>
                    <li> Description: <p>${description}</p></li>
                    <li>${lat},${long}</li>
                </ul>
            </div>
        </div>
    `);
}
$('#ownPosts').append(items);
}

为此功能,我为第一个div分配了一个ID,它是所有元素的容器。

我有以下功能,即单击事件侦听器,它应获取被单击的div的ID,并将其传递给viewSinglePost,这是AJAX请求,用于返回单个帖子的数据并将其作为情态的。

function popPost() {
$('#ownPosts').on('click', '.post-item', (event) => {
    const singlePost = event.target.id
    viewSinglePost(singlePost);
});
}

当前,仅当单击具有“ post-item”类的div时,popPost()才会触发。如果单击ul。或li或div.post-item的任何子元素,即使它们在div内也不会触发。

所以,我问我如何获取点击侦听器以注册单击div.post-item的子元素,孙元素等中的任何一个……将其像单击div.post-item一样对待?< / p>

谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

如果我正确理解,您正在使用类后项的父div的ID。

如果这是您的问题,则可以更改此行:

const singlePost = event.target.id

具有:

const singlePost = $(event.target).closest('div.post-item').attr('id')

或者,在普通js中:

const singlePost = event.target.closest('div.post-item').id;

位置:

  

jQuery.closest():,通过测试元素本身并在DOM树中遍历其祖先,获得与选择器匹配的第一个元素

摘要:

populateProfile([{"title": 1, "sport": 1, "members":1, "membersLimit":1, "description":1, "_id":1,
    "location": {"lat": 1, "long": 1}},
    {"title":2, "sport":2, "members":2, "membersLimit":2, "description":2, "_id":2,
    "location": {"lat": 2, "long": 2}}]);
$('#ownPosts').on('click', '.post-item', function(event) {
    const singlePost = $(event.target).closest('div.post-item').attr('id');
    console.log('---> ' + singlePost);
    //viewSinglePost(singlePost);
});


function populateProfile(arr) {
    let items = ``;

    for (let i = 0; i < arr.length; i++) {
        const { title, sport, members, membersLimit, description, _id } = arr[i];
        const { lat, long } = arr[i].location;

        items = items.concat(`
    <div id="${_id}" class="post-item">
                <div class="post-item-list">
                <ul>
                <li><h4>${title}<h4></li>
                <li>Sport: ${sport}</li>
        <li>Max players: ${membersLimit}</li>
        <li>Current players: ${members}</li>
        <li> Description: <p>${description}</p></li>
        <li>${lat},${long}</li>
        </ul>
        </div>
        </div>
`);
    }
    $('#ownPosts').append(items);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div id="ownPosts"></div>

答案 1 :(得分:1)

我认为这不是显示帖子的正确方法。您最终将听到的点击次数超出了您的期望。一些例子:

  • 列表中某处的深处,有一个“复制到剪贴板”按钮
  • 或可点击的锚点

您不想在这里处理这些项目的点击(即过滤掉它们),并且如果它们突然冒出气泡,则不希望它们与您的表演相关功能放慢速度。从性能角度来看,这不是一个好的方向。

每个帖子的h4标题旁边,您可以有一个按钮来显示该帖子的详细信息(我想viewSinglePost()提供了此功能)。然后,您可以在此按钮/那些按钮上放置一个侦听器(所有帖子均使用一个侦听器列出按钮),并确定当最终用户单击时最终用户的意图。