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'); }); 

每当我看到addClassremoveClass我想为什么不只是使用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/