最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

jQuery.support的实现方式

来源:懂视网 责编:小采 时间:2020-11-27 20:16:52
文档

jQuery.support的实现方式

jQuery.support的实现方式:jQuery.support jQuery.support 用于检查浏览器对各项特性的支持。检查项多达 27 个。 首先,让我们用一段代码测试一下 support 中包含的检查项:<script src='jquery.js'></script> <script>
推荐度:
导读jQuery.support的实现方式:jQuery.support jQuery.support 用于检查浏览器对各项特性的支持。检查项多达 27 个。 首先,让我们用一段代码测试一下 support 中包含的检查项:<script src='jquery.js'></script> <script>

jQuery.support


jQuery.support 用于检查浏览器对各项特性的支持。检查项多达 27 个。
首先,让我们用一段代码测试一下 support 中包含的检查项:

<script src='jquery.js'></script>
<script>
support = $.support;
for (key in support) {
	document.write('support.' + key + ' = ' + support[key] + '<br />');
}
</script>


IE 下的输出结果为:

support.leadingWhitespace = false
support.tbody = false
support.htmlSerialize = false
support.style = false
support.hrefNormalized = false
support.opacity = false
support.cssFloat = false
support.checkOn = true
support.optSelected = false
support.getSetAttribute = false
support.submitBubbles = false
support.changeBubbles = false
support.focusinBubbles = true
support.deleteExpando = false
support.noCloneEvent = false
support.inlineBlockNeedsLayout = false
support.shrinkWrapBlocks = true
support.reliableMarginRight = true
support.noCloneChecked = false
support.optDisabled = true
support.radioValue = false
support.checkClone = undefined
support.appendChecked = false
support.boxModel = false
support.reliableHiddenOffsets = false
support.ajax = true
support.cors = false


FireFox 中的显示结果为:

support.leadingWhitespace = true
support.tbody = true
support.htmlSerialize = true
support.style = true
support.hrefNormalized = true
support.opacity = true
support.cssFloat = true
support.checkOn = true
support.optSelected = true
support.getSetAttribute = true
support.submitBubbles = true
support.changeBubbles = true
support.focusinBubbles = false
support.deleteExpando = true
support.noCloneEvent = true
support.inlineBlockNeedsLayout = false
support.shrinkWrapBlocks = false
support.reliableMarginRight = true
support.noCloneChecked = true
support.optDisabled = true
support.radioValue = true
support.checkClone = undefined
support.appendChecked = true
support.boxModel = true
support.reliableHiddenOffsets = true
support.ajax = true
support.cors = true


需要注意的是,源代码中 checkClone 的检查是有问题的。这将在后面提到。
接下来,我们就对这些检查项进行逐一的分析。

leadingWhitespace


检查用 innerHTML 赋值时,是否会保留前面的空白符。
IE中为 false , Firefox 中为 true 。
实现方式如下:

$ = function(){ 
 var p = document.createElement( "p" );
 p.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
 
 var support = {
 leadingWhitespace: (p.firstChild.nodeType === 3) 
 }
 
 return { support : support }
}();


这段代码中,先创建了一个 p ,之后就用 innerHTML 为 p 赋值,
然后检查 p 的第一个子元素的 nodeType 是否为 3 (表示文本),
是的话则空白字符被保留,否则未被保留。

tbody


检查是否会自动为 table 插入 tbody ,会的话为 false ,不会则为 true 。
IE中为 false , FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...
 
 var support = {
 leadingWhitespace: (p.firstChild.nodeType === 3),
 tbody: !p.getElementsByTagName("tbody").length
 }
 
 // Other codes ...
}();


这段代码在原有基础上为 support 增加了 tbody 属性, 并检查是否能够获取 tbody 标签。
由于 innerHTML 中已经包含了 table 标签,能获取 tbody 标签的话则表示会自动为 table 插入 tbody,否则表示不会自动插入 tbody 。

htmlSerialize


检查link标签能否被正确地序列化。
IE中为 false , FireFox 中为true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 var a = p.getElementsByTagName("a")[0];

 var support = {
 // Other codes ...
 tbody: !p.getElementsByTagName( "tbody" ).length,
 htmlSerialize: !!p.getElementsByTagName("link").length
 }
 
 return { support : support }
}();


这段代码在原有基础上为 support 增加了 htmlSerialize 属性,并检查能否获取 link 标签。
由于 innerHTML 中已经包含了 link 标签,能通过getElementsByTagName 获取 link 标签的话,表示 link 可以被正确地序列化,否则表示 link 标签不能被正确地序列化。

style


检查是否能通过 “style” 属性获取 DOM Element 的样式。
IE中为 false , Firefox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 var a = p.getElementsByTagName("a")[0];

 var support = {
 // Other codes ...
 htmlSerialize: !!p.getElementsByTagName("link").length,
 style: /top/.test(a.getAttribute("style"))
 }
 
 return { support : support }
}();


这段代码先是通过 getElementsByTagName("a") 获取表示链接的 DOM Element,
然后在原有基础上为 support 增加了 style 属性,并检查能否通过 getAttribute("style") 获取样式。

hrefNormalized


检查链接的 “href” 属性能否被正常地序列化。
IE中为 false , FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 var support = {
 // Other codes ...
 style: /top/.test(a.getAttribute("style")),
 hrefNormalized: (a.getAttribute("href") === "/a")
 }

 return { support : support }
}();


这段代码通过 getAttribute("href") 来获取 “href” 属性的值,
能正确获取则表示链接的 “href”属性能够被正确地序列化。

opacity


检查 css 样式中的透明度设置能够被有效支持。
IE 中为 false , FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 var support = {
 // Other codes ...
 hrefNormalized: (a.getAttribute("href") === "/a"),
 opacity: /^0.55$/.test(a.style.opacity)
 }
 
 return { support : support }
}();


这段代码通过 a.style.opacity 来获取透明度设置,并用正则表达式 /^0.55$/ 进行检查,通过检查表示 css 样式中的透明度能够被有效地支持,否则表示不能。

cssFloat


检查 css 样式中的 float 属性能够被有效支持。
IE 中为 false , FireFox中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 var support = {
 // Other codes ...
 opacity: /^0.55$/.test(a.style.opacity),
 cssFloat: !!a.style.cssFloat
 }
 
 return { support : support }
}();


这段代码通过 a.style.cssFloat 来获取 float 属性,并通过 !! 将属性转为 boolean 值(undefined 将被转为 false ,而其他值将被转为 true)。

checkOn


检查 chebox 的 value 是否为 “on”。
IE 和 FireFox 中都为true,而 Chrome 中则为 false 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 var a = p.getElementsByTagName("a")[0],
 input = p.getElementsByTagName("input")[0];

 var support = {
 // Other codes ...
 cssFloat: !!a.style.cssFloat,
 checkOn: (input.value === "on")
 }
 
 return { support : support }
}();


这段代码先通过 getElementsByTagName("input") 获取 checkbox,然后检查 checkbox 的 value 是否为 “on”。

optSelected


检查 select 中的第一个 option 能否被默认选中。
IE 中为 false , FireFox 中为 true 。

$ = function(){ 
 // Other codes ...

 var select = document.createElement("select");
 var opt = select.appendChild(document.createElement("option"));

 var support = {
 // Other codes ...
 checkOn: (input.value === "on"),
 optSelected: opt.selected
 }
 
 return { support : support }
}();


这段代码先通过 createElement("select") 创建了一个 select,
然后将一个 “option” 添加到了 select 中。
接着在 support 中增加了属性 optSelected,检查 opt.selected 是否为true 。

getSetAttribute


检查能够功过 getAttribute("calssName") 和 setAttribute("className", "...") 来获取和设置 p 的 css class。
实际上只检查 setAttribute("className", "...")。
IE 中为 false , FireFox 中为 true 。

