Detail browser feature detection (1)-jquery1.4 Add part _jquery

Source: Internet
Author: User
The most classic use of this is the Universal addevent function:

function addEvent(element, type, handler) { 
if (element.attachEvent) { //IE8及以下浏览器 
element.attachEvent('on' + type, handler); 
} 
else { //W3C标准浏览器 
element.addEventListener(type, handler, false); 
} 
};

A function can detect whether the Attachevent function exists to determine the use of attachevent or AddEventListener, which is also the simplest feature detection, so that it is usually detected in real time when needed. Another feature is that the detection process is more cumbersome, so the detection is completed in advance, and the result of the detection (usually a Boolean type) is saved in a variable.

The main goal of this article is to analyze, explain the new content of browser features in jQuery1.4, and deepen the memory of several details of browser compatibility.

jQuery1.4 has mainly added the following several browser characteristics, this article for them to analyze:

Checkon
The 1.4 version is introduced to determine whether a checkbox without setting the value value has a default value of "on".
optselected
The 1.4.3 version is introduced to determine whether the first OPTION element of the Select element is selected by default.
Optdisabled
The 1.4.3 version is introduced to determine whether all option child elements are also set to disabled when the Select element is set to disabled.
Checkclone
The 1.4.1 version is introduced to determine whether radio and checkbox checked properties will be retained when using the CloneNode function for DocumentFragment.
Inlineblockneedslayout
The 1.4.3 version is introduced to determine if the next block element of IE has a haslayout attribute and is display: inline; displayed by Inline-block.
Shrinkwrapblocks
1.4.3 version of the introduction, decided that the next element of IE has haslayout attributes and fixed width/height, whether the quilt elements will not be large.
Reliablehiddenoffsets
The
1.4.3 version is introduced to determine whether a TD or TH element is set to display: none; be offsetheight.

Checkon

You can detect this attribute by using the following code:

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

The following are the results of the running in each browser:

IE6 On
IE7 On
IE8 On
IE9 Beta On
Firefox 3.6 On
Chrome 7 [Empty string]
Safari 5 On

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

This feature is used by jquery to get the values of the checkbox and radio, and the compatible judgment statements are as follows:

//不支持checkOn的浏览器都不存在property/attribute混用问题,因此需要明确使用getAttribute 
return support.checkOn ? 
element.value : 
(element.getAttribute('value') === null ? 'on' : element.value);

optselected

You can detect this attribute by using the following code:

<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 following are the results of the running in each browser:

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

After testing, IE series and Safari using AppendChild to add an option to an empty SELECT element, the option's Selected property is not set to True by default.

The bug that caused the problem is described below:

Some browsers incorrectly return false when they get the selected property of option.

The solution to this problem is to access the selected property by first accessing the SelectedIndex property of its parent select element, forcing the browser to compute the option's Selected property to get the correct value. It should be noted that the parent element of the option element is not necessarily a select, it may be a optgroup. The specific code is as follows:

if (!support.optSelected) { 
var parent = option.parentNode; 
parent.selectedIndex; 
//处理optgroup时的情况 
if (parent.parentNode) { 
parent.parentNode.selectedIndex; 
} 
} 
return option.selected;

Optdisabled

You can detect this attribute by using the following code:

<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 following are the results of the running in each browser:

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

After testing, Safari will also set the option in the Select Disabled set to Disabled.

This feature is used to get the value of the Select element, especially when the select is rendered as a multiple-selection box, you need to be aware of removing the option element from disabled, but in Safari, when you get the value of a select that is set to disabled, Because all option elements are set to disabled, the value cannot be obtained.

So with optdisabled (true means that option is not automatically set disabled), you can have this code:

//如果optDisabled为true,则disabled属性返回的是option的真实状态 
//否则判断disabled属性是否为null 
var disabled = support.optDisabled ? 
option.disabled : option.getAttribute('disabled') !== null; 
if (!disabled) { 
return option.value; 
}

Checkclone

You can detect this attribute by using the following code:

<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 need to explicitly specify a name property for input, and call the CloneNode function 2 consecutive times when copying the fragment object.

The following are the results of the running in each browser:

true
true
true
true
firefox 3.6 true
true
true
false

As you can see from the results, the problem appears in Safari 4, and has been repaired in Safari 5, between Safari's share in the market and the older version, the problem does not need much attention.

This feature is rarely used, and in development there is little such a stringent environment (2 consecutive calls to DocumentFragment CloneNode), in jquery, which is used as a caching function in buildfragment this intrinsic function, jquery caches the creation result of a simpler string that creates a DOM element into DocumentFragment, but if CloneNode is false when it encounters the creation of a radio, it is enforced without caching.

Inlineblockneedslayout

This is a long history problem, IE7 the following version does not support the display: inline-block; style, but uses display: inline; and other styles to trigger its haslayout to form a pseudo Inline-block state (specifically click here).

An important difference between inline-block and inline is that inline-block elements can be set and high explicitly, so you can detect the attribute with the following code:

<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 following are the results of the running in each browser:

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, WebKit browser has obtained 0,ie8 above version and Firefox obtained 1, only IE7 and the following version of the calculation of width and padding-left, the width of 2px.

This feature can be used to set the CSS style of the elements, when the need to set to Inline-block, for IE7 and the following browsers can be set up display: inline; and zoom: 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 a direct way to use this is certainly problematic, when you need to get the display style how to do? Judge Zoom and display at the same time? and haslayout can cause some other problems.

Therefore, jquery uses this feature only for animation, when the width and height need to be animated, and when the element is inline, it is first set to the (pseudo) Inline-block state, and the associated style is restored when the animation finishes.

Shrinkwrapblocks

A detailed explanation of this problem can be referenced here, using the following code to detect the attribute:

<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 following are the results of the running in each browser:

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

The test results show that the size of IE6 can be propped up by the influence of the child element even if the width is explicitly set and the haslayout is triggered.

jquery uses this feature for animation, and for the purpose of changing the width/height of an element during the animation, the child elements do not overflow, and jquery does the following steps:

    1. Saves the current overflow, overflow-x, overflow-y Three styles of the element.
    2. Set the element to Inline-block to modify the Width/height value.
    3. Sets the element's overflow to hidden, prevents the child element from overflowing or the current element quilt element is stretched (IE6).
    4. After the animation finishes, make sure that the element does not open (Shrinkwrapblocks to true) of the quilt element before resuming the overflow style.

Reliablehiddenoffsets

This problem was encountered in the last two days of work, just jQuery1.4.3 upgrade this content, use the following code 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 following are the results of the running in each browser:

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

Only IE8 has this problem, when the TD element display is none, its height is still affected by the height of its row, not 0.

The existence of this problem has fundamentally led to an error in determining the visibility of elements, and the code that originally judged whether an element was hidden was this:

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

Because of this bug, the above function loses its effect on the TD element, so it needs to be improved to:

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

Read the jquery source, you will find this section of the judgment of a more sentence element.style.display , this sentence is used to determine the element has display value to take to see if none of the, so as to avoid getting the run-time style overhead.

Conclusion

    1. Feature detection is really useful, sometimes more reliable than browser version sniffing, but it's rather cumbersome to detect certain features, rather than using browser sniffing when necessary.
    2. jquery's naming of features really makes people want to chop off their team.
    3. Some features can reproduce the low surprise of the browser version, in most projects can not be considered, such as Checkclone. jquery itself makes too many assumptions about compatibility, and the individual thinks that there are some things that can be completely discarded, such as getboundingclientrect problems that can be said later.
    4. There are also 2 of the characteristics of the detection of events, because the characteristics of the event detection is a common topic, there will be dedicated to write the article, so it is not in this article to repeat.
    5. jquery each small version of the improvement is very large, especially in detail, these are to read through the source of the continuous excavation, the front end of the world is so changeable (sigh).
    6. This article uses the example can click this view, the concrete can view the source code, this article describes each question/bug not to find the authoritative explanation on the Internet, also please forgive me!

<! DOCTYPE html> <ptml xmlns= "http://www.w3.org/1999/xhtml" > <pead> <title>untitled page</title > <script type= "Text/javascript" > Function w (title, result) {document.write (' <p><label> ' + title + '-</label><span> ' + result + ' </span></p> '); }; </script> </pead> <body> <!--checkon--> <p>checkOn</p> <input id= "Checkon" type= "checkbox"/> <script type= "text/javascript" > (function () {W (' Checkon.value ', document.getElementById ( ' Checkon '). Value); })(); </script> <!--optselected--> <p>optSelected</p> <select id= "optselected" > </sele ct> <script type= "Text/javascript" > (function () {var select = document.getElementById (' optselected '), Optio n = document.createelement (' option '); Select.appendchild (option); W (' optselected>option.selected ', option.selected); })(); </script> <!--Optdisabled--> <p>optDisabled</p> <select id= "optdisabled" disabled= "Disabled" > <option>< /option> </select> <script type= "Text/javascript" > (function () {var select = document.getElementById ( ' optdisabled '), option = select.getelementsbytagname (' option ') [0]; W (' optdisabled>option.disabled ', option.disabled); })(); </script> <!--checkclone--> <p>checkClone</p> <div id= "Checkclone" > <input type= " Radio "Name=" Checkclone "checked=" checked "/> </div> <script type=" Text/javascript "> (function () {var fragment = Document.createdocumentfragment (), div = document.getElementById (' Checkclone '), radio = Div.getelementsbyta Gname (' input ') [0]; Fragment.appendchild (radio); W (' radioaftercloned ', Fragment.clonenode (True). CloneNode (True). lastchild.checked); })(); </script> <!--inlineblockneedslayout--> <p>inlineBlockNeedsLayout</p> <div id= " InlinebloCkneedslayout "style=" WIDTH:1PX; padding-left:1px; Display:inline; zoom:1; " > </div> <script type= "Text/javascript" > (function () {var div = document.getElementById (' Inlineblockn Eedslayout '); W (' Inlineblockneedslayout.offsetwidth ', div.offsetwidth); })(); </script> <!--shrinkwrapblocks--> <p>shrinkWrapBlocks</p> <div id= "Shrinkwrapblocks" & Gt <div > </div> </div> <script type= "Text/javascript" > (function () {var div = Document.getele Mentbyid (' shrinkwrapblocks '), inner = div.getelementsbytagname (' div ') [0]; W (' Innerdiv.offsetwidth ', inner.offsetwidth); })(); </script> <!--reliablehiddenoffsets--> <p>reliableHiddenOffsets</p> <table id= " Reliablehiddenoffsets "> <tbody> <tr> <td > </td> <td> ABCD </td> </tr&gt ; </tbody> </table> <script type= "Text/javascript" > (function () {var table = docUment.getelementbyid (' Reliablehiddenoffsets '), TD = Table.getelementsbytagname (' TD ') [0]; W (' Td[0].offsetheight ', td.offsetheight); })(); </script> </body> </ptml>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

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.