简体   繁体   中英

change color of a group of divs on click

I want to change the background color of all the divs having the same value for an attribute (#id for example) after a click on one of the divs sharing the same value for this attribute.

I tried this :

$('.group').click(function(){

  var clickedID=$(this).attr("id");
    $('.group').(function(){
        if($(this).attr("id")==clickedID){
          $(this).css({"background-color",'red'});

          });
      ;

  });

You can't have multiple ids with the same name in a page. You have to use classes.

if( $(this).hasClass('classname') ) { ... }

Document languages may contain attributes that are declared to be of type ID. What makes attributes of type ID special is that no two such attributes can have the same value; whatever the document language, an ID attribute can be used to uniquely identify its element. In HTML all ID attributes are named "id"; XML applications may name ID attributes differently, but the same restriction applies.

Reference: w3.org

OK everyone got a bit stuck on the duplicate ID thing which is totally valid but not really the point of the question - you were just a little unfortunate to pick the one attribute you can't repeat.

The basic structure of your code is good:

  1. Attach click event to all .group s
  2. On click get the attribute value of the clicked element.
  3. Find stuff with the same attribute value and change the CSS

Storing the value

So the first question is what attribute can I use to link things together if an id cannot be used twice? HTML5 (although older browsers will generally work too) introduced an offical way of doing this - the data- attribute . From the MDN link:

HTML5 is designed with extensibility in mind for data that should be associated with a particular element but need not have any defined meaning. data-* attributes allow us to store extra information on standard, semantic HTML elements

In other words, you can store metadata specific to your webpage which isn't used for normal "HTML". In this case we can call it something obvious like data-value :

<div data-value="x" class="group">1</div>
<div data-value="y" class="group">2</div>
<div data-value="x" class="group">3</div>

Here 1 and 3 are linked.

Getting the value and associated elements

JQuery provides a helper method to access these value - .data() . We can simply use this like

var clickedValue = $this.data("value");

Then to get the associuted elements you will need to search the document and match .group elements with the same attribute value, using the attribute equals selector as so:

$('.group[data-value="' + clickedValue + '"]')

Setting the CSS

Now we have found what we want, we can use .css() to change the background color. This takes either two strings if you want to set 1 css property, or an object if you want to set multiple. We only want to set background-color , so the first way is enough:

someJQueryObject.css('background-color', 'red');

Putting it together

Now we have our steps we just need to put them together. I have also included a line to store the jQuery object for $(this) to explain how it can be used. We don't really need it this case because we only use it once, but it should demonstrate the idea.

 $('.group').click(function () { // this "caches" the jquery object. If you are using it multiple times, // this is much more efficient as it doesn't have to rebuild things every time. var $this = $(this); // get the "data-value" of the clicked element var clickedValue = $this.data("value"); // now find other groups with the same data-value // and apply the css to it $('.group[data-value="' + clickedValue + '"]').css('background-color', 'red'); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <div data-value="x" class="group">1</div> <div data-value="y" class="group">2</div> <div data-value="x" class="group">3</div> 

Alright so ... here is a feeble attempt at dissecting what you are trying to do.

Function

Your use of .(function is ... man, not even close. First, it looks like you want to validate the clicked item against some specific ID? You need to declare that as a variable outside the function:

var validID = 'foo';

Then you can safely split off the validation into a separate function:

function checkID(id,$el){
    if(id === validID){
        $el.css({
            backgroundColor:'red'
        });
    }
}

jQuery

Then, access the function in your .click() function:

$('.group').on('click',function(){
    var self = this;

    checkID(self.id,$(self));
});

Result

Your overall JS would then look like this:

var validID = 'foo';

function checkID(id,$el){
    if(id === validID){
        $el.css({
            backgroundColor:'red'
        });
    }
}

$('.group').on('click',function(){
    var self = this;

    checkID(self.id,$(self));
});

Some tips:

  • Use === instead of == whenever possible ... == checks values only, whereas === checks both value and type, so "2" == 2 is true, whereas "2" === 2 is false
  • Learn how to leverage the element-level items. There are a lot of places to do this, but doing $(this).attr('id') is approximately 600,000 times slower than using this.id with the same result. You definitely can't do this everywhere, but things like this.id and this.checked are super easy, cross-browser, and a lot faster
  • When I mentioned "cache your instance of $(this) ", I tried to provide a rudimentary example here (although it didn't really apply). General rule is that if you need to reference the same element / object more than once, you cache it, because you'll see a massive improvement in speed and resource consumption. I did an example of caching this in the .on('click') function, but you can do it with anything.
  • Personal recommendation, learn to use .on() instead of the shorthand. .click() works well if you only need to bind one event, but what if you bind .mouseenter() and .mouseleave() ?

You can take this:

$('.someSelector').click(function(){
    // stuff
}).mouseenter(function(){
    // stuff
}).mouseleave(function(){
    // stuff
});

to this:

$('.someSelector').on({
    click:function(){
         // stuff
    },
    mouseenter:function(){
        // stuff
    },
    mouseleave:function(){
        // stuff
    }
});

Way easier to maintain, but also much faster (as you only hit the DOM once instead of three times).

Hope this helped!

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