Details about browser Feature Detection (1)-added in jQuery1.4

Source: Internet
Author: User

Its most classic application is the general addEvent function:

Function addEvent (element, type, handler) {if (element. attachEvent) {// IE8 and the following browser elements. attachEvent ('on' + type, handler);} else {// W3C standard browser element. addEventListener (type, handler, false );}};

The function can determine whether to use the attachEvent or addEventListener by checking whether the attachEvent function exists. This is also the simplest feature detection, so it usually performs real-time detection when necessary. Another feature is detected because the detection process is troublesome, so the detection is completed in advance and the detection results (usually Boolean type) are saved in a variable.

The main purpose of this article is to analyze and describe the new content of browser Feature Detection in jQuery1.4, and to deepen the memory of several details about browser compatibility.

JQuery1.4 mainly adds the following browser features. This article analyzes them one by one:

CheckOn
Version 1.4 is introduced to determine whether the checkbox with no value set has the default value "on ".
OptSelected
Version 1.4.3 is introduced to determine whether the first option element of the select element will be selected by default.
OptDisabled
Version 1.4.3 is introduced to determine whether all the option sub-elements of a select element are also set to disabled after the select element is set to disabled.
CheckClone
Version 1.4.1 is introduced to determine whether the checked attribute of radio and checkbox will be retained when DocumentFragment uses the cloneNode function.
InlineBlockNeedsLayout
Introduced in version 1.4.3, it is decided that the next block element in IE has the hasLayout attribute and has display: inline;Whether the display is based on inline-block.
ShrinkWrapBlocks
Version 1.4.3 is introduced to determine whether the quilt element will not be large when the next element of IE has the hasLayout attribute and fixed width/height.
ReliableHiddenOffsets
Version 1.4.3 is introduced to determine whether a td or th element is set display: none;Whether there is offsetHeight.
CheckOn

Use the following code to detect this feature:

<input id="checkOn" type="checkbox" /> <script type="text/javascript"> alert(document.getElementById('checkOn').value); </script>

The running results in various browsers are as follows:

IE6 On
IE7 On
IE8 On
IE9 beta On
Firefox 3.6 On
Chrome 7 [Null String]
Safari 5 On

After testing, all browsers except Chrome will give the checkbox with no value a default value "on ".

This feature is used by jQuery to obtain checkbox and radio values. compatible judgment statements are as follows:

// The browsers that do not support checkOn do not have the problem of mixed property/attribute. Therefore, you need to explicitly use getAttribute return support. checkOn? Element. value: (element. getAttribute ('value') = null? 'On': element. value );
OptSelected

Use the following code to detect this feature:

<select id="optSelected"> </select> <script type="text/javascript"> var select = document.getElementById('optSelected'), option = document.createElement('option'); select.appendChild(option); alert(option.selected); </script>

The running results in various browsers are as follows:

IE6 False
IE7 False
IE8 False
IE9 beta False
Firefox 3.6 True
Chrome 7 True
Safari 5 False

After testing, the IE series and Safari use appendChild to add an option to an empty select element, the selected Attribute of this option is not set to true by default.

The BUG caused by this problem is described as follows:

Some browsers return false incorrectly when obtaining the selected Attribute of option.

The solution to this problem is to first access the selectedIndex attribute of the parent select element when accessing the selected Attribute, and force the browser to calculate the selected Attribute of the option to get the correct value. Note that the parent element of the option element may not be select or optgroup. The Code is as follows:

If (! Support. optSelected) {var parent = option. parentNode; parent. selectedIndex; // if (parent. parentNode) {parent. parentNode. selectedIndex;} return option. selected;
OptDisabled

Use the following code to detect this feature:

<select id="optDisabled" disabled="disabled"> <option></option> </select> <script type="text/javascript"> var select = document.getElementById('optDisabled'), option = select.getElementsByTagName('option')[0]; alert(option.disabled); </script>

The running results in various browsers are as follows:

IE6 False
IE7 False
IE8 False
IE9 beta False
Firefox 3.6 False
Chrome 7 False
Safari 5 True

After testing, Safari will set the option in the select with disabled as well as disabled.

This feature is used to obtain the value of the select element. When the select element is rendered as a multi-choice box, you need to remove the option element of disabled. However, in Safari, when obtaining the select value set to disabled, the value cannot be obtained because all option elements are set to disabled.

Therefore, optDisabled (true indicates optionNoAfter being set to disabled automatically, you can have the following code:

// If optDisabled is true, the true state of option is returned for the disabled attribute. // otherwise, whether the disabled attribute is null var disabled = support. optDisabled? Option. disabled: option. getAttribute ('Disabled ')! = Null; if (! Disabled) {return option. value ;}
CheckClone

Use the following code to detect this feature:

<div id="checkClone"> <input type="radio" name="checkClone" checked="checked" /> </div> <script type="text/javascript"> var fragment = document.createDocumentFragment(), div = document.getElementById('checkClone'), radio = div.getElementsByTagName('input')[0]; fragment.appendChild( radio ); alert(fragment.cloneNode(true).cloneNode(true).lastChild.checked); </script>

Note that to reproduce this problem, you must explicitly specify a name attribute for the input and call the cloneNode function twice in a row when copying the fragment object.

The running results in various browsers are as follows:

IE6 True
IE7 True
IE8 True
IE9 beta True
Firefox 3.6 True
Chrome 7 True
Safari 5 True
Safari 4 False

The results show that this problem occurs in Safari 4 and has been fixed in Safari 5, which is due to the market share of Safari and older versions, this issue does not require much attention.

This feature is rarely used, and there is almost no such strict environment in development (for DocumentFragment to call cloneNode twice in a row). In jQuery, this feature is used as the cache function in the buildFragment internal function. jQuery caches the creation results of strings that are relatively simple to create DOM elements to DocumentFragment. However, when radio is created, if cloneNode is false, the cache is forcibly disabled.

InlineBlockNeedsLayout

This is a long history issue, which is not supported by IE7 or earlier versions.display: inline-block;Style, but usedisplay: inline;Other styles are used to trigger its hasLayout to form a pseudo-inline-block state (click here for details ).

An important difference between inline-block and inline is that the inline-block element can explicitly set the width and height, so you can use the following code to detect this feature:

<div id="inlineBlockNeedsLayout" style="width: 1px; padding-left: 1px; display: inline; zoom: 1;"> </div> <script type="text/javascript"> var div = document.getElementById('inlineBlockNeedsLayout'); alert(div.offsetWidth); </script>

The running results in various browsers are as follows:

IE6 2
IE7 2
IE8 1
IE9 beta 1
Firefox 3.6 1
Chrome 7 0
Safari 5 0

For inline elements, the width style is invalid. In this test, all webkit browsers get 0, IE8 and Firefox get 1, only IE7 and earlier versions calculate both width and padding-left, And the 2px width is obtained.

This function can be used to set the css style of an element. When you need to set it to inline-block, you can set the css style for IE7 and the following browsers at the same time.display: inline;Andzoom: 1;To simulate the effect, the core code is as follows:

if (name == 'display' && value == 'inline-block') { if (support.inlineBlockNeedsLayout) { element.style.display = 'inline'; element.style.zoom = 1; } else { element.style.display = value; } };

Of course, this is definitely a problem. What should I do when I need to get the display style? Can zoom and display be determined at the same time? In addition, hasLayout may cause some other problems.

Therefore, jQuery only uses this feature for animation effects. When width and height are to be animated and the element is inline, it is first set to the (pseudo) inline-block state, after the animation ends, the relevant style is restored.

ShrinkWrapBlocks

For details about this problem, refer to the following code to detect this feature:

<div id="shrinkWrapBlocks" style="width: 1px; zoom: 1;"> <div style="width: 4px;"> </div> </div> <script type="text/javascript"> var div = document.getElementById('shrinkWrapBlocks'), inner = div.getElementsByTagName('div')[0]; alert(div.offsetWidth); </script>

The running results in various browsers are as follows:

IE6 4
IE7 1
IE8 1
IE9 beta 1
Firefox 3.6 1
Chrome 7 1
Safari 5 1

The test results show that, even if IE6 explicitly sets the width, the size of IE6 is greatly affected by the influence of sub-elements when hasLayout is triggered.

JQuery uses this feature for animation effects. To change the width/height of an element during the animation process, its child elements do not overflow. jQuery performs the following steps:

  1. Saves the current overflow, overflow-x, and overflow-y styles of the element.
  2. Set the element to inline-block to modify the width/height value.
  3. Set the overflow of the element to hidden to prevent child element overflow or support (IE6) of the current element ).
  4. After the animation ends,Make sure that the element is not supported by the quilt element (the value of shrinkWrapBlocks is true ).To restore the overflow style.
ReliableHiddenOffsets

This problem was encountered during the work in the last two days. jQuery1.4.3 upgraded the content and the following code can be used to detect this feature:

<table id="reliableHiddenOffsets"> <tbody> <tr> <td style="display: none;"> </td> <td> abcd </td> </tr> </tbody> </table> <script type="text/javascript"> var table = document.getElementById('reliableHiddenOffsets'), td = table.getElementsByTagName('td')[0]; alert(td.offsetHeight); </script>

The running results in various browsers are as follows:

IE6 0
IE7 0
IE8 21
IE9 beta 0
Firefox 3.6 0
Chrome 7 0
Safari 5 0

Only IE8 has this problem. When the display of the td element is none, its height will still be affected by the height of its row, rather than 0.

The existence of this problem fundamentally leads to an error in the determination of element visibility. The Code originally used to determine whether an element is hidden is like this:

function isHidden(element) { return element.offsetWidth == 0 || element.offsetHeight == 0; };

Due to the emergence of this BUG, the above function has lost effect on the td element, so it needs to be improved:

function isVisible(element) { return (element.offsetWidth == 0 && element.offsetHeight == 0) || (!support.reliableHiddenOffsets && getStyle(element, 'display') == 'none'); };

When reading the jQuery source code, you will find that there is an additional sentence in this section.element.style.displayThis statement is used to determine whether the element has a display value and check whether it is none, so as to avoid overhead of the runtime style.

Conclusion
  1. Feature Detection is indeed useful. Sometimes it is more reliable than browser version sniffing, but it is quite troublesome to detect some features. If not necessary, it is better to use browser sniffing.
  2. The name of jQuery's features really makes people want to cut down their team.
  3. The low version of browsers with some features that can be reproduced is surprising, and can be ignored in most projects, such as checkClone. JQuery has made too many assumptions for compatibility. I personally think that some of them can be completely abandoned. For example, we will discuss the getBoundingClientRect issue later.
  4. There are also two feature checks on events. Because event feature detection is a common topic, we will write a specific article in the future, so we will not repeat it in this article.
  5. Every small version of jQuery has been greatly improved, especially in terms of details. These are constantly explored by reading the source code, and the front-end world is so changeable (sigh ).
  6. You can click here to view the examples used in this article. For more information, see the source code. No Authoritative instructions are found on the Internet for all the problems/bugs described in this article. Sorry!

<! Doctype html> <ptml xmlns = "http://www.w3.org/1999/xhtml"> <pead> <title> Untitled Page </title> </pead> <body> checkOn <input id = "checkOn" type = "checkbox"/> optSelected <select id = "optSelected"> </select> optDisabled <select id = "optDisabled" disabled = "disabled"> <option> </option> </select> checkClone <input type = "radio" name = "checkClone" checked = "checked"/> inlineBlockNeedsLayout shrinkWrapBlocks reliableHiddenOffsets <table id = "reliableHiddenOffsets"> <tbody> <tr> <td style = "display: none; "> </td> <td> abcd </td> </tr> </tbody> </table> </body> </ptml>
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]

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.