简体   繁体   中英

jQuery - element is selected by attribute but the index returns value of the elements without attribute

function check(){
    $('.left').removeClass('left');
    $('.right').removeClass('right');

    $('.item[style*="display: block"]').each(function(index){
        console.log('checking...');
        console.log($(this));
        console.log($(this).index()%2);

        if ($(this).index()%2==0)
            $(this).addClass('left');
        else
            $(this).addClass('right');
    });
}
<div class="item" style="display:block"></div> 
<div class="item" style="display:block"></div> 
<div class="item" style="display:block"></div> 
<div class="item" style="display:none"></div> 
<div class="item" style="display:block"></div>

So here is my code. It is simply supposed to add left and right classes to the odd and even elements that have .item class and have display:block . However the index() acts as if I selected all the elements with class .item without the attribute selection. Can anybody explain me why and how to fix this?

Use filter to filter the required elements. Then use each to iterate over jquery object to match the odd and even

function check() {

    $('.left').removeClass('left');
    $('.right').removeClass('right');
    $('.item').filter(function() {
        return $(this).css('display') == 'block';
    }).each(function(index) {
        console.log(index);
        if (index % 2 == 0)
            $(this).addClass('left');
        else
            $(this).addClass('right');
    });
}

check()

JSFIDDLE

I'd suggest the following instead:

function check() {

  // select all elements with the class-name of 'left'
  // or 'right':
  $('.left, .right')
    // from those elements remove the class-names 'left'
    // and 'right' if either or both is present (if
    // neither class is present this generates no errors):
    .removeClass('left right');

  // select all '.item' elements whose 'style' attribute
  // features the string 'display:block'; and iterate
  // over that collection using the anonymous function of
  // the addClass() method:
  $('.item[style*="display:block"]').addClass(function(i){
      // i: the index of the current element in the
      // collection:

      // i%2 return 0 then we return the 'left' class-name
      // to be added; otherwise we return the 'right'
      // class-name to be added:
      return i%2 === 0 ? 'left' : 'right';
  });
}

 function check() { $('.left, .right').removeClass('left right'); $('.item[style*="display:block"]').addClass(function(i) { return i % 2 === 0 ? 'left' : 'right'; }); } check(); 
 div.left { color: limegreen; } div.right { color: red; } div::before { content: attr(class); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="item" style="display:block"></div> <div class="item" style="display:block"></div> <div class="item" style="display:block"></div> <div class="item" style="display:none"></div> <div class="item" style="display:block"></div> 

In plain JavaScript the above is equally possible with the following:

function check() {

  // Using Array.from to convert the results of the
  // call to document.querySelectorAll() into an
  // Array:
  Array.from(

    // selecting all '.left' and '.right' elements
    // in the document:
    document.querySelectorAll('.left, .right')

  // using Array.prototype.forEach() to iterate over
  // the resulting Array:
  ).forEach(function(el) {
    // 'el': the current element in the Array of elements
    //       over which we're iterating.

    // here we use the Element.classList API to remove both
    // the 'left' and 'right' class-name(s) from all
    // elements (no errors if a class-name isn't present):
    el.classList.remove('left', 'right');
  });
  // As above, to convert an Array-like collection into
  // an Array:
  Array.from(

    // here we select all elements with the class of 'item',
    // which also have the string 'display:block' present
    // in their 'style' attribute-value:
    document.querySelectorAll('.item[style*="display:block"]')

  // iterating over that resulting Array:
  ).forEach(function(el, i) {
    // el: as above, the current element of the Array,
    // i:  the second argument, the index of the
    //     current array-element in the array over
    //     which we're iterating.

    // here we add the class-name 'left', if the remainder
    // of the current index/2 is equal to 0; otherwise
    // we add the 'right' class-name:
    el.classList.add(i % 2 === 0 ? 'left' : 'right');
  });
}

check();

 function check() { Array.from(document.querySelectorAll('.left, .right')).forEach(function(el) { el.classList.remove('left', 'right'); }); Array.from(document.querySelectorAll('.item[style*="display:block"]')).forEach(function(el, i) { el.classList.add(i % 2 === 0 ? 'left' : 'right'); }); } check(); 
 div.left { color: limegreen; } div.right { color: red; } div::before { content: attr(class); } 
 <div class="item" style="display:block"></div> <div class="item" style="display:block"></div> <div class="item" style="display:block"></div> <div class="item" style="display:none"></div> <div class="item" style="display:block"></div> 

References:

Below code will solve your problem.

function check(){
    $('.left').removeClass('left');
    $('.right').removeClass('right');

    $('.item[style*="display:block"]').each(function(index){
       if ((index)%2==0)
            $(this).addClass('left');
        else
            $(this).addClass('right');
    });
}

If you just want to capture the visible elements, then you can also use the below code.

function check() {
    $('.left').removeClass('left');
    $('.right').removeClass('right');

    $('.item:visible').each(function(index){
       if ((index)%2==0)
            $(this).addClass('left');
        else
            $(this).addClass('right');
    });
}

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