$ = function(){ 
 // Other codes ...

 p.setAttribute("className", "t");
 
 var support = {
 // Other codes ...
 optSelected: opt.selected,
 getSetAttribute: p.className !== "t"
 }
 
 return { support : support }
}();


这段代码通过 p.setAttribute("classsName", "t") 将 p 的 css class 设置为 “t”,然后在 support 中增加 getSetAttribute 属性, 检查 p 的 className 是否为 “t”。

submitBubbles, changeBubbles, focusinBubbles


检查 submit、change、focus 事件是否在“冒泡阶段”触发。实际上只针对 IE 进行检查。因为大多数浏览器(及IE9)使用 addEventListener 附加事件,函数的第三个参数 useCapture (是否在“捕捉阶段”触发事件)既可以为 false ,也可以为 true 。
而 IE (IE9之前)使用 attachEvent 函数附加事件,该函数无法指定在哪个阶段触发事件,一律都为“冒泡阶段”触发。

关于 Bubble Event 的更多内容,可以参考 iteye 里其他相关的文章:
http://www.iteye.com/search?query=bubble+event&type=blog

实现方式如下:

$ = function(){ 
 // Other codes ...
 
 var support = {
 // Other codes ...
 getSetAttribute: p.className !== "t",
 submitBubbles: true,
 changeBubbles: true,
 focusinBubbles: false
 }

 if (p.attachEvent) {
 for(var i in { submit: 1, change: 1, focusin: 1 }) {
 var eventName = "on" + i;
 var isSupported = (eventName in p);
 if (!isSupported) {
 p.setAttribute(eventName, "return;");
 isSupported = ( typeof p[eventName] === "function" );
 }
 support[i + "Bubbles"] = isSupported;
 }
 }

 return { support : support }
}();


首先,在 support 中增加 submitBubbles, changeBubbles, focusinBubbles,默认值分别为 true, true, false ,这是针对大多数浏览器的。
然后,针对IE (也就是存在 DOMElement.attachEvent 函数的情况),检查 "onXXX" 事件是否存在,以及能否通过 setAttribute(eventName, xxx)进行设置,可以的话就判断为“冒泡阶段”触发(即只要支持该事件,就判断为“冒泡阶段”触发)。

事实上,jQuery 中的 focusin 事件是在 focus 的基础上进行模拟的,浏览器并不支持该事件,所以 focusinBubbles 总是为 false。

从源代码中的注释来看,似乎还考虑到了跨站脚本攻击:
Short-circuiting here helps us to avoid an eval call (in setAttribute) which can cause CSP to go haywire.

大意是说在这里进行简短的检查(typeof p[eventName] === "function"),而不是直接用 eval 执行事件,可以避免不可控的跨站脚本攻击。(我不确定有没有翻译错)

deleteExpando


检查是否允许删除附加在 DOM Element 上的数据。
IE 中为 false , FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...
 
 var support = {
 // Other codes ...
 focusinBubbles: false,
 deleteExpando: true
 }

 // Other codes ...

 try {
 delete p.test;
 } catch(e) {
 support.deleteExpando = false;
 }

 return { support : support }
}();


首先在 support 中增加属性 deleteExpando ,默认值为 true 。
然后尝试删除 p.test ,发生错误则将 deleteExpando 设为 false 。

noCloneEvent


检查复制 DOM Element 时是否会连同 event 一起复制,会则为 false , 不会则为true 。
IE 中为 false , FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...
 
 var support = {
 // Other codes ...
 deleteExpando: true,
 noCloneEvent: true
 }

 // Other codes ...

 if (!p.addEventListener && p.attachEvent && p.fireEvent) {
 p.attachEvent( "onclick", function click() {
 support.noCloneEvent = false;
 p.detachEvent( "onclick", click );
 });
 p.cloneNode(true).fireEvent("onclick");
 }

 return { support : support }
}();


首先在 support 中增加属性 noCloneEvent , 默认值为 true 。
然后复制 p, 并触发其 “onclick” 事件,触发成功则为将 noCloneEvent 设为 false。
从判断条件来看,依旧是针对 IE 的事件体系的检查。

inlineBlockNeedsLayout, shrinkWrapBlocks


都是针对 offsetWidth 的检查。

inlineBlockNeedsLayout 表示将原本 display 为 block 的 DOM Element 设置为 disylay: inline 时,是否与 inline 形式的 DOM Elemnt 一致( offsetWidth 为 2 )。
IE 8 及之前的浏览器中为 true , FireFox 中为 false 。

shrinkWrapBlocks 表示内部 DOM Element 的样式是否会影响外部 DOM Element 的样式。
IE 6 中为 true , 多数浏览器中为 false 。
实现方式如下:

$ = function(){ 
 // Other codes ...
 
 var support = {
 // Other codes ...
 noCloneEvent: true,
 inlineBlockNeedsLayout: false,
 shrinkWrapBlocks: false
 }

 // Other codes ...

 if ( "zoom" in p.style ) {
 p.style.display = "inline";
 p.style.zoom = 1;
 support.inlineBlockNeedsLayout = ( p.offsetWidth === 2 );

 p.style.display = "";
 p.innerHTML = "<p style='width:4px;'></p>";
 support.shrinkWrapBlocks = ( p.offsetWidth !== 2 );
 }

 return { support : support }
}();


首先在 support 中增加这两个属性,然后将 p 的 css 样式中的 display 设为 inline ,并检查 offsetWidth ,以确定 inlineBlockNeedsLayout 的值。
接着在 p 内部增加一个 p, 并将其宽度设为 4px ,并检查 offsetWith 的值,以确定外部的 p 是否会受到影响而收缩。

reliableMarginRight


检查 Margin Right 的计算是否可靠。 各浏览器中都为 true 。
原注释中提到某些老版本的 Webkit 内核的浏览器中为 false 。
实现方式如下:

$ = function(){ 
 // Other codes ...
 
 var support = {
 // Other codes ...
 shrinkWrapBlocks: false,
 reliableMarginRight: true
 }

 // Other codes ...

 if ( document.defaultView && document.defaultView.getComputedStyle ) {
 var marginp = document.createElement( "p" );
 marginp.style.width = "0";
 marginp.style.marginRight = "0";
 p.appendChild( marginp );
 support.reliableMarginRight =
 ( parseInt( document.defaultView.getComputedStyle( marginp, null ).marginRight, 10 ) || 0 ) === 0;
 }

 return { support : support }
}();


简单地说,就是将 width 和 marginRight 设为 0 时,获取的 marginRignt 应为 0 。

noCloneChecked


检查复制 checkbox 时是否连选中状态也一同复制,若复制则为 false ,否则为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 input.checked = true;
 support.noCloneChecked = input.cloneNode(true).checked;
 
 return { support : support }
}();


这段代码将 input 的选中状态设为 true ,然后复制 input ,并检查 checked 是否为 true 。

optDisabled


已经被设为 disable 的 select ,其内部的 option 的 disable 不应为 true 。
这个名称有一定的误导性,可能称为 “optNotDisabled” 更合适一些。
在各浏览器上的值都为 true 。
根据原注释,某些老版本的 Webkit 内核的浏览器上,该值为 false 。
实现如下:

$ = function(){ 
 // Other codes ...

 select.disabled = true;
 support.optDisabled = !opt.disabled;
 
 return { support : support }
}();


这段代码先将 select 的状态设为 disable , 然后检查其中的 option 的 disable 的值。

radioValue


检查 input 元素被设为 radio 类型后是否仍然保持原来的值。
IE 中为 false , FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 input = document.createElement("input");
 input.value = "t";
 input.setAttribute("type", "radio");
 support.radioValue = input.value === "t";

 return { support : support }
}();


这段代码先创建了 input 元素,将 value 设为 “t” ,然后将其类型设置为 “radio”,最后检查器 input 原来的值是否仍然保留。

checkClone


检查 fragment 中的 checkbox 的选中状态是否能被复制,IE 中为 false ,FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 p.innerHTML = "";

 input.setAttribute("checked", "checked");
 p.appendChild( input );
 fragment = document.createDocumentFragment();
 fragment.appendChild( p.firstChild );

 support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;

 return { support : support }
}();


这段代码创建了一个 fragment ,并将一个处于选中状态的 checkbox 加入,连续复制两遍后检查 checkbox 是否为选中状态。(这里源代码中的实现似乎有问题,没有将 p 的 innerHTML 清空,导致 p 的 firstChild 并非 checkbox,使得 checkclone 在各浏览器中的值均为 undefined 。)

appendChecked


检查被添加到 DOM 中的 checkbox 是否仍然保留原来的选中状态。
IE 中为 false ,FireFox 中为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 support.appendChecked = input.checked;

 return { support : support }
}();


实际上只是简单地检查之前添加到 fragment 中的 checkbox 的选中状态。

boxModel


检查页面渲染是否符合 W3C Box Model 。
在 IE 中没有 DocType 声明时为 false ,其余情况为 true 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 p.innerHTML = "";
 p.style.width = p.style.paddingLeft = "1px";

 body = document.createElement( "body" );
 bodyStyle = {
 visibility: "hidden",
 width: 0,
 height: 0,
 border: 0,
 margin: 0,
 background: "none"
 };
 for (var i in bodyStyle ) {
 body.style[i] = bodyStyle[i];
 }
 body.appendChild(p);
 document.documentElement.appendChild(body);

 support.boxModel = p.offsetWidth === 2;

 body.innerHTML = "";
 document.documentElement.removeChild( body );

 return { support : support }
}();


将 p 的 width 和 paddingLeft 设为 1px ,然后将它添加到 body 中,检查 p 的 offsetWidth 是否为 2 。

reliableHiddenOffsets


检查 hidden 状态下的 offsetWidth 和 offsetHeight 是否正确。
IE 中为 false , FireFox 中为 true 。
实现方式如下(插入到清空 body.innerHTML 之前):

$ = function(){ 
 // Other codes ...
 
 p.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
 var tds = p.getElementsByTagName("td");

 var isSupported = (tds[0].offsetHeight === 0);

 tds[0].style.display = "";
 tds[1].style.display = "none";

 support.reliableHiddenOffsets = isSupported && (tds[0].offsetHeight === 0);

 body.innerHTML = "";
 document.documentElement.removeChild( body );
 
 return { support : support }
}();


检查将一个 td 隐藏时, 相邻的 td 的 offsetHeight 是否为 0 。

ajax, cors


检查是否支持 ajax 请求,以及是否支持跨域 ajax。
IE 与 FireFox 中 ajax 均为 true ,IE 中 cors 为 false , FireFox 中 cros 为 false 。
实现方式如下:

$ = function(){ 
 // Other codes ...

 var xhr = window.ActiveXObject ?
 !this.isLocal && createStandardXHR() || createActiveXHR() :
 createStandardXHR();

 support.ajax = !!xhr;
 support.cors = !!xhr && ( "withCredentials" in xhr )
 
 function createStandardXHR() {
 try {
 return new window.XMLHttpRequest();
 } catch( e ) {}
 }

 function createActiveXHR() {
 try {
 return new window.ActiveXObject("Microsoft.XMLHTTP");
 } catch( e ) {}
 }

 return { support : support }
}();


尝试创建 ajax 对象,创建成功,则 ajax 为 true ;如果 ajax 对象中包含了 "withCredentials" 属性,则表示支持跨域 ajax。

文档

jQuery.support的实现方式

jQuery.support的实现方式:jQuery.support jQuery.support 用于检查浏览器对各项特性的支持。检查项多达 27 个。 首先,让我们用一段代码测试一下 support 中包含的检查项:<script src='jquery.js'></script> <script>
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top