theShadraq
theShadraq

Reputation: 29

javascript, change class but only when it meets certain criteria

I have a class that is used ~~120 times on a page. I would like to change the margin-bottom only if other things affecting that class meet a certain criteria. The problem with the below code is that it changes everything associated with that class...not just the ones that meet the criteria.

if (actualCharacters > charactersCanFitInContainer) {
  $("#Full .t16").each(function () {
    $(this).css('margin-bottom', '1.25em');
  });

  $("#Full .t8").each(function () {
    $(this).css('margin-bottom', '4.4175em');
  });
}

Upvotes: 1

Views: 202

Answers (2)

theShadraq
theShadraq

Reputation: 29

In case anyone stumbles across this question and answer, I wanted to post what I ended up doing - special thanks to Qodeninja for setting me straight.

Rather than change CSS via javascript, I went with simple @media queries to handle the various font and spacing changes below. There are a variety of differing methods to do responsive design. This worked best for my requirements

@media all and (max-width: 1500px) 
{
    body
    {
        font-size:1.1em;
    }
    #Full
    {
        width:1200px; 
        background-color:Blue;
    }
    .theTeams
    {
        width:8.925em;
        padding-left:.238em;
        padding-right:.238em; 
    }
    .t8{margin-bottom:4.75em;}
    .t4{margin-bottom:11.75em;}
    .t2{margin-bottom:26.5em;}
    .tend{margin-bottom:0em;}
    .rtR{margin-left:19em;}

@media all and (max-width: 1200px) 
{
    body
    {
        font-size:0.9em;
    }
    #Full
    {
        width:900px; 
        background-color:Orange;
    }
    .theTeams
    {
        width:7.75em;
        padding-left:.14em;
        padding-right:.14em;
        height:2.1em;   
    } 
    .t8{margin-bottom:4.95em;}
    .t4{margin-bottom:12.25em;}
    .t2{margin-bottom:27.75em;}
    .tend{margin-bottom:0em;}
    .rtL{margin-left:16em;}     
}

Upvotes: 0

qodeninja
qodeninja

Reputation: 11266

I want to help you with your problem, but the premise is wrong. You shouldn't be trying to do this in jQuery. Maybe there is something wrong with your CSS, and it would be better to try to resolve it using CSS.

Having said that let's go over some of the problems with your code:


(1) Don't use $( selector ).each()

When you do a call to jQuery

$( selector );

This little guy returns an array of all elements that match the css of the selector.

There may be 200 elements, or even a thousand, but never, ever, do an .each() call unless you tend to explicitly change every individual element in a unique way.

$( selector ).each() runs a for loop on the array of matched selectors, which will give you performance problems if your matched set is too large.

To change all matched elements you need only to do this:

$( selector ).css('margin-bottom', '1.25em');

Read more about .each()


(2) Do not use Javascript (or jQuery), to do CSS's job

From your question it seems like you're having a problem with spacing. CSS has a number of ways to resolve this using rules like overflow, white-space, text-overflow that you should explore before resorting to scripting.


(3) Avoid using .css()

You should avoid using the $( selector ).css() function since it also introduces performance problems, especially on large sets. Instead, you should create a class that you can apply to the set and use:

$( selector ).toggleClass( 'myclass' );
//or 
$( selector ).addClass( 'myclass' ); //and 
$( selector ).removeClass( 'myclass' );

since these functions are more performant.

To take it a step further, do not apply a class to every set of matching elements, rather, add the class to a parent element and let the children inherit their styles from the updated parent class.

Read more about toggleClass()


(5) Stick to conventions

While it's perfectly OK to use capital letters in naming your CSS rules, you should probably avoid that since it's not standard practice. The whole point of having a standard practice is so that everyone can look at your code and know exactly what is going on, which makes your code easier to debug and share.


(6) Don't try to compensate for bad design with over-engineered solutions

Also consider that, sometimes, the requirements need to be changed if your only solution is to script the styles.

I've run into situations where what a project manager wanted to accomplish was not technically feasible. If they want a large body of text to display in a limited area, they need to allow for things like scrollbars or consider keeping a standard size limitation on blocks of text.

Go back to the stakeholder for this project and tell them that what they want to do is not reasonable, and make decisions together to design this widget better.

As a developer, you should not allow for unreasonable requirements, some things simply need to be redesigned instead of making you come up with a messy way to resolve bad design.


Conclusion

In terms of your problem, play around with the CSS rules that specifically address the spacing problem you're having (overflow, text-overflow, etc). You may need to look deeper into the styles to find a better way to do this.

Upvotes: 3

Related Questions