ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript フレームワークの設計 - ブラウザー スニッフィングと機能検出_JavaScript スキル

JavaScript フレームワークの設計 - ブラウザー スニッフィングと機能検出_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 15:53:301442ブラウズ

ブラウザのスニッフィングは推奨されなくなりましたが、状況によっては依然として必要です。たとえば、いくつかの統計スクリプトなどです。標準ブラウザでは document.implementation.hasfeature が提供されていますが、バグが多く不正確です。現在、w3c は CSS.supports メソッドを開始しており、この点に注目していることがわかります。

1. ブラウザを決定します。

主流のブラウザには ie firefox opera chorme safari があり、初期の頃はこれらのフレームワークは navigator.userAgent を通じて判定されていましたが、現在ではほとんどの海外ブラウザが判定可能です。

ブラウザの判定スクリプトに関して、jQueryをオントロジーから外しプラグイン化しました。他にも紹介方法はあります

モバイル デバイスの関連性を判断するには、jQuery mobile と zepto のソース コードを参照することをお勧めします。

コードをコピーします コードは次のとおりです:

isIPone = /isIPone/i.test(navigator.userAgent);
isIPone4 = window.devicePixelRatio >= 2 //Web ページでは、ピクセルとポイントの比率は、通常のデバイスは 1、iPhone4 は 2、一部の Android モデルは 1.5 と呼ばれます
。 isIpad = /ipad/i.test(navigator.userAgent)
isAndroid = /android/i.test(navigator.userAgent)
isIOS = isIPone || isIpad

国内のブラウザの場合は、基本的に IE、Webkit、Blink カーネルである Tangrame または qwrap を参照してください。

2. イベントサポート検出

プロトタイプの中心メンバーである Kangax は、特定のイベントに対するブラウザーのサポートを決定する記事を書きました。そこで与えられる実装は次のとおりです:

  var isEventSupported = (function() {
    var TAGNAMES = {
      'select':'input','change':'input',
      'submit':'form','reset':'form',
      'error':'img','load':'img','abort':'img'
    }
    function isEventSupported(eventName){
      var el = document.createElement(TAGNAMES[eventName] || 'div');
      eventName = 'on' + eventName;
      var isSupported = (eventName in el);
      if (!isSupported) {
        el.setAttribute(eventName, 'return;');
        isSupported = typeof el[eventName] == 'function';
      }
      el = null;
      return isSupported;
    }
    return isEventSupported;
  })();

現在、jQuery とその他のフレームワークは簡略化されたバージョンのスクリプトを使用しています

ただし、どちらが優れていても、この検出は DOM0 に対してのみ機能します。たとえば、DOM で始まる DOMMouseScroll DOMContentLoaded DOMFocusIn DOMFocusOut DOMSubtreeModified DOMNodeInserted DOMNodeRemovedFromDocument DOMNodeInsertedIntoDocument DOMAttrModified DOMCharactorDataModified は役に立ちません。

これらのイベントの中には、DOMMouseScroll など、非常に便利なものもあります。Firefox はマウスシェルをサポートしていないため、代替としてのみ使用できます。
DOMContentLoaded は、domReady を実装する際の重要なイベントです。DOMNodeRemoved は、他の要素ノードまたはドキュメントのフラグメントである親ノードから要素が削除されるかどうかを判断するために使用され、DOMAttrModified は、シミュレーションによく使用されます。 IE の onpropertyChange

CSS3 は 2 つのアニメーションを追加します。1 つはトランジション アニメーション、もう 1 つはキーフレーム トゥイーン アニメーションです。これらはすべて、イベントの終了時にイベント コールバックを使用します。しかし、標準化の過程でブラウザが付けた名前はほぼランダムでした。これも事前に検出する必要があります。

以下はブートストラップの実装です。 modernizr から来ているそうですが、比較的ラフです。たとえば、あなたが使用している Oprera は、イベントのない標準イベント名をすでにサポートしています。それでも oTransitionEnd を返します。

  $.supports.transition = (function(){
    var transitionEnd = (function(){
      var el = document.createElement('bootstarp'),
          transEndEventNames = {
            'WebkitTransition':'webkitTransitionEnd',
            'MozTransition':'transitionend',
            'OTransition':'OTransitionEnd otransitionend',
            'transition':'transitionend'
          };
        for (var name in transEndEventNames){
          if (el.style[name] !== undefined){
            return transEndEventNames[name]
          }
        }
    }());
    return transitionEnd && {
      end: transitionEnd
    }
  })();

キーフレーム トゥイーン アニメーションは Mass の fx_neo モジュールから取得されます

  var eventName = {
    AnimationEvent:'animationend',
    WebKirAnimationEvent: 'WebKirAnimationEnd'
  },animationend;
  for(var name in eventName) {
    if (/object|function/.test(typeof window[name])){
      animationend = eventName[name]
      break
    }
  }

3.スタイルサポート探偵

css3 は多くの便利なスタイルを提供しますが、問題は、各ブラウザーに独自のプライベート プレフィックスがあることです。massFramework は、それらを処理するための cssName メソッドを提供し、そうでない場合は、使用可能なキャメル ケース スタイル名を返します。 null である

  var prefixes = ['','-webkit-','-o-','-moz-','-ms-'];
  var cssMap = {
    "float" : $.support.cssFloat ? 'cssFloat' : 'styleFloat',background:'backgroundColor'
  };
  function cssName(name, host, camelCase){
    if(cssMap[name]) {
      return cssMap[name];
    }
    host = host || document.documentElement
    for (var i = 0 || n = prefixes.length; i < n; i++) {
      camelCase = $.String.camelize(prefixes[i] + name);
      if (camelCase in host) {
        return (cssMap[name] = camelCase)
      }
    }
    return null
  }

