首页 web前端 js教程 javascript框架设计之浏览器的嗅探和特征侦测_javascript技巧

javascript框架设计之浏览器的嗅探和特征侦测_javascript技巧

May 16, 2016 pm 03:53 PM
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,特征侦测不退反进,越来越重要了。

以上所述就是本文的全部内容了,希望大家能够喜欢。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

仓库:如何复兴队友
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

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

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

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

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

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

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

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

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

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

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

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

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

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

如何在JavaScript中获取HTTP状态码的简单方法 如何在JavaScript中获取HTTP状态码的简单方法 Jan 05, 2024 pm 01:37 PM

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

See all articles