jQuery source code analysis data operation module class style operation details

Keywords: Javascript JQuery Attribute

There are four parts in jQuery's attribute operation module. The third part is the class style operation part, which is used to modify the class characteristics of DOM elements. For class style operation, jQuery does not define static methods, but only instance methods, as follows:

  • addClass(value); add one or more class styles for each element in the matching element collection. Modify the class style by modifying the DOM attribute className. Value can be a space separated class style or a function (return one or more space separated class styles)
  • hasClass(selector); checks whether any element in the matching element contains the specified class style. As long as one element contains the specified class style, it returns true. Selector is a class style.
  • removeClass(value); removes one or more or all class styles from each element in the set of matching elements. Value can be empty (remove all), space separated (remove multiple styles), or a function that returns one or more space separated class styles.
  • toggleClass(value,stateVal); there are five ways to switch between one or more classes that set or remove the selected element

writer by: Desert QQ:22969969

· toggleClass(); no parameter was passed in; at this time, if the current element contains styles, all classes will be removed; if not, recovery will be attempted.
· toggleClass(stateVal);; only one boolean type is passed in; if stateVal is true, it is equivalent to toggleClass(); if false, all classes are always removed.
· toggleClass(value) ‚ parameter 1 is a string or function, and parameter 2 ‚ is not passed in; when value is a string, it represents one or more styles, separated by spaces, the same below; when value is a function, it returns the string format. If the matching element contains the specified class style, remove it, otherwise add the style.
· toggleClass(value,stateVal); parameter 1 is string or function, parameter 2 is Boolean; when stateVal is true, it is always added; when false, it is always removed.

When toggleClass switches styles, the internal implementation of jQuery will temporarily save all classes in the "className" data of the data cache object, and then try to read them in the next recovery.

Here's a chestnut:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
    <style>
        .color{color: #f00;}
        .back{background: #ccc;}
    </style>
</head>
<body>
    <p>Hello World!</p>
    <button id="b1">Set all styles</button>
    <button id="b2">switch color style</button>
    <button id="b3">Cancel all styles</button>
    <script>
        let b1 = document.getElementById('b1'),
            b2 = document.getElementById('b2'),
            b3 = document.getElementById('b3');
        b1.onclick = ()=>{
            $('p').addClass('color back');           //Add all styles
        }
        b2.onclick = ()=>{
            $('p').toggleClass('color');             //switch color style
        }
        b3.onclick = ()=>{
            $('p').removeClass();                    //Cancel all styles
        }        
    </script>    
</body>
</html>

Here we customize two class:color and back in style. The former modifies the color of font, and the latter modifies the background color of font. Then we define three buttons for operation style, rendering as follows:

Click to set all styles, and two class es, color and back, will be added to the DOM element p, as follows:

When you click to switch the color style, because the color class on the p element already exists, it will be cancelled:

When you click the switch color style button again, because the color class on the p element has been canceled, it will be displayed as follows:

When we click cancel all styles, we will delete all class es on the p element and return to the initial state, as follows:

 

Source code analysis

jQuery internally modifies the className attribute of the corresponding DOM element to perform style operations. In the middle, the indexOf string and replace operations are used to perform search and replacement. The logic for adding and deleting styles is as follows:

jQuery.fn.extend({
    addClass: function( value ) {        //Add class style
        var classNames, i, l, elem,
            setClass, c, cl;

        if ( jQuery.isFunction( value ) ) {        //If value It's a function.
            return this.each(function( j ) {
                jQuery( this ).addClass( value.call(this, j, this.className) );        //The function is executed on each matching element and its return value is taken as the class style to be added, and then called..addClass(className)Add a class style. When executing the function, two parameters are passed in, which are the subscript position of the element in the collection and the current style value.
            });
        }

        if ( value && typeof value === "string" ) {                //If value Is a string, which can be multiple styles separated by spaces
            classNames = value.split( rspace );                        //use/\s+/Yes value Division

            for ( i = 0, l = this.length; i < l; i++ ) {            //Traversal match element
                elem = this[ i ];

                if ( elem.nodeType === 1 ) {                            //For element nodes only
                    if ( !elem.className && classNames.length === 1 ) {        //If elem.className If it does not exist and the number of styles to be added is 1, it is set directly. elem.className
                        elem.className = value;

                    } else {    
                        setClass = " " + elem.className + " ";                //In the class style to be added className Space before and after

                        for ( c = 0, cl = classNames.length; c < cl; c++ ) {    //Calendar class style to add value
                            if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {    //If classNames A style in does not exist setClass in
                                setClass += classNames[ c ] + " ";                            //Then add the style
                            }
                        }
                        elem.className = jQuery.trim( setClass );                //Finally, remove the spaces on both sides of the class style, and then set to elem.className in
                    }
                }
            }
        }

        return this;
    },
    removeClass: function( value ) {            //Removes one or more or all class styles from each element in the matching element collection. By modifying DOM attribute className To remove the class style.
        var classNames, i, l, elem, className, c, cl;

        if ( jQuery.isFunction( value ) ) {            //If value Is a function
            return this.each(function( j ) {            //Traversal match element
                jQuery( this ).removeClass( value.call(this, j, this.className) );    //Call the removeClass()Function, parameter is value Return value of function
            });
        }

        if ( (value && typeof value === "string") || value === undefined ) {    //If value Exists and is a string or value Undefined
            classNames = ( value || "" ).split( rspace );                            //Separated by whitespace value To support the removal of multiple class styles at a time. Here if value It's empty, so the result is[""],The array length Equal to 1

            for ( i = 0, l = this.length; i < l; i++ ) {                            //Traversal match element
                elem = this[ i ];                                                        //elem Is a matching element

                if ( elem.nodeType === 1 && elem.className ) {                            //Only support has been set className Element node of.
                    if ( value ) {                                                            //If the value value,Set style
                        className = (" " + elem.className + " ").replace( rclass, " " );    //classNames It is the class style of the current element. Add a space on both sides, and then remove the line feed, tab and carriage return characters. var rclass = /[\n\t\r]/g,
                        for ( c = 0, cl = classNames.length; c < cl; c++ ) {                //Traverse the array of class styles to remove classNames
                            className = className.replace(" " + classNames[ c ] + " ", " ");    //Call string method replace()Remove one by one from the current class style
                        }
                        elem.className = jQuery.trim( className );                            //Remove the blank character, and set elem.className attribute

                    } else {
                        elem.className = "";
                    }
                }
            }
        }

        return this;
    },
    /*slightly*/
})

When we do all kinds of animation effects in the page, we still use this API, which is very convenient. With css, we can achieve all kinds of animation effects.

Posted by don117 on Tue, 22 Oct 2019 16:44:17 -0700