一个样式对于N种样式值,比如display有n种取值,如果要侦测浏览器是否支持某一种,会很麻烦。为此,浏览器做了一个善举,给出一个css.supports的API,如果不支持,则尝试下一个开源项目。显然,不是很完美。

https://github.com/termi/CSS.supports

4.jQuery的一些常用的特征的含义

jQuery在support模块例举了一些常用的DOM特征支持情况,不过名字起的很怪,不同版本差别也很大,本章以jQuery1.8为准。

leadingWhitespace:判定浏览器在进行innerHTML赋值时,是否存在trimLeft操作,这个功能原本是IE发明的,结果其他浏览器认为要忠于以后的原始值,最前面的空白不能神略掉,要变成一个文本节点,最终IE678返回false,其他浏览器返回true

tobody:指在用innerHTML动态创建元素时,浏览器是否会在table内自动补上tobody,jQuery希望浏览器别处理,让jQuery来补全。判断浏览器是否只能插入tobody。在表格布局的年代,这个特性十分受用。如果没有tbody,table会在浏览器解析到闭合标签时才显示出来。如果起始标签和闭合标签相隔很远,换言之,这个表格很长,用户会什么都看不到,但有了tbody分段显示和识别,避免了长时间空白后一下子显示出来的情况。

复制代码 代码如下:

    var div = document.createElement("div");
    div.innerHTML = 'f5d188ed2c074f8b944552db028f98a1f16b1740fad44fb09bfe928bcc527e08'
    alert(div.innerHTML) //=>ie678返回f5d188ed2c074f8b944552db028f98a192cee25da80fac49f6fb6eec5fd2c22aca745a59da05f784b8811374296574e1f16b1740fad44fb09bfe928bcc527e08,其它返回f5d188ed2c074f8b944552db028f98a1f16b1740fad44fb09bfe928bcc527e08

html.Serialize:判断浏览器是否完好支持用innerHTML转换一个符合html标签规则的字符串为一个元素节点,此过程jQuery称为序列化,但IE支持不够完好。包括scirpt link style mata在内的no-scope元素都转换失败。

style:这个命名很难看懂,不看代码不知道什么意思,真像是判定getAttribute是否返回style的用户预设值。IE678没有返回区分特性的特征,返回一个CSSStyleDeclaration对象。

hrefNormalized:判定getAttribute能否返回href的用户预设值。IE会补充给你完整的路径给你

opacity:判定浏览器是否支持opacity属性,ie678要使用滤镜

cssFloat: 判定float的样式在DOM的名字是那个,W3c为cssFloat,IE678为styleFloat

CheckOn: 在大多数浏览器中checkBox的value为on,chorme返回空字符串

optSelected: 判定是否正确取得动态添加option元素的seleted,ie6-10与老版的safari对动态添加option没有设置为true。解决办法,在访问selected属性前,先访问父节点的selectedIndex属性,再强制计算option的seleted.

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

optDisabled: select 要素の disable 属性が子要素の無効な値に影響するかどうかを決定します。Safari では、select 要素が無効になると、その子要素も無効になり、値を取得できなくなります。 >

checkClone: チェックボックス要素を参照します。checked=true が設定されている場合、複数のクローンが作成された後も、そのコピーは true のままになります。このメソッドは safari4 でのみ false を返し、その他は true

inlineBlockNeedsLayout: hasLayout メソッドを使用して display:inline-block を有効にするかどうかを決定します。このメソッドは ie678

にのみ当てはまります

getSetAttribute: 特性属性を区別するかどうかを決定します。ie678 のみ false

noCloneEvent: 要素を複製するときに、attachEvent バインディング イベントを複製するかどうかを決定します。 IE の古いバージョンとその互換モードのみが false を返します

enctype: ブラウザーがエンコーディング属性をサポートするかどうかを決定します。IE67 は代わりにエンコーディング属性を使用します。

boxModel: ブラウザーがコンテンツ ボックス ボックス レンダリング モードであるかどうかを判断します

submitBubbles、changeBubbles、focusinBubble: ブラウザがこれらのイベントをサポートしているかどうかを判断し、ドキュメントにバブルアップします

shrinkWrapBlocks: 要素が子要素によって引き伸ばされるかどうかを決定します。 IE678 では、size と hasLayout が設定されている場合、非置換要素は親要素を展開します。

html5Clone: cloneNode を使用して HTML5 の新しいタグを複製できるかどうかを決定します。IE の古いバージョンはそれをサポートしていません。 externalHTML

を使用する必要があります

deleteExpando: 要素ノードのカスタム要素を削除できるかどうかを決定します。これは jQuery キャッシュ システムで使用されます。古いバージョンの IE はサポートしておらず、直接未定義です

pixelPosition: getComputedStyle が要素の左上右下要素のパーセンテージ値を変換できるかどうかを決定します。これにより Webkit システムに問題が発生するため、Dean Edwards のハックを使用する必要があります

reliableMarginRight: getComputedStyle が要素の marginRiht を正しく取得できるかどうかを判断します。

clearCloneStyle: ie9 10で奇妙なバグが発生します。要素のbackground-*スタイル要素をコピーし、コピーした要素をクリアすると、元のスタイルがクリアされてしまいます。

ブラウザの目まぐるしいアップデートにより、標準ブラウザが引き起こす様々なバグはIEを超え、機能検出の重要性がますます高まっています。

以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。