Changing element styling

In the previous lesson, we mentioned that the className property is an example of a case where markup attribute names differ from property names. But, truth be told, class names are a bit special in other respects as well and are handled as such by jQuery. This section describes a better way to deal with class names than by directly accessing the className property or using the jQuery’s attr() method.

When you want to change the styling of an element, there are two options used more often than others. The first is that you can add or remove a class, causing a restyle of the element based on its new or removed class. The other is that you can operate on the DOM element by applying styles directly.

Let’s start by taking a look at how jQuery makes it simple to perform changes to an element’s style via classes.

Adding and removing class names

The class attribute of HTML elements is crucially important to the creation of interactive interfaces. In HTML, the class attribute is used to supply these names as a space-separated string. You can have as many spaces as you want, but people usually use one. For example, you may have

<div class="some-class my-class    another-class"></div>

Unfortunately, rather than manifesting themselves as an array of names in the DOM element’s corresponding className property, the class names appear as that same space-delimited string. How disappointing, and how cumbersome! This means that whenever you want to add class names to or remove class names from an element that already has class names, you need to parse the string to determine the individual names when reading it and be sure to restore it to a valid space-separated format when writing it.

Taking the cue from jQuery and other similar libraries, HTML5 has introduced a better way to manage this task through an API called classList. The latter has more or less the same methods exposed by jQuery, but unfortunately, unlike their jQuery counterparts, these native methods can work on only one element at a time. If you want to add a class to a set of elements, you have to iterate over them. In addition, being a new introduction, it isn’t supported by older browsers, most notably Internet Explorer 6–9. To better understand this difference, consider this code written in pure JavaScript that selects all elements having class some-class and adds the class hidden:

var elements = document.getElementsByClassName('some-class');
for(var i = 0; i < elements.length; i++) {
    elements[i].classList.add('hidden');
}

The previous snippet is compatible only with modern browsers, including Internet Explorer 10 and above. Now compare it with its jQuery equivalent:

$('.some-class').addClass('hidden');

The jQuery version is not only shorter but is also compatible starting with Internet Explorer 6 (depending on the version of jQuery you’ll use, of course)!

Note

The list of class names is considered unordered; that is, the order of the names within the space-delimited list has no semantic meaning.

Although it’s not a monumental activity to write code that handles the task of adding and removing class names from a set of elements, it’s always a good idea to abstract such details behind an API that hides the mechanical details of such operations. Luckily, you don’t have to develop your own code because jQuery has already done that for you.

Adding class names to all the elements of a set is an easy operation with the following addClass() method that was used in the previous snippet.

Method syntax: addClass
addClass(names)
Adds the specified class name(s) to all the elements in the set. If a function is provided, every element of the set is passed to it, one at a time, and the returned value is used as the class name(s).
Parameters
names(String|Function) Specifies the class name, or a space-delimited string of names, to be added. If a function, the function is invoked for each element, with that element set as the function context (this). The function is passed two values: the element index and the element’s current class value. The function’s returned value is used as the new class name or names to add to the current value.
Returns
The jQuery collection.

Removing class names is just as straightforward with the following removeClass() method.

Method syntax: removeClass
removeClass(names)
Removes the specified class name(s) from each element in the jQuery collection. If a function is provided, every element of the set is passed to it, one at a time, and the returned value is used to remove the class name(s).
Parameters
names(String|Function) Specifies the class name, or a space-delimited string of names, to be removed. If a function, the function is invoked for each element, setting that element as the function context (this). The function is passed two values: the element index and the class value prior to any removal. The function’s returned value is used as the class name or names to be removed.
Returns
The jQuery collection.

To see when the removeClass() method is useful, let’s say that you have the following element in a page:

<p id="text" class="hidden">A brief description</p>

You can remove the hidden class with this simple statement:

$('#text').removeClass('hidden');

Often, you may want to switch a set of styles that belong to a class name back and forth, perhaps to indicate a change between two states or for any other reasons that make sense with your interface. jQuery makes this easy with the toggleClass() method.

