ホームページ > 記事 > ウェブフロントエンド > JavaScript フレームワークの設計 - ブラウザー スニッフィングと機能検出_JavaScript スキル
ブラウザのスニッフィングは推奨されなくなりましたが、状況によっては依然として必要です。たとえば、いくつかの統計スクリプトなどです。標準ブラウザでは document.implementation.hasfeature が提供されていますが、バグが多く不正確です。現在、w3c は CSS.supports メソッドを開始しており、この点に注目していることがわかります。
1. ブラウザを決定します。
主流のブラウザには ie firefox opera chorme safari があり、初期の頃はこれらのフレームワークは navigator.userAgent を通じて判定されていましたが、現在ではほとんどの海外ブラウザが判定可能です。
ブラウザの判定スクリプトに関して、jQueryをオントロジーから外しプラグイン化しました。他にも紹介方法はあります
モバイル デバイスの関連性を判断するには、jQuery mobile と zepto のソース コードを参照することをお勧めします。
国内のブラウザの場合は、基本的に 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分段显示和识别,避免了长时间空白后一下子显示出来的情况。
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 を返し、その他は trueinlineBlockNeedsLayout: hasLayout メソッドを使用して display:inline-block を有効にするかどうかを決定します。このメソッドは ie678
にのみ当てはまります
getSetAttribute: 特性属性を区別するかどうかを決定します。ie678 のみ falsenoCloneEvent: 要素を複製するときに、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を超え、機能検出の重要性がますます高まっています。
以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。