Heim  >  Artikel  >  Web-Frontend  >  JavaScript-Framework-Design – Browser-Sniffing und Feature-Erkennung_Javascript-Kenntnisse

JavaScript-Framework-Design – Browser-Sniffing und Feature-Erkennung_Javascript-Kenntnisse

WBOY
WBOYOriginal
2016-05-16 15:53:301420Durchsuche

Browser-Sniffing wird nicht mehr empfohlen, ist aber in manchen Situationen immer noch erforderlich. Zum Beispiel einige Statistikskripte. In Standardbrowsern wird document.implementation.hasfeature bereitgestellt, es ist jedoch fehlerhaft und ungenau. Derzeit hat w3c die Methode CSS.supports gestartet, die die Aufmerksamkeit aller auf diesen Aspekt lenkt.

1. Bestimmen Sie den Browser.

Zu den Mainstream-Browsern gehört Firefox Opera Chorme Safari. Früher wurden diese Frameworks über navigator.userAgent beurteilt. Derzeit können fast alle ausländischen Browser beurteilen.

Was das Beurteilungsskript des Browsers betrifft, wurde jQuery aus der Ontologie entfernt und in ein Plug-in umgewandelt. Es gibt noch mehr Möglichkeiten, sich vorzustellen,

Zur relevanten Bestimmung mobiler Geräte empfiehlt es sich, einen Blick auf den Quellcode von jQuery Mobile und Zepto zu werfen.

Code kopieren Der Code lautet wie folgt:

isIPone = /isIPone/i.test(navigator.userAgent);
isIPone4 = window.devicePixelRatio >= 2 // Auf der Webseite wird das Verhältnis von Pixel zu Punkt als Gerätepixelverhältnis bezeichnet. Gewöhnliche Geräte sind 1, iPhone4 ist 2 und einige Android-Modelle sind 1,5
isIpad = /ipad/i.test(navigator.userAgent)
isAndroid = /android/i.test(navigator.userAgent)
isIOS = isIPone ||. isIpad

Für inländische Browser können Sie sich Tangrame oder qwrap ansehen, bei denen es sich im Wesentlichen um IE-, Webkit- und Blink-Kernel handelt.

2. Ereignisunterstützungserkennung

Kangax, ein Kernmitglied von Prototyp, hat einen Artikel geschrieben, um die Unterstützung des Browsers für bestimmte Ereignisse zu ermitteln. Die dort angegebene Implementierung lautet wie folgt:

  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;
  })();

Jetzt verwenden jQuery und andere Frameworks vereinfachte Versionen von Skripten

, aber was auch immer besser ist, diese Erkennung funktioniert nur für DOM0.

Einige dieser Ereignisse sind sehr nützlich, z. B. DOMMouseScroll. Firefox unterstützt Mousesheel nicht und kann es nur als Ersatz verwenden.
DOMContentLoaded ist ein wichtiges Ereignis bei der Implementierung von domReady. DOMNodeRemoved wird verwendet, um zu bestimmen, ob ein Element von seinem übergeordneten Knoten entfernt wird. Dabei kann es sich um andere Elementknoten oder Dokumentfragmente handeln. DOMNodeRemovedFromDocument wird häufig zur Simulation verwendet IE's onpropertyChange

CSS3 fügt zwei Animationen hinzu, eine ist eine Übergangsanimation und die andere ist eine Keyframe-Tweening-Animation. Sie alle verwenden Ereignisrückrufe am Ende des Ereignisses. Aber während des Standardisierungsprozesses waren die Namen, die Browser ihnen gaben, fast zufällig. Auch dies muss im Vorfeld erkannt werden.

Das Folgende ist die Implementierung von Bootstrap. Ich habe gehört, dass es von modernizr kommt, was relativ grob ist. Beispielsweise unterstützt die von Ihnen verwendete Oprera bereits Standard-Ereignisnamen ohne Ereignisse. Es wird immer noch oTransitionEnd.

zurückgegeben
  $.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
    }
  })();

Keyframe-Tween-Animation stammt aus dem fx_neo-Modul von Mass

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

3. Stilunterstützungsdetektiv

css3 bringt viele nützliche Stile mit, aber das Problem besteht darin, dass jeder Browser über eine CSSName-Methode verfügt, um diese zu verarbeiten. Wenn dies der Fall ist, wird der verfügbare Camel-Case-Stilname zurückgegeben sei 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: Bestimmen Sie, ob sich das Disable-Attribut des Select-Elements auf den Disabled-Wert des untergeordneten Elements auswirkt. Sobald das Select-Element in Safari deaktiviert ist, sind auch seine untergeordneten Elemente deaktiviert, was zu einem Wert führt, der nicht abgerufen werden kann

checkClone: ​​Bezieht sich auf ein Checkbox-Element, wenn „checked=true“ gesetzt ist und seine Kopien nach mehreren Klonen „true“ bleiben können. Diese Methode gibt in Safari4 nur false zurück, andere sind true

inlineBlockNeedsLayout: Bestimmen Sie, ob die hasLayout-Methode verwendet werden soll, um display:inline-block wirksam zu machen. Diese Methode gilt nur für ie678

getSetAttribute: Bestimmen Sie, ob charakteristische Attribute unterschieden werden sollen, nur ie678 ist falsch

noCloneEvent: Bestimmt, ob das attachmentEvent-Bindungsereignis beim Klonen eines Elements geklont werden soll. Nur ältere IE-Versionen und ihre Kompatibilitätsmodi geben false

zurück

enctype: Bestimmen Sie, ob der Browser das Kodierungsattribut unterstützt. IE67 verwendet stattdessen das Kodierungsattribut

boxModel: Bestimmen Sie, ob sich der Browser im Content-Box-Box-Rendering-Modus befindet

submitBubbles, changeBubbles, focusinBubble: Bestimmen Sie, ob der Browser diese Ereignisse unterstützt und sprudeln Sie zum Dokument hoch

shrinkWrapBlocks: Bestimmen Sie, ob das Element durch untergeordnete Elemente gestreckt wird. In IE678 erweitern nicht ersetzte Elemente ihre übergeordneten Elemente, wenn size und hasLayout festgelegt sind.

html5Clone: ​​​​Bestimmen Sie, ob cloneNode zum Klonen neuer HTML5-Tags verwendet werden kann. Ältere Versionen von IE unterstützen dies nicht. Es muss OuterHTML verwendet werden

deleteExpando: Bestimmt, ob das benutzerdefinierte Element auf dem Elementknoten gelöscht werden kann. Dies wird im jQuery-Caching-System verwendet. Ältere IE-Versionen unterstützen dies nicht und sind direkt undefiniert

pixelPosition: Bestimmen Sie, ob getComputedStyle den Prozentwert des Elements oben links unten rechts konvertieren kann. Dies führt zu Problemen im Webkit-System und Sie müssen den Hack von Dean Edwards verwenden

reliableMarginRight: Bestimmen Sie, ob getComputedStyle den marginRiht des Elements korrekt ermitteln kann.

clearCloneStyle: In ie9 10 tritt ein seltsamer Fehler auf. Wenn das Hintergrund-*-Stilelement eines Elements kopiert und das kopierte Element gelöscht wird, wird der ursprüngliche Stil gelöscht.

Mit den verrückten Browser-Updates haben verschiedene von Standardbrowsern verursachte Fehler den IE übertroffen, und die Funktionserkennung wird immer wichtiger.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er gefällt Ihnen allen.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn