javascript框架设计之浏览器的嗅探和特征侦测_javascript技巧
浏览器的嗅探现在已经不推荐了,但在某些场合还是需要的。比如一些统计脚本。在标准浏览器里,提供了document.implementation.hasfeature,可惜有bug,不准确,目前,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 //在网页中,pixel与point比值称为device-pixel-ratio,普通设备都是1,iPhone4是2,有些 安卓机型是1.5
isIpad = /ipad/i.test(navigator.userAgent)
isAndroid = /android/i.test(navigator.userAgent)
isIOS = isIPone || isIpad
国内的浏览器判定可以看Tangrame或qwrap,它们基本是IE,webkit,blink内核。
2.事件的支持侦测
prototype的核心成员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奏效,像DOMMouseScroll DOMContentLoaded DOMFocusIn DOMFocusOut DOMSubtreeModified DOMNodeInserted DOMNodeRemoved DOMNodeRemovedFromDocument DOMNodeInsertedIntoDocument DOMAttrModified DOMCharactorDataModified这些以DOM开头的就无能为力了。
这些事件中,有的非常有用,如DOMMouseScroll,firefox一直不支持mousesheel,只能用它做替代品。
DOMContentLoaded是实现domReady的重要事件;DOMNodeRemoved是判定元素是否从其父节点移除,父节点可能是其它元素节点或文档碎片;DOMNodeRemovedFromDocument 是移离DOM树,DOMAttrModified 以前经常用于模拟IE的onpropertyChange
css3添加两种动画,一种是transition动画,另外一种是keyframe补间动画。它们在事件结束时都用事件回调。但在标准化过程中,浏览器给它们起的名字相当于没规则。这个也需要预先侦测出来。
下面是bootstrap的实现。听说来源于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 } })();
keyframe补间动画来自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 = '
alert(div.innerHTML) //=>ie678返回
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属性是否影响到子元素的disabled取值.在safari中,一旦select元素被disabled,它的子元素也disabled,导致一个值也取不到
checkClone:是指一个checkbox元素,如果设置了checked=true,且在多次克隆后,它的复制品能否保持为true。这个方法只有在safari4中返回false,其它的都true
inlineBlockNeedsLayout:判定是否使用hasLayout方法让dispaly:inline-block生效。这个方法只有ie678为true
getSetAttribute:判定是否区分特性属性,只有ie678为false
noCloneEvent:判定在克隆元素时是否克隆attachEvent绑定事件。只有旧版本的ie及其兼容模式返回false
enctype:判定浏览器是否支持encoding属性,ie67使用encoding属性来代替
boxModel:判定浏览器是否在content-box盒子渲染模式下
submitBubbles, changeBubbles, focusinBubble:判定浏览器是否支持这些事件,一直冒泡到document
shrinkWrapBlocks:判定元素是否会被子元素撑开。在IE678中,非替换元素在设置了大小与hasLayout的情况下,将将其父级元素撑大。
html5Clone:判定能否使用cloneNode克隆HTML5新标签 ,旧版本的IE不支持。需要用到outerHTML
deleteExpando:判定能否删除元素节点上的自定义元素,这用于jQuery缓存系统。旧版本的IE不支持,直接undefined
pixelPosition:判定getComputedStyle能否转换元素的top left bottom right元素的百分比值。这个在webkit系统会出现问题,需要用到 Dean Edwards神的hack
reliableMarginRight:判定getComputedStyle能否正确的取得元素的marginRiht.
clearCloneStyle :ie9 10 会出现奇怪的bug,当复制了一个元素的background-*样式的元素,对复制的元素进行清空时,会清空原来的样式。
随着浏览器疯狂更新版本,标准浏览器引发的各种bug已经超越IE,特征侦测不退反进,越来越重要了。
以上所述就是本文的全部内容了,希望大家能够喜欢。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务