Method syntax: toggleClass
toggleClass([names][, switch])
Adds the specified class name(s) on elements that don’t possess it, or removes the name(s) from elements that already possess the class name(s). Note that each element is tested individually, so some elements may have the class name added and others may have it removed. If the switch parameter is provided, the class name(s) is always added to elements without it if switch is true, and removed from those that have it if it’s false. If the method is called without parameters, all the class names of each element in the set will be removed and eventually restored with a new call to this method. If only the switch parameter is provided, all the class names of each element in the set will be kept or removed on that element based on the value of switch. If a function is provided, the returned value is used as the class name or names, and the action taken is based on the switch value.
Parameters
names(String|Function) Specifies the class name, or a space-delimited string of names, to be toggled. If a function, the function is invoked for each element, with that element set as the function context (this). The function is passed two values: the element index and the class value of that element. The function’s returned value is used as the class name or names to toggle.
switch(Boolean) A control expression whose value determines if the class will only be added to the elements (true) or only removed (false).
Returns
The jQuery collection.

As you can see, the toggleClass() method gives you many possibilities. Before moving forward with other methods, let’s see some examples.

One situation where the toggleClass() method is most useful is when you want to switch visual renditions between elements quickly and easily, usually based on some other elements. Imagine that you want to develop a simple share widget where you have a button that, when clicked, shows a box containing the social media buttons to share the link of the page. If the button is clicked again, the box should be hidden.

Using jQuery—and jQuery’s click() method that we’ll cover in lesson 6—you can easily create this widget:

$('.share-widget').click(function() {
    $('.socials', this).toggleClass('hidden');
});

The complete code for this demo is available in the file lesson-5/share.widget.html. Before you’re disappointed, we want to highlight that the demo doesn’t provide any actual sharing functionality, only placeholder text. The resulting page in its two states (box hidden and displayed) is shown in figures 5.1a and figure 5.1b, respectively.

Figure 5.1a. The presence of the hidden class is toggled whenever the user clicks the button, causing the box to be shown or hidden. In its initial state the box is hidden.
Figure 5.1b. When the Share button is clicked, it toggles the hidden class. This figure shows the box when displayed.

Toggling a class based on whether the elements already possess the class or not is a common operation, but so is toggling the class based on some other arbitrary condition. Consider the following code:

if (aValue === 10) {
   $('p').addClass('hidden');
} else {
   $('p').removeClass('hidden');
}

For this common situation, jQuery provides the switch parameter we discussed in the description of the method. You can shorten the previous snippet of code as reported here:

$('p').toggleClass('hidden', aValue === 10);

In this case, the class hidden will be added to all the paragraphs selected if the variable aValue is strictly equal to 10; otherwise it’ll be removed.

As our last example, imagine that you want to add a class on a per-element basis based on a given condition. You might want to add to all the odd-positioned elements in the set a class called hidden while keeping all the classes of the even-positioned elements unchanged. You can achieve this goal by passing a function as the first argument of toggleClass():

$('p').toggleClass(function(index) {
    return (index % 2 === 0) ? 'hidden' : '' ;
});

Sometimes you need to determine whether an element has a particular class to perform some operations accordingly. With jQuery, you can do that by calling the hasClass() method:

$('p:first').hasClass('surprise-me');

This method will return true if any element in the set has the specified class, false otherwise. The syntax of this method is as follows.

Method syntax: hasClass
hasClass(name)
Determines if any element of the set possesses the passed class name
Parameters
names(String) The class name to be searched
Returns
Returns true if any element in the set possesses the passed class name, false otherwise

Recalling the is() method from lesson 3, you could achieve the same goal with

$('p:first').is('.surprise-me');

But arguably, the hasClass() method makes for more readable code, and internally hasClass() is a lot more efficient.

Manipulating the stylistic rendition of elements via CSS class names is a powerful tool, but sometimes you want to get down to the nitty-gritty styles themselves as declared directly on the elements. Let’s see what jQuery offers you for that.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *