JQuery-1.9.1 source code analysis series (9) CSS operations, jquery-1.9.1css

Source: Internet
Author: User
Tags number strings

JQuery-1.9.1 source code analysis series (9) CSS operations, jquery-1.9.1css

Jquery.fn.css gets the attribute value of the first element matched by jQuery [$ (...). Css (cssName). Note that this cssName can beArrayOr set the style value for each element that the current jQuery matches [$ (...). Css (cssname, value)/$ (...). Css (obj )];

You can see that jquery. access is directly called to process the function. Access splits the elements matching the jQuery object composed of multiple elements into a single element and calls the callback function (elem, name, value) in the second parameter one by one. If the parameter name isObjectIn this case, the access internal decomposition nameRecursive callProcess each key/value key-value pair of name one by one

Source code

JQuery.fn.css: function (name, value) {// access splits the current jQuery object into a single element and calls the callback function (elem, name, value) in the second parameter one by one ), // If the parameter name is an object, access internally splits the name into recursive calls and processes each key/value key-value pair of name one by one. return jQuery. access (this, function (elem, name, value) {var len, styles, map ={}, I = 0; // If the css feature name is an array, for example, ['left', 'marginright'] if (jQuery. isArray (name) {styles = getStyles (elem); len = name. length; // get the corresponding Css feature value for (; I <len; I ++) {map [name [I] = jQuery.css (elem, name [I], false, styles );} return map;} // If valuehas a value, you can use the $.styleto set a single cssvalue. If valuehas no value, you can use the $.css () method to obtain the return value of the corresponding css feature value! = Undefined? JQuery. style (elem, name, value): jQuery.css (elem, name) ;}, name, value, arguments. length> 1 );}View Code

This api is relatively simple, but you will find a lot of knowledge by carefully analyzing the called functions. I will explore them one by one.

First, we can see the getStyles (elem) function and take a look at its definition.

If (window. getComputedStyle) {getStyles = function (elem) {return window. getComputedStyle (elem, null );};... // ie8-compatible} else if (document.doc umentElement. currentStyle) {getStyles = function (elem) {return elem. currentStyle ;};...}

Two different methods are window. getComputedStyle and elem. currentStyle. Next we will analyze them one by one.

 

A. window. getComputedStyle

Complete Expression window. getComputedStyle (elem, pseudo)

Elem: DOM node, required

Pseudo: pseudo class. It can only be a pseudo class of pseudo elements, such as: after,: before,: first-letter,: first-line. Optional [before Gecko 2.0 (Firefox 4/Thunderbird 3.3/SeaMonkey 2.1), the second parameter "pseudo class" is required]

Note: This function is used to obtain the final CSS attribute values after CSS calculation.Excluding the attribute values of left/right/top/bottomFor example, left: 10%, the left or "10%" obtained through getComputedStyle (the percentage returned by margin-right of Safari 5.1.7 needs special processing ). Read-only. Good support in modern browsers, not IE8-

  

Example ):

<Style>
# MyList {
Height: 100px;
}
# MyList: after {
Content: 'a ';
Height: 100px;
}
</Style>

<Ul id = "myList" style = 'width: 50%; left: 666px; '> <li> test </li> </ul>
<Ul id = "myList2" style = 'width: 50%; left: 111px; '> <li> test2 </li> </ul>

The value of getComputedStyle is the calculated value (for example, the percentage is converted to pixels). The example is as follows:

  

The width of 50% is converted to pixels.

 

The second parameter in getComputedStyle takes effect only when it is a pseudo-element pseudo class. The example is as follows:

  

As you can see, as long as the following pseudo elements do not match or do not pass the pseudo element pseudo class parameter, the getComputedStyle value of the element corresponding to the first parameter is obtained. The. left and. content attributes can be testified.

 

GetComputedStyle is a read-only array object. Each element of the array is a CSS style name, in addition, this read-only array object has a one-to-one attribute corresponding to each element in the array to save the CSS style value. Let's take a look at the structure (window. getComputedStyle (document. getElementById ('mylist'), null ))

  

   

However, because IE8 is not supported, we need a method that IE8 supports. This is the elem. currentStyle of IE.

 

B. elem. currentStyle

Elem. currentStyle is also a read-only object.

  The difference between elem. currentStyle and getComputedStyle

1. elem. currentStyle is a pure object in IE8-without the structure of the class array. You cannot use style [n] to obtain the CSS style name. In IE9 +, elem. currentStyle is a class array object.

2. Although the style obtained by elem. currentStyle is the final CSS style, it is not a computed style. For example, it is also the previous example.

The width of getComputedStyle is 632px.

  

The result of elem. currentStyle is the set percentage value of 50%.

  

3. Differences in style names. For example, for the float attribute, currentStyle in IE8-Is styleFloat.

  

In firefox, getComputedStyle is cssFloat and float [not recommended, reserved by the browser, but also non-standard, not supported by the browser ].

  

In chrome, getComputedStyle is displayed as float. In fact, it is recommended to use float [not to use it, it is retained by the browser, and it is also not a standard method. It is not supported by the browser] And cssFloat can be obtained.

  

  

IE9 has both cssFloat and styleFloat.

So how does jQuery obtain the float attribute?"Float": jQuery.support.css Float? "CssFloat": "styleFloat"

  

C. elem. style

  Comparison between elem. style, window. getComputedStyle (elem, pseudo), and elem. currentStyle

Elem. style is used to obtain the inline style of elem. This is different from window. getComputedStyle (elem, pseudo) and elem. currentStyle.

  

The style result is readable and writable, while the getComputedStyle and currentStyle results are read-only.

The style result is not calculated, which is similar to currentStyle. getComputedStyle is the computed result. For example, the value of style. width is 50%, not the pixel value.

  

  

D. modern browsers get the value of a style in the style sheet -- getPropertyValue

GetPropertyValue (className) isModern Browser(IE9 +, firefox, chrome...) an attribute method of the style sheet. As long as it is a modern browser, you can use this method to obtain style values in the style table style obtained by getComputedStyle/currentStyle/style. For example, style. getPropertyValue ("float ").

Note that the className isDirect property name(For example, "background-color "). "Float" instead of "css-float" or "cssFloat ".

  

If you want to obtain the float value by using properties, You need to convert it to "cssFloat" or "styleFloat", such

  

This is a tough task.

  

Because IE8 does not support this method, IE8 directly uses the attribute acquisition method.

  

  

The currentStyle of IE8-also supports another method for obtaining attributes: style.GetAttribute(ClassName ).

