javascript framework designed for browser sniffing and feature detection

  • 2020-06-19 09:38:55
  • OfStack

Browser sniffing is no longer recommended, but is needed in some situations. For example, some statistics scripts. In the standard browser, document.implementation.hasfeature is provided, but bug is not accurate. At present, w3c has launched the ES7en.supports method, which shows everyone's interest in this area.

1. Determine the browser.

The mainstream browsers include ie firefox opera chorme safari. In the early days, these frameworks were judged by navigator.userAgent. At present, almost all foreign browsers can be judged.

For browser judgment scripts, jQuery has moved out of the ontology to form a plug-in. In more ways than one,

For mobile devices, see the source code of jQuery mobile and zepto for this recommendation.


    isIPone = /isIPone/i.test(navigator.userAgent);
    isIPone4 = window.devicePixelRatio >= 2 // In the web page, pixel with point The ratio is called device-pixel-ratio, Common equipment 1 . iPhone4 is 2 , some Android models are 1.5
    isIpad = /ipad/i.test(navigator.userAgent)
    isAndroid = /android/i.test(navigator.userAgent)
    isIOS = isIPone || isIpad

Domestic browsers can judge Tangrame or qwrap, they are basically IE,webkit,blink kernel.

2. Event detection support

kangax, a core member of prototype, wrote an article to determine browser support for an event. The implementation given is as follows:


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

Frameworks such as jQuery are now simplified versions using scripts

Either way, the test only works for DOM0, not for things like DOMMouseScroll DOMContentLoaded DOMFocusIn DOMFocusOut DOMSubtreeModified DOMNodeRemoved DOMAttrModified DOMCharactorDataModified.

Some of these events are very useful, such as DOMMouseScroll, firefox1 do not support mousesheel, can only be used as a substitute.
DOMContentLoaded is an important event to realize domReady. DOMNodeRemoved determines whether an element is removed from its parent, which may be other element nodes or document fragments; DOMNodeRemovedFromDocument is the move away from the DOM tree, DOMAttrModified is the onpropertyChange that was often used to simulate IE

css3 adds two kinds of animations, one is transition animation, the other is keyframe tween animation. They all use event callbacks at the end of an event. But in the standardization process, browsers give them names that amount to no rules. This also needs to be detected in advance.

Here is the implementation of bootstrap. Heard from modernizr, relatively rough. For example, Oprera, which you use, already supports standard event names without an event. Again, it returns 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
    }
  })();

keyframe tween animation is from fx_neo module of 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. Style supports detectives

css3 comes with a number of useful styles, but the trouble is that each browser has its own private prefix, and massFramework provides an cssName method to handle them, returning the available camel style name if there is one, and null if there is none


  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
  }

1 style for N style values, for example, display has n values, it can be difficult to detect if the browser supports one. To this end, the browser has done a good deed, giving one ES111en. supports API, if not, try the next open source project. Not perfect, obviously.

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

4. Meaning of some common features of jQuery

jQuery in support module examples of 1 common DOM feature support, but the name is strange, different versions are also very different, this chapter es125EN1.8 shall prevail.

leadingWhitespace: To determine whether there is an trimLeft operation in the browser when assigning innerHTML. This function was originally invented by IE. As a result, other browsers decided to stick to the original value in the future

tobody: Refers to whether the browser will automatically fill tobody in table when dynamically creating elements with innerHTML. jQuery wants the browser to leave it alone and let jQuery complete. Determine if the browser can only insert tobody. In the age of table layouts, this feature was useful. Without tbody,table is not displayed until the browser resolves to the closing tag. If the start tag and the close tag are far apart, in other words, the table is so long that the user can't see anything, but with tbody segmented display and recognition, you can avoid a long period of blank space after 1 down.


    var div = document.createElement("div");
    div.innerHTML = '<table></table>'
    alert(div.innerHTML) //=>ie678 return <table><tbody></tbody></table>, Other return <table></table>

html. Serialize: Determines whether the browser supports using innerHTML to convert a string conforming to the html tag rule to an element node. This process is called serialization, but IE support is not sound enough. The conversion of ES163en-ES164en elements including scirpt link style mata failed.

style: This name is hard to read. It's like deciding whether getAttribute returns the style user default. IE678 does not return the distinguishing feature, returning 1 CSSStyleDeclaration object.

hrefNormalized: Determines whether getAttribute can return href's user default. IE will add the full path to you

opacity: to determine whether the browser supports the opacity attribute, use a filter for ie678

cssFloat: Determine that float's style is that of DOM, W3c is cssFloat and IE678 is styleFloat

CheckOn: In most browsers checkBox's value is on and chorme returns an empty string

optSelected: Determine if seleted dynamically adds option elements correctly. ie6-10 and the old safari dynamically adds option without setting it to true. The solution is to access the selectedIndex property of the parent node before accessing the selected property, and then force the calculation of seleted for option.


<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: Determine whether the disable attribute of select element affects the disabled value of the child element. In safari, once select element is disabled, its child element is disabled, resulting in the failure of one value

checkClone: refers to an checkbox element. If checked=true is set, can its copy remain true after multiple clones? This method only returns false in safari4, and everything else is true

inlineBlockNeedsLayout: Determine whether to use the hasLayout method for dispaly: ES239en-ES240en to work. This method only has ie678 as true

getSetAttribute: Determine whether to distinguish property attributes, only ie678 is false

noCloneEvent: Determines whether the attachEvent binding event is cloned when the element is cloned. Only the older version of ie and its compatibility mode return false

enctype: Determines whether the browser supports the encoding attribute. ie67 USES the encoding attribute instead

boxModel: Determines if the browser is in content-ES264en box rendering mode

submitBubbles, changeBubbles, focusinBubble: Determine if the browser supports these events, 1 bubbles directly to document

shrinkWrapBlocks: Determines whether the element will be supported by the quilt element. In IE678, the non-substitutable element expands its parent element with the size set to hasLayout.

html5Clone: Determine if cloneNode can be used to clone the new HTML5 tag. The old VERSION of IE is not supported. You need outerHTML

deleteExpando: Determines whether custom elements on element nodes can be deleted. This is used in jQuery caching systems. Older versions of IE do not support undefined directly

pixelPosition: Determines whether getComputedStyle can convert the percentage value of the element top left bottom right. This will cause problems in THE webkit system, requiring Dean Edwards

reliableMarginRight: The marginRiht that determines whether getComputedStyle gets the element correctly.

clearCloneStyle: ie9 10 produces the odd bug, which will be emptied when the background-* style element of 1 element is copied and the copied element is emptied.

With the browser going crazy with updates, bug has surpassed IE and feature detection is becoming more and more important.

This is the end of this article, I hope you enjoy it.


Related articles: