源码解读jQ中浏览器兼容模块support

前端之家收集整理的这篇文章主要介绍了源码解读jQ中浏览器兼容模块support前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

jQuery的属性support是判断浏览器之间是否兼容的模块 ,该模块包含了

leadingWhitespace,tbody,htmlSerialize,style,hrefNormalized,opacity,cssFloat,checkOn,optSelected,getSetAttribute….

等兼容问题,所有的这些属性也只是jQuery内部会用到,因为jQ内部一些模块需要对这些东西进行判断, 就直接写成了一个support模块, 可以供我们, 但是我们写代码的时基本都没用到啊,

今天再把这些玩意儿过一下, 测试的浏览器为FF,CHROME,IE11, IE6-IE10是用IE11模拟的:

$.support.leadingWhitespace

  ———— IE中自动去空格

$.support.checkOn

—-chrome中radio默认值为checkOn

$.support.tbody

—-IE通过innerHTML自动生成tbody

$.support.htmlSerialize

—–  标准浏览器会自动生成link标签

$.support.style

  —-IE67中getAttriute会获取各种类型的数据….

$.support.opacity

  —- IE678不支持opacity

$.support.cssFloat

   —-cssFloat标准浏览器支持的,IE要用styleFloat

$.support.optSelected

  —–浏览器并不会设置默认的option

$.support.getSetAttribute

  —-getSetAttribute在浏览器之间的兼容

$.support.html5Clone

   —- 复制标签的问题

$.support.BoxModel

  —- 是否支持盒模型

$.support.submitBubbles

  —-冒泡

$.support.changeBubbles

  —-冒泡

$.support.focusinBubbles

  —-冒泡

$.support.deleteExpando

  —–IE的DOM元素是COM组件, 不能delete组件的属性

$.support.noCloneEvent

   —-复制元素的事件

$.support.reliableHiddenOffsets

  —-table元素中tr内td的问题;

$.support.BoxSizing

  —是否支持BoxSizing

$.support.doesNotIncludeMarginInBodyOffset

  —-body不会包含margin的问题(算不算问题呢?)

$.support.pixelPosition

  —-获取样式返回的是否是像素值

$.support.BoxSizingReliable

  —-BoxSizing是否可用

$.support.reliableMarginRight

—-chrome中margin的bug

$.support.inlineBlockNeedsLayout

—-IE中layout的问题

$.support.shrinkWrapBlocks

—-IE6中自动扩大宽高的问题

$.support.leadingWhitespace属性

兼容 "

//但是我们可以通过jQuery的方式生成并插入到DOM数种
$("").appendTo(document.body)

$.support.style

标准浏览器通过getAttribute获取都应该是字符串的,IE67你getAttriute是各种奇葩,你获取的style是一整个样式对象,IE67要获取行内样式要用 eDiv.style.cssText 才行哦

兼容

在IE6中执行会变成这样:

, 而且这个特性在IE11模拟IE5,IE6一点效果都没有;

小技巧为了让IE6支持HTML5的标签可以自己创建html5标签,而且你可以给这些标签自定义样式:

兼容
<style>
nav{
  width:100px;
  height:100px;
  background:#f00;
  display:block;
}
</style>
<nav>nav</nav>
<footer>footer</footer>
<script type="text/javascript"&gt;
  window.l = (function() {
    var el = document.createElement("div"),index = 0;
    el.style.cssText = "padding:10px;position:fixed;top:0;right:0;width:10%;border:1px solid #f00;";
    return function(message) {
      message = message.toString();
      if( message ) {
        var span = document.createElement("span");
        span.innerHTML = (++index) + "信息:<br>"+ message+"<br>";
        el.appendChild( span );
      };
      //IE低版本直接通过createElement创建的元素有parentNode;
      if( !el.parentNode || (el.parentNode.toString() === "[object]") ) {
        document.body.appendChild(el);
      };
      return l;
    };
  })();
</script>

<script type="text/javascript"&gt;
l(document.createElement("nav").cloneNode( true ).outerHTML);
</script>

$.support.boxModel

这个玩意儿 document.compatMode === “‘BackCompat'” 是为了让我们知道当前的文档模式是否是标准的文档模式,还是有用的;

$.support.submitBubbles,$.support.changeBubbles,$.support.focusinBubbles

除了火狐以外所有的浏览器都支持focusin和focusout, 这两个事件和focus和blur的区别是, focus和blur并不会发生冒泡,focusin和focusout会冒泡, 我们可以通过focusin和focusout实现事件代理, 例子:

focus(in|out) not implemented

Please click on input above to change element color.
Konqueror 4.7: only DOMFocus

虽然就只有firefox不支持focusin, 但是support.focusinBubbles在ff,chrome,以及IE11中的值都为

false

, 也就是说jQuery把他们都统一起来,通过

focus

blur

的的自定义代理模拟

focusin

focusout

因为ie6-ie10中都支持attachEvent方法,所以focusinBubble都为true, IE11不支持attachEvent,所以

focusinBubble

false

了;

submitBubbles

changeBubbles

在IE8以下的浏览器中都是false;

结果的确有点乱, 在后面的事件系统中不支持事件冒泡是要做特殊处理的,下面这个代码从jQ中切出来( ̄_, ̄ )的代码

兼容
<script type="text/javascript"&gt;
var support = {
  submitBubbles: true,changeBubbles: true,focusinBubbles: false
};

var div = document.createElement("div");
if ( div.attachEvent ) {
  for ( i in {
    submit: true,change: true,focusin: true
  }) {
    eventName = "on" + i;
    isSupported = ( eventName in div );
    if ( !isSupported ) {
      div.setAttribute( eventName,"return;" );
      isSupported = ( typeof div[ eventName ] === "function" );
    };
    support[ i + "Bubbles" ] = isSupported;
  };
};
l( JSON.stringify(support) );

</script>

$.support.deleteExpando

因为IE6和IE7下的DOM元素是COM组件,delete删除COM组件的属性会报错,所以有了deleteExpando这个玩意儿,DEMO

兼容
<script type="text/javascript"&gt;
  var container = document.createElement("div");
  var div = document.createElement("div");
  var isSupported;
  var body = document.getElementsByTagName("body")[0];
  body.insertBefore( container,body.firstChild );

  container.appendChild( div );
  div.innerHTML = "<table&gt;<tr&gt;<td&gt;</td&gt;<td&gt;t</td&gt;</tr&gt;</table&gt;";
  tds = div.getElementsByTagName("td");
  tds[0].style.cssText = "padding:0;margin:0;border:0;display:none";
  isSupported = (tds[0].offsetHeight === 0);

  tds[0].style.display = "";
  tds[1].style.display = "none";
  isSupported = isSupported && ( tds[ 0 ].offsetHeight === 0 );
  l( isSupported );
</script>

$.support.BoxSizing,$.support.doesNotIncludeMarginInBodyOffset

IE8中是支持Box-sizing的,IE6,IE7通过开启怪异模式也是支持BoxSizing的;doesNotIncludeMarginInBodyOffset很不常用, 一般的offsetLeft或者offsetTop是从边框外开始计算的,也就是包含了margin, 但是因为body这个元素的特殊性质,body的offsetTop和offsetLeft并不包含margin,而且body一般有一个默认8px的marign, 导致计算位置的时候会产生混乱, so, jQ把他们统一起来了,doesNotIncludeMarginInBodyOffset这个在任何浏览器中都未true,(哎,放心了,我的小心肝都快碎了);

兼容
<script type="text/javascript"&gt;

  var div = document.createElement("div");
  var body = document.getElementsByTagName("body")[0];
  var support = {};
  body.insertBefore( div,body.firstChild );

  div.innerHTML = "";
  div.style.cssText = "<a href="/tag/Box/" target="_blank" class="keywords">Box</a>-sizing:border-<a href="/tag/Box/" target="_blank" class="keywords">Box</a>;-moz-<a href="/tag/Box/" target="_blank" class="keywords">Box</a>-sizing:border-<a href="/tag/Box/" target="_blank" class="keywords">Box</a>;-webkit-<a href="/tag/Box/" target="_blank" class="keywords">Box</a>-sizing:border-<a href="/tag/Box/" target="_blank" class="keywords">Box</a>;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
  support.<a href="/tag/Box/" target="_blank" class="keywords">Box</a>Sizing = ( div.offsetWidth === 4 );
  support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );

  l( support.<a href="/tag/Box/" target="_blank" class="keywords">Box</a>Sizing );
  l( support.doesNotIncludeMarginInBodyOffset );
</script>

$.support.pixelPosition,$.support.BoxSizingReliable,$.support.reliableMarginRight

piexelPosition是指当你给一个元素设置百分比的宽度或者高度的时候, 通过getComputedStye标准浏览器都要返回像素的宽高, 有些浏览器返回的还是百分比的宽高, 这个bug应该是低版本的chrome或者ff才有的bug, IE(<=IE10)通过currentStyle获取的宽高返回的还是百分比的宽高,要获取像素宽高需要hack…..,我想静静….;

BoxSizingReliable这个也是再次验证盒模型是否支持, 不知道有什么用;

reliableMarginRight是指低版本chrome获取不到marginRight的问题,jQuery真是操碎了心;

兼容
<div id="shrinkWrapBlocks" style="width: 1px; zoom: 1;"&gt; 
  <div style="width: 4px;"&gt; 
  </div> 
</div> 

<script type="text/javascript"&gt; 
  var div = document.getElementById('shrinkWrapBlocks'),inner = div.getElementsByTagName('div')[0]; 
  l(div.offsetWidth); 
</script>

通过直接调用jQuery.support来检测某些功能,通过查看其源代码我们可以更深入的了解各个浏览器之间的区别。特别是针对IE,还有webkit的bug,都能让我们受益匪浅。本文内容到此就结束了,希望对大家学习jQuery有所帮助。

猜你在找的JavaScript相关文章