不能使用off()关闭动态列表事件处理程序的事件处理程序(jquery)

Can't use off() to turn off event handlers with an event handler for a dynamic list (jquery)?

本文关键字:事件处理 程序 列表 jquery 动态 off 不能      更新时间:2023-09-26

我是js/jQuery新手。我有一个列表,可以修改和添加到定义的页面内:<ol id="elementlist"></ol>

在页面加载时,它是一个空列表。使用JQuery将列表项添加到列表中。

我希望能够悬停在每个元素上并改变颜色。我使用jQuery提供的on()函数完成了这个任务:

// highlight on mouseover 
$("#elementlist").on("mouseover", "li", function(){
        $(this).css("background-color","#f2fdf2");
    });
// restore white background    
$("#elementlist").on("mouseout", "li", function(){ 
        $(this).css("background-color","#ffffff");
    });

我还希望能够双击一个li,突出显示它,并使其突出显示。当鼠标悬停在该元素上时,也应该禁止改变颜色。我可以双击并更改颜色,但我不能使用以下代码禁用悬停处理程序:

// highlights on double click, but doesn't disable mouseover/mouseout
$("#elementlist").on("dblclick", "li", function(){
        $(this).css("background-color","#f2d2d2");
        $(this).off("mouseover", "");
        $(this).off("mouseout", "");
    });

我无法禁用已单击的特定列表项(其他列表项应该仍然能够突出显示)。

使用data()或一个类来设置高亮显示状态,并检查是否正确:

$("#elementlist").on({
    mouseenter: function(){
        if (!$(this).hasClass('highlight')) $(this).css("background-color","#f2fdf2");
    },
    mouseleave: function() {
        if (!$(this).hasClass('highlight')) $(this).css("background-color","#fff");
    },
    dblclick: function() {
        $(this).css("background-color","#f2d2d2").addClass('highlight');
    }
}, 'li');

你也可以用CSS:

#elementlist li {background-color : #f2fdf2}
#elementlist li:hover {background-color : #fff}
#elementlist li.highlight, #elementlist li.highlight:hover {background-color : f2d2d2}

并保留click处理程序

$("#elementlist").on('dblclick', 'li', function() {
    $(this).addClass('highlight');
});

小提琴

事件绑定到父ol,使用off()li s没有效果,因为它们没有事件绑定。

一个解决方案是将事件绑定到没有disabledhover类的li。然后在双击时添加这样的类。

// highlight on mouseover 
$("#elementlist").on("mouseover", "li:not(.disabledhover)", function(){
     $(this).css("background-color","#f2fdf2");
});
// restore white background    
$("#elementlist").on("mouseout", "li:not(.disabledhover)", function(){ 
     $(this).css("background-color","#ffffff");
});
// highlights on double click, but doesn't disable mouseover/mouseout
$("#elementlist").on("dblclick", "li", function(){
     $(this).css("background-color","#f2d2d2");
     $(this).addClass("disabledhover");
});

演示

这是因为处理程序没有直接绑定到单个li元素,但是当然您不能在父元素上使用.off(),否则它将不适用于任何li元素。你可以这样做:

$("#elementlist").on("mouseover", "li", function(){
    if (!$(this).hasClass("fixedBackground"))
        $(this).css("background-color","#f2fdf2");
});
// restore white background    
$("#elementlist").on("mouseout", "li", function(){
    if (!$(this).hasClass("fixedBackground"))
        $(this).css("background-color","#ffffff");
});
$("#elementlist").on("dblclick", "li", function(){
    $(this).css("background-color","#f2d2d2")
           .addClass("fixedBackground");
});

演示:http://jsfiddle.net/t8c23/

也就是说,在双击时向元素添加一个类,表明它的背景不应该再次更改,并在mouseover/out处理程序中测试该类。

理想情况下,您可以在样式表中定义新类,以便通过类设置背景颜色,而不是直接在JS中硬编码颜色值。

您的监听器位于'#elementList'元素上,这就是off()不起作用的原因

http://jsfiddle.net/blackjim/HShzg/1/

$("li", "#elementlist")
.on("mouseover", function(){
    // highlight on mouseover 
    $(this).css("background-color","#f2fdf2");
})
.on("mouseout", function(){ 
    // restore white background   
    $(this).css("background-color","#ffffff");
})
.on("dblclick", function(){
    // highlights on double click, but doesn't disable mouseover/mouseout
    $(this).css("background-color","#f2d2d2");
    $(this).off();
});

PS:如果你的列表有很多元素,那么这么多监听器可能不是一个好主意,你应该考虑一个"标记"的方式来打开/关闭绑定,就像@nnnnnn所说的。