如何将事件侦听器添加到多个按钮,每个按钮都修改数据的不同部分

如何解决如何将事件侦听器添加到多个按钮,每个按钮都修改数据的不同部分

我正在做我的第一个个人项目,我快要完成了,但是我在努力使一些按钮起作用。我的项目是可以保存书签的项目,其中有一个列是收藏夹的书签,还有一个列是其他保存的书签的。这些按钮每个都对应于从数据库中检索到的项目(我在数据库中使用的是Firestore,但对于本帖子,我已经对其进行了修改,以消除对Firestore的需求),因此没有硬编码到html文件中。保存新书签后,它会具有一个名称(例如“ Reddit”),一个URL(“ www.reddit.com”)和一个用于表示其收藏状态的布尔值(如果为收藏,则为true,否则为false)。 。我希望每个书签都有一个关联的按钮,可以单击该按钮将书签移到另一列。我被困在如何向数据库中的每个项目添加事件侦听器,而该事件侦听器仅修改该项目中的数据。代码如下(底部有更多说明。

完整代码可在此处找到(包括完整运行该程序所需的一切):https://github.com/matt-manning/Bookmarker

以下是最小化版本(仍然足以单独使用):

const bookmarkList = document.querySelector('#other-list');
const favoriteList = document.querySelector('#favorite-list');
const form = document.querySelector('#add-bookmark');

function start() {
    const db = [
        {website: 'Reddit',url: 'www.reddit.com',favorite: true},{website: 'Google',url: 'www.google.com',favorite: false},{website: 'Netflix',url: 'www.netflix.com',{website: 'YouTube',url: 'www.youtube.com',favorite: false}
    ];
    const bookmarkData = setupBookmarks(db);
    registerBookmarkEventListeners(db,bookmarkData);
}

const setupBookmarks = (data) => {
    let favoritesHTML,bookmarksHTML = '';
    const bookmarkData = [];
    if (data && data.length) {
        data.forEach(doc => {
            const bookmarkId = Math.floor(Math.random() * 10000000);
            const bookmark = doc;
            if (bookmark.favorite) {
                favoritesHTML += bookmarkHTML(bookmark,bookmarkId);
            } else {
                bookmarksHTML += bookmarkHTML(bookmark,bookmarkId);
            }
            bookmarkData.push({bookmark,bookmarkId});
        })
    }
    favoriteList.innerHTML = favoritesHTML;
    bookmarkList.innerHTML = bookmarksHTML;
    return bookmarkData;
}

const bookmarkHTML = (bookmark,bookmarkId) => {
    let html = '';
    // cut for minimizing; here is a potentially relevant snippet. Full code can be found in the github link above.
    const li =
        `<li>
            <button class='btn-flat waves-light btn-small right listener' id='${bookmarkId}'>
                <i class='material-icons left'>compare_arrows</i>switch</button>
        <li>`;
    html += li;
    return html;
}

我的问题出在registerBookmarkEventListeners函数中。我想要此功能执行的操作是将事件侦听器添加到每个书签上的按钮,然后单击该按钮时,所述书签中的“收藏夹”布尔值将变为相反,这将使书签切换到另一列

这是我做过的几次尝试(更多尝试可以在github链接中找到):

const registerBookmarkEventListeners = (data,bookmarkData) => {
    document.querySelectorAll('.listener').forEach(elem => {
        elem.addEventListener('click',e => {
            e.preventDefault();
            const bookmark = elem;
            if (bookmark.favorite) {
                bookmark.favorite = false;
            } else {
                bookmark.favorite = true;
            }
        })
    })
}

const registerBookmarkEventListeners = (data,bookmarkData) => {
    const {bookmark,bookmarkId} = bookmarkData;
    bookmarkData.forEach(item => {
        const btnElement = document.querySelector(`#${bookmarkId}`);
        btnElement.addEventListener('click',e => {
            e.preventDefault();
            if (bookmark.favorite) {
                bookmark.favorite = false;
            } else {
                bookmark.favorite = true;
            }
        })
    })
}

我了解为什么我的上述尝试不起作用。第一个甚至不使用数据库数据提供的任何参数。第二个使用bookmarkId,但是它不会“连接”(如果是正确的词)(如果它是正确的词)到它应该修改的数据。我正在努力寻找如何使addEventListener起作用的方法

那么,如何通过循环将事件侦听器添加到按钮,每个循环都直接修改数据的不同部分?

感谢您的帮助。

为完整起见,以下是运行程序所需的相关HTML:

<html lang="en">
<head>
    <Meta charset="UTF-8">
    <Meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Bookmarker</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
    <div class='row logged-in show-none'>
        <div class="col s6">
            <h5>Favorites</h5>
            <ul id='favorite-list'></ul>
        </div>
        <div class="col s6">
            <h5>Bookmarks</h5>
            <ul id='other-list'></ul>
        </div>
    </div>
    <script src='script.js'></script>
</body>
</html>

解决方法

如果您将项目保存在bookmarkData.forEach(item => ...中,那么您应该将分解结构放在大括号中,并具有类似的内容

const { bookmarkId,bookmark } = item;
,

我这样做的方式:

  1. 将具有ID的数据传递到registerBookmarkEventListeners函数。
  2. 每个元素上的ForEach。
  3. 找到具有与数据ID匹配的ID的按钮并添加侦听器。
  4. 更改该元素的收藏夹。

如果遇到问题,您可以在下面找到代码。注意,我通过在数字前添加“ x”来更改html代码中按钮的ID,您仍然需要弄清楚如何在更改后呈现项目。

registerBookmarkEventListeners(bookmarkData); // 1

const registerBookmarkEventListeners = (data) => {
    data.forEach(bookmark => { // 2
        document.querySelector(`#x${bookmark.bookmarkId}`).addEventListener('click',(e) => { // 3
                bookmark.bookmark.favorite = !bookmark.bookmark.favorite; // 4
                console.log(bookmark);
        })
    })
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?