Javascript Framework Design-browser sniffing and Feature Detection
Browser sniffing is no longer recommended, but it is still needed in some cases. For example, some statistics scripts. In the standard browser, document. implementation. hasfeature is provided. Unfortunately, there are bugs and inaccuracies. At present, w3c has released the CSS. supports Method to show everyone's attention to this part.
1. Determine the browser.
Mainstream browsers include ie firefox opera chorme safari. In the early days, these frameworks were determined by navigator. userAgent. Currently, almost all foreign browsers can be determined.
About the browser judgment script, jQuery has been removed from the ontology to form a plug-in. More methods are not described,
Determine mobile devices. We recommend that you check the source code of jQuery mobile and zepto.
The Code is as follows:
IsIPone =/isIPone/I. test (navigator. userAgent );
IsIPone4 = window. devicePixelRatio> = 2 // on the webpage, the pixel-to-point ratio is called device-pixel-ratio. The average device is 1, the iPhone 4 is 2, and some Android models are 1.5.
IsIpad =/ipad/I. test (navigator. userAgent)
IsAndroid =/android/I. test (navigator. userAgent)
IsIOS = isIPone | isIpad
Domestic browsers can see Tangrame or qwrap, which are basically IE, webkit, and blink kernels.
2. event support Detection
Kangax, a core member of prototype, wrote an article to determine the browser's support for certain events. The implementation is as follows:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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; })(); |
Currently, jQuery and other frameworks all use a simplified version of scripts.
But which one is good? This kind of detection only works for DOM0, like DOMMouseScroll DOMContentLoaded DOMFocusIn DOMFocusOut ?domnodeinserted DOMNodeRemoved ==domattrmodified starting with DOM.
Some of these events are very useful, such as DOMMouseScroll. firefox does not support mousesheel and can only be used as a substitute.
DOMContentLoaded is an important event for implementing domReady. DOMNodeRemoved is used to determine whether an element is removed from its parent node. The parent node may be another element node or File Fragment. DOMNodeRemovedFromDocument is removed from the DOM tree, DOMAttrModified used to simulate the onpropertyChange of IE
Css3 adds two types of animations: transition animation and keyframe compensation animation. They all use Event Callback at the end of an event. However, in the standardization process, the name given by the browser is equivalent to no rule. This also needs to be detected in advance.
The following is the implementation of bootstrap. It is said that the source is modernizr, Which is rough. For example, the Oprera you are using does not contain the standard event name of the event. It still returns oTransitionEnd.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$. Supports. transition = (function (){ Var transitionEnd = (function (){ Var el = document. createElement ('bootstarp '), TransEndEventNames = { 'Webkittransition ': 'webkittransitionend ', 'Upload upload': 'deletionend ', 'Otransition ': 'otransitionend otransitionend ', 'Transition ': 'transitionend' }; For (var name in transEndEventNames ){ If (el. style [name]! = Undefined ){ Return transEndEventNames [name] } } }()); Return transitionEnd &&{ End: transitionEnd } })(); |
The keyframe compensation animation comes from the fx_neo module of mass.
?
1 2 3 4 5 6 7 8 9 10 |
Var eventName = { AnimationEvent: 'animationend ', WebKirAnimationEvent: 'webkiranimationend' }, Animationend; For (var name in eventName ){ If (/object | function/. test (typeof window [name]) { Animationend = eventName [name] Break } } |
3. Support for style Detection
Css3 brings a lot of useful styles, but the trouble is that every browser has its own private prefix. massFramework provides a cssName method to process them and returns the available camper style names, null if no
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Var prefixes = ['', '-webkit-', '-o-', '-moz-', '-ms-']; Var cssMap = { "Float": $.support.css Float? 'Cssfloat': 'stylefloat', background: 'backgroundcolor' }; Function cssName (name, host, camelCase ){ If (cssMap [name]) { Return cssMap [name]; } Host = host | document.doc umentElement 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 } |
A style has N style values, for example, display has n values. It is very troublesome to detect whether the browser supports one. To this end, the browser makes a good offer and provides a css. supports API. If not, try the next open-source project. Obviously, it is not perfect.
Https://github.com/termi/CSS.supports
4. Meanings of some common features of jQuery
JQuery provides some common DOM feature support examples in the support module. However, the names are very strange and vary greatly in different versions. In this chapter, jQuery1.8 prevails.
LeadingWhitespace: determines whether the trimLeft operation exists when the browser assigns an innerHTML value. This function was originally invented by IE. As a result, other browsers believe that they should be loyal to the original value, the leading blank cannot be omitted. to change to a text node, IE678 returns false, and other browsers return true.
Tobody: indicates whether the browser will automatically add the tobody to the table when an element is dynamically created using innerHTML. jQuery wants the browser not to process it, so that jQuery can complete it. Determines whether the browser can only insert tobody. In the age of table layout, this feature is very useful. If no tbody exists, the table is displayed only when the browser parses the closed tag. If the start tag and the closed tag are far apart, in other words, this table is very long and you will not see anything, but with tbody segmentation display and recognition, this avoids the situation that is immediately displayed after a long blank space.
The Code is as follows:
Var div = document. createElement ("div ");
Div. innerHTML = '<table> </table>'
Alert (div. innerHTML) // => ie678 returns <table> <tbody> </table>, other returns <table> </table>
Html. Serialize: Determine whether the browser is in good condition. You can use innerHTML to convert a string that complies with the html Tag rules into an element node. In this process, jQuery is called serialization, but IE is not well supported. Conversion of no-scope elements, including scirpt link style mata, fails.
Style: this name is hard to understand. It doesn't look at the code and doesn't know what it means. It's like determining whether getAttribute returns the default value of style. IE678 does not return feature differentiation, and returns a CSSStyleDeclaration object.
HrefNormalized: determines whether getAttribute can return the user preset value of href. IE will provide you with the complete path
Opacity: determines whether the browser supports the opacity attribute. For ie678, use a filter.
CssFloat: Specifies the name of the float style in the DOM. W3c indicates cssFloat, and IE678 indicates styleFloat.
CheckOn: In most browsers, the value of checkBox is on, and chorme returns an empty string.
OptSelected: determines whether the seleted that dynamically adds the option element is obtained correctly. ie6-10 and older versions of safari do not set dynamic add option to true. Solution: before accessing the selected Attribute, access the selectedIndex attribute of the parent node, and then forcibly calculate the seleted of the option.
?
1 2 3 4 5 6 7 8 9 |
<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: determines whether the disable attribute of the select element affects the disabled value of the sub-element. In safari, once the select element is disabled, its sub-element is also disabled, causing a value to be lost.
CheckClone: indicates a checkbox element. If checked is set to true and Its Replica can be kept as true after multiple clones. This method only returns false in safari4, and all others are true.
InlineBlockNeedsLayout: determines whether to use the hasLayout Method for dispaly: inline-block to take effect. This method is only true for ie678.
GetSetAttribute: determines whether to differentiate feature attributes. Only ie678 is false.
NoCloneEvent: determines whether to clone the attachEvent binding event when cloning an element. Only the earlier version of ie and its compatibility mode will return false
Enctype: determines whether the browser supports the encoding attribute. ie67 uses the encoding attribute instead.
BoxModel: determines whether the browser is in content-box rendering mode.
SubmitBubbles, changeBubbles, and focusinBubble: determines whether the browser supports these events and bubbles until the document
ShrinkWrapBlocks: determines whether the quilt element is opened. In IE678, when the size and hasLayout of Non-replaceable elements are set, the parent-level elements are extended.
Html5Clone: determine whether to use cloneNode to clone the HTML5 new tag. The old version of IE does not support it. OuterHTML is required
DeleteExpando: determines whether a custom element on an element node can be deleted, which is used by the jQuery cache system. Earlier versions of IE do not support undefined.
PixelPosition: determines whether getComputedStyle can convert the percentage of the top left bottom right element of an element. This problem may occur in the webkit system and requires the hack of Dean Edwards.
ReliableMarginRight: determines whether getComputedStyle can correctly obtain the marginRiht of an element.
ClearCloneStyle: ie9 10 may have a strange bug. When an element's background-* style element is copied and the copied element is cleared, the original style is cleared.
With the version update of the browser, various bugs caused by the standard browser have exceeded IE, and feature detection is becoming more and more important.
The above is all the content of this article. I hope you will like it.