简体   繁体   English

切换类后,jQuery将不会选择按钮

[英]Jquery will not select button after class has been toggled

I have some jquery that will, when a button is clicked, switch a class from a button to a different class (ie on click switch class from #testButton from .first to .second with an image toggle to show it works). 我有一些jquery,当单击一个按钮时,它将把一个按钮的类切换到另一个类(即单击从#testButton的单击开关类从.first切换到.second并显示图像,以显示其工作原理)。 The first click works well and it toggles the image, but the second click does not do anything. 第一次单击效果很好,并且可以切换图像,但是第二次单击则不执行任何操作。 It seems as if it is not recognizing the new class. 似乎它无法识别新班级。 Here is a fiddle. 这是一个小提琴。

https://jsfiddle.net/myfb44yu/ https://jsfiddle.net/myfb44yu/

This is the problematic javascript. 这是有问题的javascript。

$(document).ready(function(){
  $('.first').click(function(){
    alert('works');
    $('#testButton').toggleClass('first', 'second');
  });

  $('.second').click(function(){
    alert("works");
    $('#testButton').toggleClass('second', 'first');
  });
});

The interesting thing is that it works when I use an alert() to check but not when I try to change an img src. 有趣的是,当我使用alert()进行检查但不尝试更改img src时,此方法起作用。

Your main issue here is a syntax error in regards to your .toggleClass , but seeing as others have addressed that, I'd like to point out that you should consider re-thinking how you apply your listeners - just as good habit moving forward. 这里的主要问题是关于.toggleClass的语法错误,但是鉴于其他人已经解决了这一问题,我想指出,您应该考虑重新考虑如何应用您的侦听器-就像养成前进的好习惯一样。


An overview of jQuery Event Bindings jQuery事件绑定概述

Think of the elements on your page as items in a store. 将页面上的元素视为商店中的项目。 You're an employee, and your manager says "Go put a red tag on anything in the toys department", and so you do. 您是一名员工,而您的经理说:“去给玩具部门的任何东西贴上红色标签”,然后您这样做。 The next day, he puts 10 new toys in the toy department, and says to you "Why don't all the toys have red tags on them?" 第二天,他在玩具部门放了10个新玩具,对你说:“为什么所有的玩具上都没有红色标签?” He then moves one of the toys to the clothing section and asks you, "Why does this item have a red tag on it?" 然后,他将其中一个玩具移到服装区,并问您:“为什么这个商品上有红色标签?” It's simple. 这很简单。 You put the red tags on anything in the toys department when he told you to do it - things got moved around afterwards. 当他告诉你去做时,你会在玩具部门的任何东西上贴上红色标签-之后事情就变了。

The toys in this example would be your .first and .second elements. 在这个例子中的玩具将是你的.first.second元素。

This is how jQuery event bindings work - they only apply to elements that satisfied the selector at the time the event was initialized. 这就是jQuery事件绑定的工作方式-它们仅适用于在事件初始化时满足选择器要求的元素。

So, if you do $('.myClass').click(); 因此,如果您执行$('.myClass').click(); , then put .myClass on five buttons - none of those buttons will call this function, as they didn't have listeners put on them. 然后.myClass放在五个按钮上-这些按钮都不会调用此函数,因为它们没有侦听器。

Similarly, if you put a listener on an element using class, but then remove the class from that element, it will maintain the bound event . 同样,如果您使用class将侦听器放置在元素上,然后从该元素中删除该类,则它将保留bound事件


The Solution 解决方案

$(document).on("click", ".first", function() { } );

This is known as event delegation . 这称为事件委托

In continuing with my analogy from before, this would be the equivalent of skipping tagging the items altogether, and instead just deciding whether or not they're a toy when the customer brings them to the cash register. 在继续我之前的类比时,这等同于完全跳过对商品进行标记,而是仅在客户将商品带到收银机时才确定商品是否是玩具。

Instead of putting the listener on specific elements, we've put it on the entire page. 我们没有将侦听器放在特定元素上,而是将其放在整个页面上。 By using ".first" as the second parameter (which takes a selector), the function will only be executed if the element has class first . 通过使用".first"作为第二个参数(带有选择器),仅当元素具有first类时,才执行该函数。

Hope this helps. 希望这可以帮助。

EDIT : As I was typing, JHecht left a good answer that points out the same issue I outlined above. 编辑 :当我打字时,JHecht留下了一个很好的答案 ,指出了我上面概述的相同问题。

N number of elements can have the same class name ,so that's the reason if your trying to search it as $('.classname') returns an array ,so that's the reason your code is not working. N个元素可以具有相同的类名,因此这就是您尝试以$('。classname')进行搜索时返回一个数组的原因,因此这就是您的代码无法正常工作的原因。 class selector 类选择器

Id is unique,each element should have a single id . id是唯一的,每个元素应有一个id。 In your code button has two id's and for the same button your trying to toggle first and second,you need not have two separate events for first and second 在您的代码按钮中有两个ID,对于尝试切换第一个和第二个按钮的同一按钮,您不需要为第一个和第二个事件分别设置两个事件

instead you can write as following 相反,你可以这样写

check this snippet 检查此片段

 $(document).ready(function() { var firstElements = $('.first') var first = firstElements[0]; var secondElements = $('.second'); var second = secondElements[0] $("#testButton").click(function() { alert('works'); $(this).toggleClass('first').toggleClass('second'); }); }); 
 .first { color: red; } .second { color: green; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <img src="img/images.jpeg" alt="" id="testImage"> <div id="testDiv"> <button type="button" id='testButton' class='first'>Hi</button> </div> 

Hope it helps 希望能帮助到你

Ho about this solution. 何关于这个解决方案。 Hope it helps! 希望能帮助到你!

 $(document).ready(function(){ $("#testButton").click(function(){ if($(this).prop("class") === "first"){ alert('first'); $(this).removeClass("first").addClass("second"); } else if($(this).prop("class") === "second"){ alert("second"); $(this).removeClass("second").addClass("first"); } }); }); 
 .first{ color: red; } .second{ color: blue; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <img src="img/images.jpeg" alt="" id="testImage"> <div id="testDiv"> <button type="button" id='testButton' class='first'>Hi</button> </div> 

I hope that what I am about to say makes more sense than I feel it does. 我希望我要说的比我感觉的要有意义。

Your issue is that when you assign the click events, there is not currently an element that has a class of .second . 您的问题是,当您分配click事件时,当前不存在具有.second类的.second

Also, your code is wrong. 另外,您的代码是错误的。 toggleClass accepts a few arguments, the first is a string of classes, the second is an optional parameter to check whether or not to toggle the classes on or off. toggleClass接受一些参数,第一个是一类字符串,第二个是一个可选参数,用于检查是否打开或关闭这些类。

A way to accomplish what you want without changing a whole lot of code is event delegation, shown below. 事件委托是一种无需更改大量代码即可完成所需操作的方法,如下所示。

 $(function() { $(document).on('click', '.btn-first,.btn-second', function() { //here we are adding the click event on the document object, and telling it that we only want to delegate this event to an object that matches the classes of .btn-first or .btn-second. //Note: to those saying "why not just do it on the .btn class an avoid having to do this", it is so he can see what delegation looks like. But you are correct, with this markup it would be better to simply add the click event on the .btn class. $(this).toggleClass('btn-first btn-second'); }); }); 
 .btn { padding: 4px 8px; border-radius: 3px; border: 1px solid grey; } .btn-first { background-color: green; border-color: green; } .btn-second { background-color: orange; border-color: orange } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <img src="img/images.jpeg" alt="" id="testImage"> <div id="testDiv"> <button type="button" id='testButton' class='btn btn-first'>Hi</button> </div> 

A combination of javascript, CSS and HTML to toggle the class of #testButton when any element of class "first" or "second" is clicked, including the test button itself. javascript,CSS和HTML的组合,可在单击“第一”或“第二”类的任何元素(包括测试按钮本身)时切换#testButton的类。 The posted code was changed to supply JQuery's .toggleClass method with a space separated list of class names. 更改了发布的代码, .toggleClass JQuery的.toggleClass方法提供以空格分隔的类名称列表。 Click "run snippet" to test the effect. 点击“运行摘要”以测试效果。

 $(document).ready(function(){ $('.first').click(function(){ $('#testButton').toggleClass('first second'); }); $('.second').click(function(){ $('#testButton').toggleClass('first second'); }); }); 
 .first { border: thick outset green;} .second { border: thick inset red;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p class="first">This paragraph has first class</p> <p class="second">This paragraph has second class</p> <button type="button" id="testButton" class="first">this button starts out first class</div> 

The script can then be simplified by combining multiple class names in a single selector, leaving just: 然后,可以通过在单个选择器中组合多个类名称来简化脚本,只剩下:

$(document).ready(function(){
    $('.first, .second').click(function(){
       $('#testButton').toggleClass('first second');
    });
});
  • Make a neutral class that the buttons both share ( .btn ). 创建两个按钮都共享的中立类( .btn )。
  • Then add one of the state classes to each button ( .first or .second ). 然后添加状态类之一到每个按钮( .first.second )。
  • Delegate the click event to the neutral class only ( $('.btn').on('click',... ). 仅将click事件委托给中性类( $('.btn').on('click',... )。
  • Then toggle both state classes on this ( $(this).toggleClass('first second'); ) 然后在this状态上切换两个状态类( $(this).toggleClass('first second');
  • The images change by CSS, each button has 2 images which alternate between display:none/block according to the button's state class. 图像由CSS更改,每个按钮有2张图像,这些图像在display:none/block之间交替display:none/block根据按钮的状态类别, display:none/block
  • There is an example with the images outside of buttons and another example that doesn't toggle classes around. 有一个示例,其中图像位于按钮外部,而另一个示例则不切换类。

SNIPPET SNIPPET

 $('.btn').on('click', function() { $(this).toggleClass('first second'); }); /* OR */ $('.alt').on('click', function() { $('.img').toggle(); }); 
 .first > .one { display: block; } .first > .two { display: none; } .second > .one { display: none; } .second > .two { display: block; } .first + .one { display: block; } .first + .one + .two { display: none; } .second + .one { display: none; } .second + .one + .two { display: block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>Use jQuery with CSS</p> <button class='btn first'> <img src='http://placehold.it/50x50/000/fff?text=1' class='one'> <img src='http://placehold.it/50x50/fff/000?text=2' class='two'> </button> <button class='btn second'> <img src='http://placehold.it/50x50/0e0/960?text=1' class='one'> <img src='http://placehold.it/50x50/fff/000?text=2' class='two'> </button> <br/> <br/> <button class='btn first'>Toggle</button> <img src='http://placehold.it/50x50/fc0/00f?text=1' class='one'> <img src='http://placehold.it/50x50/00f/fc0?text=2' class='two'> <button class='btn second'>Toggle</button> <img src='http://placehold.it/50x50/fc0/00f?text=1' class='one'> <img src='http://placehold.it/50x50/00f/fc0?text=2' class='two'> <p>Or use only jQuery no CSS</p> <img src='http://placehold.it/50x50/0e0/930?text=1' class='img'> <img src='http://placehold.it/50x50/930/0e0?text=2' class='img' style='display:none'> <button class='alt' style='display:block;'>Toggle</button> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM