Vlad
Vlad

Reputation: 11

Checking each element and changing it based on parent (JavaScript/jQuery)

I have a case, where I need to dynamically change the background of a list items based on the background of a closest parent element with a .box class. If that parent also has .gray class, replace the current background of the span elements within this list to a dark background, else, to white. I tried this approach (code below), and it returns the right amount of trues and falses, but the if/then part wont work, it just replaces the background colour in all elements, not just within one list.

$(document).ready(function() {
	$('.box-list li span').each(function(){ 
		var is_gray = $(this).closest('.box').hasClass('gray'); 
			console.log (is_gray);
		
		if (is_gray = true) {
			$('.box-list li span').css('background', '#999');
		}
		else {
			$('.box-list li span').css('background', '#fff');
		}
	});
});
.box-list {
    list-style: none;
    padding: 0;
    overflow-x: hidden;
	width: 100%; 
}
.box-list li:before {
    float: left;
    width: 0;
    white-space: nowrap;
    content:"· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · "
}
.box-list li span:nth-child(2) {
    float: right;
}
.box-list li {
	margin: 0 0 10px 0;
}
.box-list li:last-child {
	margin: 0 !important;
}
.box-list li span {
	padding: 0 10px;
}
.box {	
	padding-right: 3rem;
	padding-left: 3rem;
	padding-top: 1.5rem !important; 
	padding-bottom: 3rem !important;
}
.box.gray {
	background: #efefef !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class = "box gray">
  <div>
    <ul class="box-list">
      <li>
        <span>
          List item
        </span>
        <span>
          1
        </span>
      </li>
      <li>
        <span>
          Another list item
        </span>
        <span>
          2
        </span>
      </li>
      <li>
        <span>
          And another one
        </span>
        <span>
          3
        </span>
      </li>
      <li>
        <span>
          And one more
        </span>
        <span>
          4
        </span>
      </li>
      <li>
        <span>
          Secont to last list item
        </span>
        <span>
          5
        </span>
      </li>
      <li>
        <span>
          The last list item
        </span>
        <span>
          6
        </span>
      </li>
    </ul>
  </div>
</div>
 
<div class = "box">
  <div>
    <ul class="box-list">
      <li>
        <span>
          List item
        </span>
        <span>
          1
        </span>
      </li>
      <li>
        <span>
          Another list item
        </span>
        <span>
          2
        </span>
      </li>
      <li>
        <span>
          And another one
        </span>
        <span>
          3
        </span>
      </li>
      <li>
        <span>
          And one more
        </span>
        <span>
          4
        </span>
      </li>
      <li>
        <span>
          Secont to last list item
        </span>
        <span>
          5
        </span>
      </li>
      <li>
        <span>
          The last list item
        </span>
        <span>
          6
        </span>
      </li>
    </ul>
  </div>
</div>

Upvotes: 0

Views: 58

Answers (4)

sminutoli
sminutoli

Reputation: 841

I'm not getting the purpose of jQuery here... Why don't you use pure CSS? Something like

.box .box-list li span {
  background: white;
}
.box.gray .box-list li span {
  background: gray;
}

This will work, unless you want to get the parent's background color dynamically. In this case the answers below aren't correct as well.


If your issue is to set the background in some-specific situation (so you don't want this behaviour always), I'd try to use jQuery only for adding/removing a class, i.e.

//click or whatever you expect
$('#button').click( flagBox );
function flagBox(){
  $('#theBox').addClass('active');
}

And CSS

.box.active .box-list li span {
  background: white;
}
.box.active.gray .box-list li span {
  background: gray;
}

Upvotes: 1

pictus
pictus

Reputation: 77

Your Code seems realy slow to me, you look for each item if it has an class. Working example with your code:

var $box = $('.box-list li span');
  $box.each(function(){
    if( $(this).parents('.box').hasClass('gray') ) {
      $(this).css('background', 'grey');
    }
    else {
      $(this).css('background', 'red');
    }
  });

but it seems easier and faster to check if an element has a children and then add the color all children.

var $box = $('.box')
  $box.each(function(){
    if( $(this).hasClass('gray') ) {
      $(this).find('span').css('background', 'grey')
    }
    else {
     $(this).find('span').css('background', 'red')
    }
  });

Upvotes: 0

indubitablee
indubitablee

Reputation: 8216

target the individual elements instead of all the ones with the class when applying the background color using $(this) instead of $('.box-list li span')

$(document).ready(function() {
	$('.box-list li span').each(function(){ 		
		if ($(this).closest('.box').hasClass('gray')) {
			$(this).css('background', '#999');
		}
		else {
			$(this).css('background', '#fff');
		}
	});
});
.box-list {
    list-style: none;
    padding: 0;
    overflow-x: hidden;
	width: 100%; 
}
.box-list li:before {
    float: left;
    width: 0;
    white-space: nowrap;
    content:"· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · ""· · · · · · · · · · · · · · · · · · · · "
}
.box-list li span:nth-child(2) {
    float: right;
}
.box-list li {
	margin: 0 0 10px 0;
}
.box-list li:last-child {
	margin: 0 !important;
}
.box-list li span {
	padding: 0 10px;
}
.box {	
	padding-right: 3rem;
	padding-left: 3rem;
	padding-top: 1.5rem !important; 
	padding-bottom: 3rem !important;
}
.box.gray {
	background: #efefef !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class = "box gray">
  <div>
    <ul class="box-list">
      <li>
        <span>
          List item
        </span>
        <span>
          1
        </span>
      </li>
      <li>
        <span>
          Another list item
        </span>
        <span>
          2
        </span>
      </li>
      <li>
        <span>
          And another one
        </span>
        <span>
          3
        </span>
      </li>
      <li>
        <span>
          And one more
        </span>
        <span>
          4
        </span>
      </li>
      <li>
        <span>
          Secont to last list item
        </span>
        <span>
          5
        </span>
      </li>
      <li>
        <span>
          The last list item
        </span>
        <span>
          6
        </span>
      </li>
    </ul>
  </div>
</div>
 
<div class = "box">
  <div>
    <ul class="box-list">
      <li>
        <span>
          List item
        </span>
        <span>
          1
        </span>
      </li>
      <li>
        <span>
          Another list item
        </span>
        <span>
          2
        </span>
      </li>
      <li>
        <span>
          And another one
        </span>
        <span>
          3
        </span>
      </li>
      <li>
        <span>
          And one more
        </span>
        <span>
          4
        </span>
      </li>
      <li>
        <span>
          Secont to last list item
        </span>
        <span>
          5
        </span>
      </li>
      <li>
        <span>
          The last list item
        </span>
        <span>
          6
        </span>
      </li>
    </ul>
  </div>
</div>

Upvotes: 0

Siguza
Siguza

Reputation: 23920

if (is_gray = true) {

You're using = instead of ==.
= assigns a new value, making the if pointless.

Upvotes: 0

Related Questions