如何使用jQuery将类应用于输入项
我正在使用jQuery构建一个购物应用程序。在文本输入中输入文本并按enter键可添加新项。将鼠标悬停在项目上并单击“删除”将删除该项目。点击一个项目会把它划掉 在文本输入中添加新的列表项后,将应用正确的类,但用于删除和删除项的jquery函数不起作用。例如,“删除”范围应在页面加载时隐藏,并在您将鼠标悬停在列表项上时显示,但对于新列表项,删除范围始终显示。为什么我的函数不适用于我通过输入添加的新项 HTML:如何使用jQuery将类应用于输入项,jquery,html,css,Jquery,Html,Css,我正在使用jQuery构建一个购物应用程序。在文本输入中输入文本并按enter键可添加新项。将鼠标悬停在项目上并单击“删除”将删除该项目。点击一个项目会把它划掉 在文本输入中添加新的列表项后,将应用正确的类,但用于删除和删除项的jquery函数不起作用。例如,“删除”范围应在页面加载时隐藏,并在您将鼠标悬停在列表项上时显示,但对于新列表项,删除范围始终显示。为什么我的函数不适用于我通过输入添加的新项 HTML: <div class="wrapper"> <form
<div class="wrapper">
<form onsubmit="return false"> <!--return false prevents enter from refreshing page -->
<input type="text" placeholder="I need to buy..." name="shopping_item">
</form>
<ul class="instructions">
<li>Click on tile to mark complete</li>
<li class="divider">|</li>
<li>Hover and click “Delete” to delete</li>
</ul>
<section>
<h1 class="outline">Shopping List Items</h1>
<ul class="shopping_item_list">
<li class="tile">Flowers<span class="delete">Delete</span></li>
<li class="tile middle">A gift card for mom's birthday<span class="delete">Delete</span></li>
<li class="tile">A birthday card<span class="delete">Delete</span></li>
<!-- Do I need to have divs to clear? It looks like it works without them. -->
<li class="tile">Yogurt<span class="delete">Delete</span></li>
<li class="tile middle">Applesauce<span class="delete">Delete</span></li>
<li class="tile">Iced tea<span class="delete">Delete</span></li>
<li class="tile">Ice cream<span class="delete">Delete</span></li>
<li class="tile middle">Laundry detergent<span class="delete">Delete</span></li>
<li class="tile">Sandwich bags<span class="delete">Delete</span></li>
</ul>
</section>
</div><!--end wrapper-->
.shopping_item_list .delete {
display: block;
position: absolute;
bottom: 0;
left: 0;
right:0;
background-color: #000;
padding-top:10px;
padding-bottom: 10px;
font-family: Verdana, sans-serif;
font-size:18px;
text-align: center;
}
.deleteAction {
background-color:#b7b7b7 !important;
text-decoration:line-through;
color:#e1e1e1;
}
$(document).ready(function() {
//add list item
$("input[name='shopping_item']").change(function() {
var item = $(this).val();
$("<li class='tile'>" + item + "<span class='delete'>Delete</span>" + "</li>").prependTo(".shopping_item_list");
$(".tile").removeClass("middle");
$(".shopping_item_list li:nth-child(3n+2)").addClass("middle");
});
// hide delete button
$(".delete").hide();
// delete square
$(".tile").hover(function() {
$(this).find(".delete").toggle();
});
$(".tile").on("click", ".delete", function() {
$(this).closest("li.tile").remove();
$(".tile").removeClass("middle");
$(".shopping_item_list li:nth-child(3n+2)").addClass("middle");
});
// cross off list
$(".tile").click(function() {
$(this).toggleClass("deleteAction");
});
}); // end of ready function
JQuery:
<div class="wrapper">
<form onsubmit="return false"> <!--return false prevents enter from refreshing page -->
<input type="text" placeholder="I need to buy..." name="shopping_item">
</form>
<ul class="instructions">
<li>Click on tile to mark complete</li>
<li class="divider">|</li>
<li>Hover and click “Delete” to delete</li>
</ul>
<section>
<h1 class="outline">Shopping List Items</h1>
<ul class="shopping_item_list">
<li class="tile">Flowers<span class="delete">Delete</span></li>
<li class="tile middle">A gift card for mom's birthday<span class="delete">Delete</span></li>
<li class="tile">A birthday card<span class="delete">Delete</span></li>
<!-- Do I need to have divs to clear? It looks like it works without them. -->
<li class="tile">Yogurt<span class="delete">Delete</span></li>
<li class="tile middle">Applesauce<span class="delete">Delete</span></li>
<li class="tile">Iced tea<span class="delete">Delete</span></li>
<li class="tile">Ice cream<span class="delete">Delete</span></li>
<li class="tile middle">Laundry detergent<span class="delete">Delete</span></li>
<li class="tile">Sandwich bags<span class="delete">Delete</span></li>
</ul>
</section>
</div><!--end wrapper-->
.shopping_item_list .delete {
display: block;
position: absolute;
bottom: 0;
left: 0;
right:0;
background-color: #000;
padding-top:10px;
padding-bottom: 10px;
font-family: Verdana, sans-serif;
font-size:18px;
text-align: center;
}
.deleteAction {
background-color:#b7b7b7 !important;
text-decoration:line-through;
color:#e1e1e1;
}
$(document).ready(function() {
//add list item
$("input[name='shopping_item']").change(function() {
var item = $(this).val();
$("<li class='tile'>" + item + "<span class='delete'>Delete</span>" + "</li>").prependTo(".shopping_item_list");
$(".tile").removeClass("middle");
$(".shopping_item_list li:nth-child(3n+2)").addClass("middle");
});
// hide delete button
$(".delete").hide();
// delete square
$(".tile").hover(function() {
$(this).find(".delete").toggle();
});
$(".tile").on("click", ".delete", function() {
$(this).closest("li.tile").remove();
$(".tile").removeClass("middle");
$(".shopping_item_list li:nth-child(3n+2)").addClass("middle");
});
// cross off list
$(".tile").click(function() {
$(this).toggleClass("deleteAction");
});
}); // end of ready function
$(文档).ready(函数(){
//添加列表项
$(“输入[name='shopping\u item'])。更改(函数(){
var item=$(this.val();
$(“”+项目+“删除”+“ ”).prependTo(“.shopping\u item\u list”);
$(“.tile”).removeClass(“中间”);
$(“.shopping\u item\u list li:nth child(3n+2)”).addClass(“middle”);
});
//隐藏删除按钮
$(“.delete”).hide();
//删除方块
$(“.tile”).hover(函数(){
$(this.find(“.delete”).toggle();
});
$(“.tile”)。在(“单击”,“删除”,函数()上){
$(this).closest(“li.tile”).remove();
$(“.tile”).removeClass(“中间”);
$(“.shopping\u item\u list li:nth child(3n+2)”).addClass(“middle”);
});
//删除列表
$(“.tile”)。单击(函数(){
$(this.toggleClass(“deleteAction”);
});
}); // 就绪功能结束
当您运行这样的代码时:
$(".tile").hover(function() {
$(this).find(".delete").toggle();
});
$('body').on('click', '.tile', function() {
$(this).toggleClass("deleteAction");
});
它在页面上查找所有具有类平铺的项目,并在这些项目上安装悬停行为
如果随后使用类平铺
向页面添加新元素,则为时已晚。安装悬停行为的代码已运行
解决此问题的简单方法是使用此结构:
$(document).on("mouseenter mouseleave", ".tile", function() {
$(this).find(".delete").toggle();
});
这意味着通常使用类tile
观察文档中的项目。因此,它将适用于现有项目和将来添加的项目
请注意,您可以在层次结构的任何级别执行此操作,因此,如果所有平铺
元素始终位于.shopping\u item\u列表
中,则您可以执行以下操作:
$(".shopping_item_list").on("mouseenter mouseleave", ".tile", function() {
...
})
这更有效。因为,例如,当您运行此附加事件的函数时,您添加的元素的相关.delete
项还不存在。所以当$(.delete”).hide()时
在页面加载时对DOM中的项目(或$(document).ready()
,实际上)非常有效,它不能告诉。删除那些还不存在的项目。将$(document).ready()
想象成教室中的初始指令集。如果你上课迟到,你就会错过说明
你基本上有两个选择
1)利用。当一个事件发生在DOM中的一个项上时,它会将该事件冒泡到DOM中的其他父项上。因此,当您单击一个按钮时,“click”事件会在DOM中弹出,所有包含元素,包括
都知道它发生了。这很方便,因为您添加到DOM中的项目仍然会使其事件冒泡。这意味着您可以将侦听器附加到外部元素(如
),检查哪个元素是事件的源,然后采取一些措施。jQuery是一个经过深思熟虑的库,它包含了一种通过。您可以重写您的\\crossoff列表代码>方法如下:
$(".tile").hover(function() {
$(this).find(".delete").toggle();
});
$('body').on('click', '.tile', function() {
$(this).toggleClass("deleteAction");
});
2)将当前所有的$(document).ready()
封装在一个单独的命名函数中,如函数cartInit()
,并随时调用该函数$(“输入[name='shopping\u item'])。发生更改()。只是,不要那样做。使用事件冒泡。:) 问题在于,您将事件直接附加到每个单独的元素,并且只有在文档准备就绪时才能执行此操作。这意味着以后添加的所有后续元素都不会附加任何处理程序
要解决这个问题,应该使用事件委派,这基本上意味着将处理程序附加到父节点,而不是每个单独的元素。来自子节点的事件将冒泡到父节点,您可以在那里拦截它们。jQuery让您指定一个委托选择器,以便可以指定感兴趣的子级
例如,以下内容将捕获对.shopping\u item\u列表
容器中.tile
元素的每次单击
$('.shopping_item_list').on('click', '.tile', function () {
//do something
});
现在,关于在hover上显示/隐藏元素,我不会使用JS。CSS强大到足以表达这种行为。例如,如果只想在悬停.tile
元素时显示.delete
元素,则可以执行以下操作
.tile .delete {
display: none;
}
.tile:hover .delete {
display: block;
}
非常感谢。这非常有帮助,特别是对于显示和隐藏删除范围。我想选择两者,但不知道是否可以。我可以吗?:)两者都很有帮助。我先看到了第一个答案,所以我用它来修改课堂作业。你的帮助我完成了删除跨度显示。你确实更完整地回答了这个问题,尽管我两者都用了。我会换成你的。谢谢。我根据您的示例更新了代码,现在可以使用了!