Note that className can beDirect property nameOrHump(For example, "background-color" or "backgroundColor ).

  

 

Therefore, there are two ways to process styles for compatibility.

1. It can be used in combination with getPropertyValue (className) and getAttribute (className) because both of them can beDirect property name

2. Use the attribute obtaining method style [className], but note that the attribute names must be compatible. For example, replace "float" with "cssFloat" or "styleFloat ".

  The second method is jQuery's processing.

Here, although jQuery uses the second method, an attribute cannot be obtained using the attribute method, which is a wonderful "filter" attribute. This property must use getPropertyValue to obtain the correct

Summarize the usage of CSS attributes in a table.

Features GetComputedStyle CurrentStyle Style
Browser support IE9 +, chrome, firefox... IE ALL
Readable and writable Read-Only Read-Only Readable and writable
Whether it is the calculated final value (for example, percentage and percentage are calculated as real pixel values) Yes No No
(External style sheet + internal style sheet + inline style) Final Result Yes Yes No (just inline style)
How to obtain attributes: style. name and style [name] Supported (except for the "filter" attribute) Supported Supported
Supported methods to obtain CSS attribute values GetPropertyValue IE8-only getAttribute is supported; IE9 + supports getPropertyValue and getAttribute ("filter ") IE8-only getAttribute is supported. IE9 + supports getPropertyValue and getAttribute ("filter"). other browsers only support getPropertyValue.
Highlights Standard, supports pseudo elements (such as: after), and obtains the calculated result.   Readable and writable
       

 

This chapter already contains a large number of words. I previously thought this chapter would be relatively simple and I didn't want to expand it so much! Cool, let's take a look...

 Next, analyze the source code:

Now that you have learned a variety of methods to obtain a CSS style table, let's take a look at the calculation-worthy function curCSS = function (elem, name, _ computed) for getting the specified CSS style name ). The difficulty is that when the obtained values through currentStyle and getComputedStyle may be percentages or relative values, we need to simulate and calculate the actual values. Process Comparison ticket, see source code comments

// Note: In window. getComputedStyle contains "window" // because node. js DOM in js will be terminated if (window. getComputedStyle) {getStyles = function (elem) {return window. getComputedStyle (elem, null) ;}; curCSS = function (elem, name, _ computed) {var width, minWidth, maxWidth, computed = _ computed | getStyles (elem ), // getPropertyValue is only available in IE9. ret = computed is used in css ('filter? Computed. getPropertyValue (name) | computed [name]: undefined, style = elem. style; if (computed) {if (ret = ""&&! JQuery. contains (elem. ownerDocument, elem) {ret = jQuery. style (elem, name);} // Chrome <17 and Safari 5.0 calculates the margin-right // Safari 5.1.7 (latest) by replacing the "calculated result" with "used value) returns the percentage but we need the pixel value, which goes against the CSSOM draft // http://dev.w3.org/csswg/cssom/#resolved-values
// Simulate if (rnumnonpx. test (ret) & rmargin. test (name) {// Save the original value width = style. width; minWidth = style. minWidth; maxWidth = style. maxWidth; // Add a new value to obtain the calculated value. For example, when marginRight is set to 10%, the value of width is set to 10%, and then computed. width to get the px width style corresponding to 10%. minWidth = style. maxWidth = style. width = ret; ret = computed. width; // restore the changed value style. width = width; style. minWidth = minWidth; style. maxWidth = maxWidth ;}} return ret; }; // Earlier version ie compatible} else if (document.doc umentElement. currentStyle) {getStyles = function (elem) {return elem. currentStyle ;}; curCSS = function (elem, name, _ computed) {var left, rs, rsLeft, computed = _ computed | getStyles (elem), ret = computed? Computed [name]: undefined, style = elem. style; // avoid setting empty characters for ret here. // so we do not set it to "auto" if (ret = null & style [name]) by default. {ret = style [name];} // we want to convert a number ending with a strange sign (such as 1em) to a pixel. // but it cannot be a location attribute, this should be because they are proportional to the parent element, and we cannot measure the ratio of the parent element, because it may be a bunch of proportional stacks (such as <div style = 'left: 10% '> <p style = 'left: 100'> <span style = 'left: 100'> </span> </p> </div> ), if (rnumnonpx. test (ret )&&! Rposition. test (name) {// Save the original value left = style. left; rs = elem. runtimeStyle; rsLeft = rs & rs. left; // Add a new value to obtain the calculated value if (rsLeft) {rs. left = elem. currentStyle. left;} style. left = name = "fontSize "? "1em": ret; ret = style. pixelLeft + "px"; // restore the changed value style. left = left; if (rsLeft) {rs. left = rsLeft;} return ret = ""? "Auto": ret ;};}

Final Processing of the jquery.fn.css Function

return value !== undefined ?        jQuery.style( elem, name, value ) :        jQuery.css( elem, name );

We can see two key low-level APIs for css processing: jquery.styleand jquery.css.

We have analyzed that only. style is readable and writable. Similarly, jQuery. style is used to read and write inline styles. The processing process of jQuery. style is

1. Modify the css feature name to save it as origName, and the name that can be recognized by the browser is saved as name.

2. Find the cssHooks of name or origName.

3. If the value is set (with the value parameter passed), set it. The special processing is that the value can be a cumulative string (for example, the original query.css is used to retrieve the original value for calculation. If the value is a number, check whether the unit of "px" is added as needed. If there is a corresponding cssHooks, special processing is required.

4. If the value is obtained (the value parameter is not passed), the hooks can be obtained through hooks in two cases. Otherwise, the style [name] can be used directly.

Source code

// Set or obtain the style feature value for the DOM node jQuery. style: function (elem, name, value, extra) {// The style feature value cannot be set for the text and comment nodes if (! Elem | elem. nodeType = 3 | elem. nodeType = 8 |! Elem. style) {return;} // modify the css feature name to adapt to the current browser var ret, type, hooks, origName = jQuery. camelCase (name), style = elem. style; // the css feature name that has been cached and queried by jQuery.css Props for subsequent convenient search use name = jQuery.css Props [origName] | (jQuery.css Props [origName] = vendorPropName (style, origName); // obtain the hooks with a prefix or without a prefix. hooks = jQuery.css Hooks [name] | jQuery.css Hooks [origName]; // set the value if (value! = Undefined) {type = typeof value; // convert relative number strings (+ = or-=) to relative numbers. #7345 // rrelNum = new RegExp ("^ ([+-]) = (" + core_pnum + ")", "I ") // convert the relative logarithm string + =/-= to the corresponding number if (type = "string" & (ret = rrelNum.exe c (value ))) {// (+ + 1) = 1; (-+ 1) =-1 value = (ret [1] + 1) * ret [2] + parseFloat (jQuery.css (elem, name); // Fixes bug #9237 type = "number" ;}// NaN and Null is not available if (value = null | type = "number" & isNaN (value) {return ;} // The css feature cannot be set as the unit of pixels in addition to the feature. For other features, add "px" if (type = "number "&&! JQuery.css Number [origName]) {value + = "px";} // support. clearCloneStyle = div. style. backgroundClip = "content-box"; // div. style. backgroundClip is a background that is not in "content-box" mode and has an empty value... set it to inherit the parent node style // Fixes #8908. More accurately, set the default value for each problem feature, but this will call the function if (! JQuery. support. clearCloneStyle & value = "" & name. indexOf ("background") = 0) {style [name] = "inherit";} // If a hook is provided, use the hook value, otherwise, set the top value if (! Hooks |! ("Set" in hooks) | (value = hooks. set (elem, value, extra ))! = Undefined) {// when the value to be set is invalid, ie will throw an exception // Fixes bug #5509 try {style [name] = value ;} catch (e) {} // obtain the value} else {// if a hook is provided, use the hook value if (hooks & "get" in hooks & (ret = hooks. get (elem, false, extra ))! = Undefined) {return ret;} // return a css feature name from the style object in other cases, this name may be the feature name function vendorPropName (style, name) with a prefix added by the supplier {// The short name does not contain the vendor prefix if (name in style) {return name ;} // check the supplier's prefix name // cssPrefixes = ["Webkit", "O", "Moz", "ms"] var capName = name. charAt (0 ). toUpperCase () + name. slice (1), origName = name, I = cssPrefixes. length; while (I --) {name = cssPrefixes [I] + capName; if (name in style) {return name ;}} return origName ;}View Code

  

JQuery.css processing is also relatively simple

1. Modify the css feature name to save it as origName, and the name that can be recognized by the browser is saved as name.

2. If the corresponding cssHooks exists, process it; otherwise, use the curCSS method to obtain the style value.

3. Make some default values worth processing for the obtained style values. For example, the default value of css style fontWeight is "normal" and the corresponding value should be 400.

Source code

// Obtain the css feature value css: function (elem, name, extra, styles) {var num, val, hooks, origName = jQuery. camelCase (name); // corrected name = jQuery.css Props [origName] | (jQuery.css Props [origName] = vendorPropName (elem. style, origName); // obtain the hooks with or without a prefix. hooks = jQuery.css Hooks [name] | jQuery.css Hooks [origName]; // extract the value if (hooks & "get" in hooks) {val = hooks. get (elem, t Rue, extra);} // use the curCSS value in other cases if (val = undefined) {val = curCSS (elem, name, styles );} // cssNormalTransform = {letterSpacing: 0, fontWeight: 400} // convert "normal" to the calculated value if (val = "normal" & name in cssNormalTransform) {val = cssNormalTransform [name];} // forcibly convert a value to a number when the limit or val value is provided and returns if (extra = "" | extra) {num = parseFloat (val ); return extra === true | jQuery. isNumeric (nu M )? Num | 0: val;} return val ;}View Code

  

OK. This chapter is finally completed.

 

If you think this article is good, click [recommendation] in the lower right corner ]!

 

  

  

 

  

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.