一个前端博客(9)——浏览器检测和加载
浏览器检测
浏览器检测是通过JavaScript BOM的navigator对象实现的。
Navigator.userAgent W3C上:userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值
通过下面的js代码,获得浏览器版本号:
var ua = navigator.userAgent.toLowerCase();
不过这里包含一些我们不需要的信息,通过观察不同浏览器获得的ua,使用正则,将版本号取出来。不过在这儿之前我们需要为全局设置一个sys对象和一个变量s。
window.sys = {}; var s;
sys对象用于存储浏览器信息,可以直接调用查看。而变量s是用来存储正则匹配出来的数组。s[1]就是版本号。
正则这里不详细说,代码如下:
window.sys = {}; var ua = navigator.userAgent.toLowerCase(); var s; (s = ua.match(/msie([\d.]+)/)) ? sys.ie = s[1] : (s = ua.match(/firefox\/([\d.]+)/)) ? sys.firefox = s[1] : (s = ua.match(/chrome\/([\d.]+)/)) ? sys.chrome = s[1] : (s = ua.match(/opera\/.*version\/([\d.]+)/)) ? sys.opera = s[1] : (s = ua.match(/version\/([\d.]+).*safari/)) ? sys.safari = s[1] : 0;
最后还有一点就是,我们要在一开始就检测,之后不再检测。这需要我们利用IIFE(立即调用的函数表达式),来在一开始执行。
完整代码如下:
(function(){ window.sys = {}; var ua = navigator.userAgent.toLowerCase(); var s; (s = ua.match(/msie([\d.]+)/)) ? sys.ie = s[1] : (s = ua.match(/firefox\/([\d.]+)/)) ? sys.firefox = s[1] : (s = ua.match(/chrome\/([\d.]+)/)) ? sys.chrome = s[1] : (s = ua.match(/opera\/.*version\/([\d.]+)/)) ? sys.opera = s[1] : (s = ua.match(/version\/([\d.]+).*safari/)) ? sys.safari = s[1] : 0; })();
加载
我们通常会使用这种方式来加载网页:
window.onload = fuction() { //code..... }
window.onload是在dom文档树加载完和所有文件加载完之后执行一个函数,而这样会导致在长时间加载页面的情况下,js程序是不可用的状态。而js其实只需要HTML DOM
文档结构构造完毕后就可以使用了,没有必要等待注入图片音乐和外部内容加载。
不过又由于兼容性问题。所以就会有不同的方式。
对于现代非IE浏览器,通过DOMContentLoaded事件来实现。
addEvent(document,'DOMContentLoaded',function() {});
对于低版本的非IE浏览器,通过检查document, document.getElementById,document.getElementsByTagName, document.body可不可用来判断是否加载完。
对于IE9以下,通过document.documentElment.doScroll('left');如果没有加载完,则会发生异常。
综合上述:
if((sys.opera && sys.opera < 9) || (sys.firefox && sys.firefox < 3) || (sys.webkit && webkit < 525)) { timer = setInterval(function() { if(document && document.getElementById && document.getElementsByTagName && document.body) { } }, 1); }else if(document.addEventListener) { addEvent(document, 'DOMContentLoaded', function() { }); }else if(sys.ie && sys.ie < 9) { var timer = null; timer = setInterval(function() { try { document.documentElement.doScroll('left'); }catch(e){}; }, 1); }
这里我们用到了定时器,当我们加载成功后,应该执行函数,清楚定时器。把这个工作封装以下。
function doReady() { if(timer) clearInterval(timer); if(isReady) return; isReady = true; fn(); }
最后完整代码如下:
function addDomLoaded(fn) { var isReady = false; var timer = null; function doReady() { if(timer) clearInterval(timer); if(isReady) return; isReady = true; fn(); } if((sys.opera && sys.opera < 9) || (sys.firefox && sys.firefox < 3) || (sys.webkit && webkit < 525)) { timer = setInterval(function() { if(document && document.getElementById && document.getElementsByTagName && document.body) { doReady(); } }, 1); }else if(document.addEventListener) { addEvent(document, 'DOMContentLoaded', function() { fn(); removeEvent(document, 'DOMContentLoaded', arguments.callee); }); }else if(sys.ie && sys.ie < 9) { var timer = null; timer = setInterval(function() { try { document.documentElement.doScroll('left'); doReady(); }catch(e){}; }, 1); } }
这些写在了我们的工具函数tool.js文件里。下面我们来修改Tar.js
我们希望能和jQuery以下,通过这种方式来加载:
$(function(){});
我们相当于传递了一个函数。所以修改构造函数部分:
function Tar(args) { //存储节点数组 this.elements = []; if(typeof args == 'string') { //css模拟 }else if(typeof args == 'object') { }else if(typeof args == 'function') { this.ready(args); } };
判断如果参数是函数的话,直接调用ready方法。我们再写Tar的ready方法:
Tar.prototype.ready = function(fn) { addDomLoaded(fn); };
待续。。。。