简体   繁体   中英

.addClass() not working inside for() jQuery

UPDATE - FINAL SOLUTION

Thank you to EVERYONE who has helped me with this problem. Special thanks must go to @Pranav for all of their help through email . All of your answers seemed to have worked in JSFiddle yet I could not replicate it on my local server.

My problem was that my js file was firing before PHP had finished adding elements and classes dynamically. I was able to fix this (without using an event handler) with calling:

( function() {
    jQuery(window).load( function($) {

// Add stuff

});
})(jQuery);

This seems to wait until PHP has done its thang and then fire. I can see the changes happen in the DevTools panel.

I also didn't realise that Wordpress really doesn't seem to like $ and would rather have jQuery, so had to create $ = jQuery variable to counter this.

Once again, thank you all. I have only just started learning jQuery and Javascript and this has been a great lesson to learn.


ORIGINAL QUESTION

I am trying to add classes to a select boxes options depending on the classes they have been given by WooCommerce. (The reason for this is that I gave up trying to point to the 'disabled' property I couldn't get working.)

For some reason, the code I am using isn't adding any classes.

 jQuery(document).ready( function($) { // Classes for the link and the visible dropdown $selectclass='turnintodropdown'; // class to identify selects $listclass='turnintoselect'; // class to identify ULs $boxclass='dropcontainer'; // parent element $triggeron='activetrigger'; // class for the active trigger link $triggeroff='trigger'; // class for the inactive trigger link $dropdownclosed='dropdownhidden'; // closed dropdown $dropdownopen='dropdownvisible'; // open dropdown $i=0; $count=0; $sels=$('select'); $opts=$('option'); $trigger=('<a href="#"></a>'); function $switchTriggerClass (){ $($trigger).toggleClass($triggeron).toggleClass($triggeroff); } for($i; $i<$opts.length; $i++){ if($($opts).hasClass('enabled')){ $(this).addClass('woo'); } else { $(this).addClass('foo'); } } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <tbody> <tr> <td class="label"> <label for="size">Size</label> </td> <td class="value"> <select id="size" class="turnintodropdown" name="attribute_size" data-attribute_name="attribute_size" data-show_option_none="yes"> <option value="">- -</option> <option value="10" class="attached enabled">10</option> <option value="20" class="attached enabled">20</option> <option value="30" class="attached enabled">30</option> <option value="40" class="attached enabled">40</option> <option value="50" class="attached" disabled="">50</option> <option value="60" class="attached" disabled="">60</option> </select> <a class="reset_variations" href="#" style="visibility: hidden;"></a> </td> </tr> </tbody> 

Any help would be greatly appreciated.

Regards Michael

EDIT Hi all,

I have tried all of these methods and the result is 'foo' being outputted to all option elements. I have also tried these methods on my navigation menu and the li elements are responding how I would expect this code to run.

My only conclusion has to be that Javascript/jQuery is not seeing the class 'enabled' even though it is definitely attached.

Could it be that the script is running before PHP has completed it processing? This is a dynamically loaded select box.

Cheers

Inside for loop this not refers to the element it may be window object or something else. Yo can resolve the problem using eq() method.

for(; $i < $opts.length; $i++){
    // cache the element reference
    var $item = $opts.eq($i);
    // or $($opts[$i])

    if($item .hasClass('enabled')){
        $item .addClass('woo');
    }
    else {
        $item .addClass('foo');
    }
}

 var $opts = $('option'); for (var $i = 0; $i < $opts.length; $i++) { // cache the element reference var $item = $opts.eq($i); // or $($opts[$i]) if ($item.hasClass('enabled')) { $item.addClass('woo'); } else { $item.addClass('foo'); } } 
 .foo { color: red } .woo { color: green; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="size" class="turnintodropdown" name="attribute_size" data-attribute_name="attribute_size" data-show_option_none="yes"> <option value="">- -</option> <option value="10" class="attached enabled">10</option> <option value="20" class="attached enabled">20</option> <option value="30" class="attached enabled">30</option> <option value="40" class="attached enabled">40</option> <option value="50" class="attached" disabled="">50</option> <option value="60" class="attached" disabled="">60</option> </select> 

Or using each() method instead of for loop

$opts.each(function(){
    // cache the element reference
    $item = $(this);

    if($item .hasClass('enabled')){
        $item .addClass('woo');
    }
    else {
        $item .addClass('foo');
    }
});

 var $opts = $('option'); $opts.each(function() { // cache the element reference $item = $(this); if ($item.hasClass('enabled')) { $item.addClass('woo'); } else { $item.addClass('foo'); } }); 
 .foo { color: red } .woo { color: green; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="size" class="turnintodropdown" name="attribute_size" data-attribute_name="attribute_size" data-show_option_none="yes"> <option value="">- -</option> <option value="10" class="attached enabled">10</option> <option value="20" class="attached enabled">20</option> <option value="30" class="attached enabled">30</option> <option value="40" class="attached enabled">40</option> <option value="50" class="attached" disabled="">50</option> <option value="60" class="attached" disabled="">60</option> </select> 


Even you can do it in 2 lines using filter() and not() methods.

// filter all elements with the class and add the class
$opts.filter('.enabled').addClass('woo');      

// filter all elements which doesn't have the class and add the class
$opts.not('.enabled').addClass('foo');

 var $opts = $('option'); // filter all elements with the class and add the class $opts.filter('.enabled').addClass('woo'); // filter all elements which doesn't have the class and add the class $opts.not('.enabled').addClass('foo'); 
 .foo { color: red } .woo { color: green; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="size" class="turnintodropdown" name="attribute_size" data-attribute_name="attribute_size" data-show_option_none="yes"> <option value="">- -</option> <option value="10" class="attached enabled">10</option> <option value="20" class="attached enabled">20</option> <option value="30" class="attached enabled">30</option> <option value="40" class="attached enabled">40</option> <option value="50" class="attached" disabled="">50</option> <option value="60" class="attached" disabled="">60</option> </select> 

The same with a single line using end() method.

$opts
   .filter('.enabled').addClass('woo')
   // back to the previous element object
   .end()
   .not('.enabled').addClass('foo');

 var $opts = $('option'); // filter all elements with the class and add the class $opts.filter('.enabled').addClass('woo') .end() .not('.enabled').addClass('foo'); 
 .foo { color: red } .woo { color: green; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="size" class="turnintodropdown" name="attribute_size" data-attribute_name="attribute_size" data-show_option_none="yes"> <option value="">- -</option> <option value="10" class="attached enabled">10</option> <option value="20" class="attached enabled">20</option> <option value="30" class="attached enabled">30</option> <option value="40" class="attached enabled">40</option> <option value="50" class="attached" disabled="">50</option> <option value="60" class="attached" disabled="">60</option> </select> 

You have to change your code block from

for($i; $i<$opts.length; $i++){
        if($($opts).hasClass('enabled')){
            $(this).addClass('woo');
        }
        else {
            $(this).addClass('foo');
        }
    }

To

$opts.each(function(){
    if($(this).hasClass('enabled'))
    {
        $(this).addClass('woo');
    }
    else
    {
        $(this).addClass('foo');
    }
})

Another way of doing is :

$('option.enabled').addClass('woo');      
$opts.not('.enabled').addClass('foo');

If you need an alternative then you can use foreach

$opts.each(function(){
        if(($(this)).hasClass('enabled')){
            $(this).addClass('woo');
        }
        else {
            $(this).addClass('foo');
        }
    })

Try this approach instead.

$sels.find('option').each(function() {
 if($(this).hasClass('enabled')) {
  $(this).addClass('woo');
 } else {
  $(this).addClass('foo');
 }
});

In side for loop this doesn't give you the current element in loop. you need to use $($opt[$i]).hasClass() inorder to access your options in select box.

 jQuery(document).ready( function($) { // Classes for the link and the visible dropdown $selectclass='turnintodropdown'; // class to identify selects $listclass='turnintoselect'; // class to identify ULs $boxclass='dropcontainer'; // parent element $triggeron='activetrigger'; // class for the active trigger link $triggeroff='trigger'; // class for the inactive trigger link $dropdownclosed='dropdownhidden'; // closed dropdown $dropdownopen='dropdownvisible'; // open dropdown $i=0; $count=0; $sels=$('select'); $opts=$('option'); $trigger=('<a href="#"></a>'); function $switchTriggerClass (){ $($trigger).toggleClass($triggeron).toggleClass($triggeroff); } for($i; $i < $opts.length; $i++){ if($($opts[$i]).hasClass('enabled')){ $($opts[$i]).addClass('woo'); } else { $($opts[$i]).addClass('foo'); } } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <tbody> <tr> <td class="label"> <label for="size">Size</label> </td> <td class="value"> <select id="size" class="turnintodropdown" name="attribute_size" data-attribute_name="attribute_size" data-show_option_none="yes"> <option value="">- -</option> <option value="10" class="attached enabled">10</option> <option value="20" class="attached enabled">20</option> <option value="30" class="attached enabled">30</option> <option value="40" class="attached enabled">40</option> <option value="50" class="attached" disabled="">50</option> <option value="60" class="attached" disabled="">60</option> </select> <a class="reset_variations" href="#" style="visibility: hidden;"></a> </td> </tr> </tbody> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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