jQuery中的addClass和removeClass – 不删除类
我正在尝试做一些非常简单的事情。 基本上我有一个可点击的div’热点’,当你点击它填满屏幕并显示一些内容。 我通过简单地改变div的类,删除’spot’并添加’grow’来实现这一点,并且有一些CSS动画来使它成长。 这很好用。
问题是,在这个div中有一个close_button,目前只是文本。 我希望这可以将类切换回来 – 即删除成长和读取的点。 单击时不会执行此操作。 我相信这是在DOM加载时没有这些类的元素,但我是jQuery的新手,不知道如何解决这个问题。
我认为这可能是一种更明智的做法,有人能指出我正确的方向吗? 我会非常感激的。 我尝试使用toggleClass而无济于事。
$( document ).ready(function() { $(".clickable").click(function() { $(this).addClass("grown"); $(this).removeClass("spot"); }); $(".close_button").click(function() { alert (this); $("#spot1").removeClass("grown"); $("#spot1").addClass("spot"); }); });
更新:
我现在正在使用此代码,
$( document ).ready(function() { $(document).on("click", ".close_button", function () { alert ("oi"); $("#spot1").addClass("spot"); $("#spot1").removeClass("grown"); }); $(document).on("click", ".clickable", function () { if ($(this).hasClass("spot")){ $(this).addClass("grown"); $(this).removeClass("spot"); } }); });
奇怪的是,close_button函数仍然不会添加’spot’或删除’grow’虽然它会添加任何其他类,但它会删除其他类…我添加了if子句,因为我认为这两个函数都可能被触发时间,互相取消,但似乎没有任何区别
会发生什么情况是您的关闭按钮放在.clickable
div中,因此将在两个元素中触发click事件。
事件冒泡将使click事件从子节点传播到其父节点。 因此,首先执行.close_button
回调,当达到.clickable
时,它将再次切换类。 由于运行速度非常快,您无法注意到发生的两件事。
/ \ --------------------| |----------------- | .clickable | | | | ----------------| |----------- | | | .close_button | | | | | ------------------------------ | | event bubbling | ----------------------------------------
要防止事件到达.clickable
,您需要将事件参数添加到回调函数,然后在其上调用stopPropagation
方法。
$(".close_button").click(function (e) { $("#spot1").addClass("spot"); $("#spot1").removeClass("grown"); e.stopPropagation(); });
小提琴: http : //jsfiddle.net/u4GCk/1/
有关事件顺序的更多信息, 请访问 : http : //www.quirksmode.org/js/events_order.html (这是我选择那个漂亮的ASCII艺术=]的地方)
该问题是由于事件冒泡引起的。 添加.grown
的代码的第一部分工作正常。
单击链接时,第二部分“删除已增长的类”无法正常工作,因为执行了.close_button
和.clickable
的处理程序。 因此它将已grown
类移除并读取到div
。
您可以通过在.close_button
单击处理程序中使用e.stopPropagation()
来避免此事件,以避免事件冒泡。
演示: http : //jsfiddle.net/vL8DP/
完整代码
$(document).on('click', '.clickable', function () { $(this).addClass('grown').removeClass('spot'); }).on('click', '.close_button', function (e) { e.stopPropagation(); $(this).closest('.clickable').removeClass('grown').addClass('spot'); });
每当我看到addClass
和removeClass
我想为什么不只是使用toggleClass
。 在这种情况下,我们可以删除.clickable
类以避免事件冒泡,并避免在我们点击.clickable
div
内部的所有内容上触发事件。
$(document).on("click", ".close_button", function () { $(this).closest(".grown").toggleClass("spot grown clickable"); }); $(document).on("click", ".clickable", function () { $(this).toggleClass("spot grown clickable"); });
我还建议您的.clickable
divs
的父包装,而不是使用该document
。 我不确定你是如何动态添加它们所以不想为你假设你的布局。
http://jsfiddle.net/bplumb/ECQg5/2/
快乐编码:)
我建议你多次缓存你使用的jQuery对象。 例如:
$(document).on("click", ".clickable", function () { $(this).addClass("grown"); $(this).removeClass("spot"); });
将会:
var doc = $(document); doc.on('click', '.clickable', function(){ var currentClickedObject = $(this); currentClickedObject.addClass('grown'); currentClickedObject.removeClass('spot'); });
它实际上更多的代码,但它是muuuuuuch更快,因为你不必“遍历”整个jQuery库,以获得$(this)对象。
我想你差不多了。 问题是,你在“关闭按钮”监听器中的$(this)
不是可点击的div。 所以你想先搜索它。 尝试用$(this)
替换$(this).closest(".clickable")
。 并且不要忘记Guilherme建议的e.stopPropagation()
。 这应该是这样的:
$( document ).ready(function() { $(document).on("click", ".close_button", function () { alert ("oi"); e.stopPropagation() $(this).closest(".clickable").addClass("spot"); $(this).closest(".clickable").removeClass("grown"); }); $(document).on("click", ".clickable", function () { if ($(this).hasClass("spot")){ $(this).addClass("grown"); $(this).removeClass("spot"); } }); });
试试这个 :
$('.close-button').on('click', function(){ $('.element').removeClass('grown'); $('.element').addClass('spot'); }); $('.element').on('click', function(){ $(this).removeClass('spot'); $(this).addClass('grown'); });
我希望我理解你的问题。
为什么不简化呢?
jQuery的
$('.clickable').on('click', function() {//on parent click $(this).removeClass('spot').addClass('grown');//use remove/add Class here because it needs to perform the same action every time, you don't want a toggle }).children('.close_button').on('click', function(e) {//on close click e.stopPropagation();//stops click from triggering on parent $(this).parent().toggleClass('spot grown');//since this only appears when .grown is present, toggling will work great instead of add/remove Class and save some space });
这样,维护起来就容易多了。
做了一个小提琴: http : //jsfiddle.net/filever10/3SmaV/
使用.on()
你需要事件委托,因为当DOM准备好时,这些类在DOM上不存在。
$(document).on("click", ".clickable", function () { $(this).addClass("grown"); $(this).removeClass("spot"); }); $(document).on("click", ".close_button", function () { $("#spot1").removeClass("grown"); $("#spot1").addClass("spot"); });
我认为问题在于元素的嵌套。 将事件附加到外部元素后,内部元素的单击实际上会为外部元素触发相同的单击事件。 所以,你实际上从未进入过第二个州。 你可以做的是检查点击的元素。 如果是关闭按钮则避免课程改变。 这是我的解决方案:
var element = $(".clickable"); var closeButton = element.find(".close_button"); var onElementClick = function(e) { if(e.target !== closeButton[0]) { element.removeClass("spot").addClass("grown"); element.off("click"); closeButton.on("click", onCloseClick); } } var onCloseClick = function() { element.removeClass("grown").addClass("spot"); closeButton.off("click"); element.on("click", onElementClick); } element.on("click", onElementClick);
另外我正在添加和删除事件处理程序。
JSFiddle – > http://jsfiddle.net/zmw9E/1/