在ul上切换类以更改字体

toggle class on ul to change font

本文关键字:字体 ul      更新时间:2023-09-26

我对javascript&jQuery和我在点击按钮时切换类时遇到了问题。所需的输出是让用户在单击按钮时添加项目。这很好。然而,当他们想从列表中check一个项目时,当用户单击<li>内部的按钮时,我无法将字体更改为strike-through。

我想我已经接近了,但有点不对劲。感谢您的帮助。

代码:

function checkItem(element) {
    // toggles the class shopping-item__checked when button inside the parent <li> is clicked
    element.parent('li').toggleClass('.shopping-item__checked');
    console.log(element);
}
// Event listeners
$(document).ready(function () {
    console.log("ready!");
    $('#js-shopping-list-form').submit(function (event) {
        event.preventDefault();
        addItem(state, $('#shopping-list-entry').val());
        renderList(state, $('.shopping-list'));
    });
    $('ul.shopping-list > li').click(checkItem($(this).closest('shopping-item')));
});

HTML:

<div class="container">
    <h1>Shopping List</h1>
    <form id="js-shopping-list-form">
        <label for="shopping-list-entry">Add an item</label>
        <input type="text" name="shopping-list-entry" id="shopping-list-entry" placeholder="e.g., broccoli">
        <button type="submit">Add item</button>
    </form>
    <ul class="shopping-list">
        <li>
            <span class="shopping-item">apples</span>
            <div class="shopping-item-controls">
                <button class="shopping-item-toggle">
                    <span class="button-label">check</span>
                </button>
                <button class="shopping-item-delete">
                    <span class="button-label">delete</span>
                </button>
            </div>
        </li>

删除"."从toggle类,

function checkItem(element) {
    // toggles the class shopping-item__checked when button inside the parent <li> is clicked
    element.parent('li').toggleClass('shopping-item__checked');
    console.log(element);
}

你也可以尝试以下作为替代

function checkItem(element) {
    // toggles the class shopping-item__checked when button inside the parent <li> is clicked
    if(element.parent('li').hasClass('shopping-item__checked')){
        element.parent('li').removeClass('shopping-item__checked');
    }else{
        element.parent('li').addClass('shopping-item__checked');
    }
    console.log(element);
}

您以错误的方式绑定事件处理程序。

$('ul.shopping-list > li').click(checkItem($(this).closest('shopping-item')));

您需要以以下方式传递事件信息。

function checkItem(event) {
    //event information is passed. target contains the target element on which the event was fired. in this case the check button
    var element = $(event.target);
    // toggles the class shopping-item__checked when button inside the parent <li> is clicked
    //element.parent('li').toggleClass('.shopping-item__checked');
    element.closest('li').find('span.shopping-item').css('text-decoration','line-through');
    console.log(element);
}
// Event listeners
$(document).ready(function () {
    console.log("ready!");
    $('#js-shopping-list-form').submit(function (event) {
        event.preventDefault();
        addItem(state, $('#shopping-list-entry').val());
        renderList(state, $('.shopping-list'));
    });
    //bind each check button with the check item function
    $('ul.shopping-list > li > div.shopping-item-controls > button.shopping-item-toggle').on('click', {event_data:this}, checkItem);
});

修改你的html以删除按钮内的跨度,因为这是不必要的。

<div class="container">
    <h1>Shopping List</h1>
    <form id="js-shopping-list-form">
        <label for="shopping-list-entry">Add an item</label>
        <input type="text" name="shopping-list-entry" id="shopping-list-entry" placeholder="e.g., broccoli">
        <button type="submit">Add item</button>
    </form>
    <ul class="shopping-list">
        <li>
            <span class="shopping-item">apples</span>
            <div class="shopping-item-controls">
                <button class="shopping-item-toggle">
                    <!--<span class="button-label">check</span>-->
                    <!-- recommend not to use the span, since you will not be able to capture click event of button -->
                    check
                </button>
                <button class="shopping-item-delete">
                    <span class="button-label">delete</span>
                </button>
            </div>
        </li>

.closest()方法找到最接近的匹配祖先,而.find()方法找到最匹配的子代。

https://coderwall.com/p/wxjljq/jquery-find-and-closest-are-your-best-friends

首先,您为jQuery点击事件添加了错误的回调函数。

$('ul.shopping-list > li').click(checkItem($(this).closest('shopping-item')));

实际上,您将undefined作为回调函数传递,因为您正在立即调用checkItem(),而该函数什么也不返回。所以每次你点击li元素,它们什么都不做。

让我们通过添加函数名称来解决这个问题,而不需要任何附带说明。所以我们并没有调用它,我们只是将它作为一个参数传递。

$('ul.shopping-list > li .shopping-item-toggle').click(checkItem);

在这个例子中,我还针对点击的复选按钮。现在,每次单击按钮时,它都会调用checkItem并传递一个事件对象,如下所示:checkItem(event);

查看您的checkItem函数,它期望通过一个元素,让我们更改该部分:

function checkItem(event) {
    // toggles the class shopping-item__checked when button inside the parent <li> is clicked
    $(this).closest('li').toggleClass('shopping-item__checked');
    console.log(this);
}

我在这里改变了一些东西。我将参数名称从元素更改为事件,并将element.parent('li').blah.blah更改为$(this).closest('li').blah.blah

this将表示单击的元素,我将其包装在jquery选择器中,这样我就可以将一些东西链接到它,比如最近的方法和toggleClass方法。

现在我注意到,这将适用于第一个元素,但不适用于稍后添加的元素。这是因为每次调用addItem时都必须向新列表项添加一个单击事件。有一种更简单的方法可以做到这一点,它需要我们首先修改添加点击事件的方式。

$('ul.shopping-list').on('click', 'li .shopping-item-toggle', checkItem);

我们现在使用的这种技术称为事件延迟。现在,我实际上在整个购物清单上添加了点击事件,它将在购物清单内点击的所有li .shopping-item-toggle项目上启动。这意味着现在还不需要添加元素,就可以对其进行点击事件处理。稍后可以添加这些元素,它仍然可以工作。现在,当你添加新项目时,你可以点击它们,它们就会触发点击事件。