JS包容全数浏览器的DOMContentLoaded事件

2019-07-28 03:08栏目:ca888圈内

//保存domReady的事件队列
eventQueue = [];

(13).function doScroll(){},此函数可以使用利用定时器函数不断的调用doScroll()函数,如果报错,则继续调用,否则的话,也就是dom结构加载完毕,于是就执行相关函数。

JavaScript常用脚本汇总(一),javascript脚本汇总

jquery限制文本框只能输入数字

jquery限制文本框只能输入数字,兼容IE、chrome、FF(表现效果不一样),示例代码如下:

复制代码 代码如下:
$("input").keyup(function(){ //keyup事件处理
   $(this).val($(this).val().replace(/D|^0/g,''));
}).bind("paste",function(){ //CTR V事件处理
   $(this).val($(this).val().replace(/D|^0/g,''));
}).css("ime-mode", "disabled"); //CSS设置输入法不可用

上面的代码的作用是:只能输入大于0的正整数。

复制代码 代码如下:
$("#rnumber").keyup(function(){ 
        $(this).val($(this).val().replace(/[^0-9.]/g,'')); 
    }).bind("paste",function(){  //CTR V事件处理 
        $(this).val($(this).val().replace(/[^0-9.]/g,''));  
    }).css("ime-mode", "disabled"); //CSS设置输入法不可用

上面代码的作用是:只能输入0-9的数字和小数点。

封装DOMContentLoaded事件

复制代码 代码如下:
//保存domReady的事件队列
    eventQueue = [];
    //判断DOM是否加载完毕
    isReady = false;
    //判断DOMReady是否绑定
    isBind = false;
    /*执行domReady()
     *
     *@param    {function}
     *@execute  将事件处理程序压入事件队列,并绑定DOMContentLoaded
     *          如果DOM加载已经完成,则立即执行
     *@caller
     */
    function domReady(fn){
        if (isReady) {
            fn.call(window);
        }
        else{
            eventQueue.push(fn);
        };
        bindReady();
    };
    /*domReady事件绑定
     *
     *@param    null
     *@execute  现代浏览器通过addEvListener绑定DOMContentLoaded,包括ie9
     ie6-8通过判断doScroll判断DOM是否加载完毕
     *@caller   domReady()
     */
    function bindReady(){
        if (isReady) return;
        if (isBind) return;
        isBind = true;
        if (window.addEventListener) {
            document.addEventListener('DOMContentLoaded',execFn,false);
        }
        else if (window.attachEvent) {
            doScroll();
        };
    };
    /*doScroll判断ie6-8的DOM是否加载完成
     *
     *@param    null
     *@execute  doScroll判断DOM是否加载完成
     *@caller   bindReady()
     */
    function doScroll(){
        try{
            document.documentElement.doScroll('left');
        }
        catch(error){
            return setTimeout(doScroll,20);
        };
        execFn();
    };
    /*执行事件队列
     *
     *@param    null
     *@execute  循环执行队列中的事件处理程序
     *@caller   bindReady()
     */
    function execFn(){
        if (!isReady) {
            isReady = true;
            for (var i = 0; i < eventQueue.length; i ) {
                eventQueue[i].call(window);
            };
            eventQueue = [];
        };
    };
    //js文件1
    domReady(function(){
    });
    //js文件2
    domReady(function(){
    });
    //注意,如果是异步加载的js就不要绑定domReady方法,不然函数不会执行,
    //因为异步加载的js下载之前,DOMContentLoaded已经触发,addEventListener执行时已经监听不到了

用原生JS对AJAX做简单封装

首先,我们需要xhr对象。这对我们来说不难,封装成一个函数。

复制代码 代码如下:
var createAjax = function() {
    var xhr = null;
    try {
        //IE系列浏览器
        xhr = new ActiveXObject("microsoft.xmlhttp");
    } catch (e1) {
        try {
            //非IE浏览器
            xhr = new XMLHttpRequest();
        } catch (e2) {
            window.alert("您的浏览器不支持ajax,请更换!");
        }
    }
    return xhr;
};   

然后,我们来写核心函数。

复制代码 代码如下:
var ajax = function(conf) {
    // 初始化
    //type参数,可选
    var type = conf.type;
    //url参数,必填
    var url = conf.url;
    //data参数可选,只有在post请求时需要
    var data = conf.data;
    //datatype参数可选   
    var dataType = conf.dataType;
    //回调函数可选
    var success = conf.success;
    if (type == null){
        //type参数可选,默认为get
        type = "get";
    }
    if (dataType == null){
        //dataType参数可选,默认为text
        dataType = "text";
    }
    // 创建ajax引擎对象
    var xhr = createAjax();
    // 打开
    xhr.open(type, url, true);
    // 发送
    if (type == "GET" || type == "get") {
        xhr.send(null);
    } else if (type == "POST" || type == "post") {
        xhr.setRequestHeader("content-type",
                    "application/x-www-form-urlencoded");
        xhr.send(data);
    }
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            if(dataType == "text"||dataType=="TEXT") {
                if (success != null){
                    //普通文本
                    success(xhr.responseText);
                }
            }else if(dataType=="xml"||dataType=="XML") {
                if (success != null){
                    //接收xml文档   
                    success(xhr.responseXML);
                } 
            }else if(dataType=="json"||dataType=="JSON") {
                if (success != null){
                    //将json字符串转换为js对象 
                    success(eval("(" xhr.responseText ")"));
                }
            }
        }
    };
};      

最后,说明一下此函数的用法。

复制代码 代码如下:
    ajax({
        type:"post",
        url:"test.jsp",
        data:"name=dipoo&info=good",
        dataType:"json",
        success:function(data){
            alert(data.name);
        }
    }); 

跨域请求之JSONP

复制代码 代码如下:
/**
 * JavaScript JSONP Library v0.3
 * Copyright (c) 2011 snandy
 * QQ群: 34580561
 * Date: 2011-04-26
 *
 * 增加对请求失败的处理,虽然这个功能用处不太大,但研究了各个浏览器下script的差异性
 * 1, IE6/7/8 支持script的onreadystatechange事件
 * 2, IE9/10 支持script的onload和onreadystatechange事件
 * 3, Firefox/Safari/Chrome/Opera支持script的onload事件
 * 4, IE6/7/8/Opera 不支持script的onerror事件; IE9/10/Firefox/Safari/Chrome支持
 * 5, Opera虽然不支持onreadystatechange事件,但其具有readyState属性.这点甚是神奇
 * 6, 用IE9和IETester测试IE6/7/8,其readyState总为loading,loaded。没出现过complete。
 *
 * 最后的实现思路:
 * 1, IE9/Firefox/Safari/Chrome 成功回调使用onload事件,错误回调使用onerror事件
 * 2, Opera 成功回调也使用onload事件(它压根不支持onreadystatechange),由于其不支持onerror,这里使用了延迟处理。
 *    即等待与成功回调success,success后标志位done置为true。failure则不会执行,否则执行。
 *    这里延迟的时间取值很有技巧,之前取2秒,在公司测试没问题。但回家用3G无线网络后发现即使所引用的js文件存在,但由于
 *    网速过慢,failure还是先执行了,后执行了success。所以这里取5秒是比较合理的。当然也不是绝对的。
 * 3, IE6/7/8 成功回调使用onreadystatechange事件,错误回调几乎是很难实现的。也是最有技术含量的。
 *    参考了
 *    使用nextSibling,发现不能实现。
 *    令人恶心的是,即使请求的资源文件不存在。它的readyState也会经历“loaded”状态。这样你就没法区分请求成功或失败。
 *    怕它了,最后使用前后台一起协调的机制解决最后的这个难题。无论请求成功或失败都让其调用callback(true)。
 *    此时已经将区别成功与失败的逻辑放到了callback中,如果后台没有返回jsonp则调用failure,否则调用success。
 *   
 *
 * 接口
 * Sjax.load(url, {
 *    data      // 请求参数 (键值对字符串或js对象)
 *    success   // 请求成功回调函数
 *    failure   // 请求失败回调函数
 *    scope     // 回调函数执行上下文
 *    timestamp // 是否加时间戳
 * });
 *
 */
Sjax =
function(win){
    var ie678 = !-[1,],
        opera = win.opera,
        doc = win.document,
        head = doc.getElementsByTagName('head')[0],
        timeout = 3000,
        done = false;
    function _serialize(obj){
        var a = [], key, val;
        for(key in obj){
            val = obj[key];
            if(val.constructor == Array){
                for(var i=0,len=val.length;i<len;i ){
                    a.push(key '=' encodeURIComponent(val[i]));
                }
            }else{
                a.push(key '=' encodeURIComponent(val));
            }
        }
        return a.join('&');
    }
    function request(url,opt){
        function fn(){}
        var opt = opt || {},
        data = opt.data,
        success = opt.success || fn,
        failure = opt.failure || fn,
        scope = opt.scope || win,
        timestamp = opt.timestamp;
        if(data && typeof data == 'object'){
            data = _serialize(data);
        }      
        var script = doc.createElement('script');
        function callback(isSucc){
            if(isSucc){
                if(typeof jsonp != 'undefined'){// 赋值右边的jsonp必须是后台返回的,此变量为全局变量
                    done = true;
                    success.call(scope, jsonp);
                }else{
                    failure.call(scope);
                    //alert('warning: jsonp did not return.');
                }
            }else{
                failure.call(scope);
            }
            // Handle memory leak in IE
            script.onload = script.onerror = script.onreadystatechange = null;
            jsonp = undefined;
            if( head && script.parentNode ){
                head.removeChild(script);
            }
        }
        function fixOnerror(){
            setTimeout(function(){
                if(!done){
                    callback();
                }
            }, timeout);
        }
        if(ie678){
            script.onreadystatechange = function(){
                var readyState = this.readyState;
                if(!done && (readyState == 'loaded' || readyState == 'complete')){
                    callback(true);
                }
            }
            //fixOnerror();
        }else{
            script.onload = function(){
                callback(true);
            }
            script.onerror = function(){
                callback();
            }
            if(opera){
                fixOnerror();
            }
        }
        if(data){
            url = '?' data;
        }
        if(timestamp){
            if(data){
                url = '&ts=';
            }else{
                url = '?ts='
            }
            url = (new Date).getTime();
        }
        script.src = url;
        head.insertBefore(script, head.firstChild);
    }
    return {load:request};
}(this);

调用方式如下:

复制代码 代码如下:
 Sjax.load('jsonp66.js', {
        success : function(){alert(jsonp.name)},
        failure : function(){alert('error');}
  }); 

千分位格式化

复制代码 代码如下:
function toThousands(num) {
    var num = (num || 0).toString(), result = '';
    while (num.length > 3) {
        result = ',' num.slice(-3) result;
        num = num.slice(0, num.length - 3);
    }
    if (num) { result = num result; }
    return result;

以上就是本文给大家分享的javascript常用脚本了,希望大家能够喜欢。

jquery限制文本框只能输入数字 jquery限制文本框只能输入数字,兼容IE、chrome、FF(表现效果不...

//js文件1
domReady(function(){
    ...
});
//js文件2
domReady(function(){
    ...
});

低版本IE浏览器特有的doScroll方法,当dom结构没有加载完成时,调用此方法会报错,于是可以通过定时器函数不断的调用此方法,并结合try catch语句来实现判断功能,代码如下:

//判断DOM是否加载完毕
isReady = false;

代码实现了兼容所有浏览器的DOMContentLoaded效果,下面介绍一下它的实现过程。

/*domReady事件绑定
 *
 *@param    null
 *@execute  现代浏览器通过addEvListener绑定DOMContentLoaded,包括ie9
            ie6-8通过判断doScroll判断DOM是否加载完毕
 *@caller   domReady()
 */
function bindReady(){
    if (isReady) return;
    if (isBind) return;
    isBind = true;

eventQueue = [];
isReady = false;
isBind = false;
function domReady(fn){
 if(isReady){
  fn.call(window);
 }
 else{
  eventQueue.push(fn);
 };
 bindReady();
};
function bindReady(){
 if(isReady) return;
  if(isBind) return;
  isBind=true;
  if(window.addEventListener){
   document.addEventListener('DOMContentLoaded',execFn,false);
  }
  else if(window.attachEvent){
   doScroll();
  };
};
function doScroll(){
 try{
  document.documentElement.doScroll('left');
 }
 catch(error){
  return setTimeout(doScroll,20);
 };
 execFn();
};
function execFn(){
 if(!isReady){
  isReady=true;
  for(var index=0;i<eventQueue.length;index  ){
   eventQueue[index].call(window);
  };
  eventQueue = [];
 };
};
domReady(function(){
 //code
});
domReady(function(){
 //code
});

很多js框架都有个document.ready的功能,像JQuery的$(document).ready()方法,可以在DOM加载完就立即执行js代码,让图片自个慢慢加载吧。

您可能感兴趣的文章:

  • JS中获取 DOM 元素的绝对位置实例详解
  • jQuery中图片展示插件highslide.js的简单dom
  • JS实现访问DOM对象指定节点的方法示例
  • JS实现DOM删除节点操作示例
  • JS实现的DOM插入节点操作示例
  • JS遍历DOM文档树的方法实例详解
  • js中DOM事件绑定分析
  • AngularJS对动态增加的DOM实现ng-keyup事件示例
  • 原生JS实现循环Nodelist Dom列表的4种方式示例
  • 学习JS中的DOM节点以及操作

资料上说ie6~8可以使用document.onreadystatechange事件监听document.readyState状态是否等于complete来判断DOM是否加载完毕,如果页面中嵌有iframe的话,ie6~8的document.readyState会等到iframe中的所有资源加载完才会变成complete,此时iframe变成了耗时大户。但是经过测试,即使页面中没有iframe,当readyState等于complete时,实际触发的是onload事件而不是DOMContentLoaded事件,对这点表示惊奇。

(4).function domReady(fn){},此函数实现了等dom加载完毕再去执行fn函数的功能。

//注意,如果是异步加载的js就不要绑定domReady方法,不然函数不会执行,
//因为异步加载的js下载之前,DOMContentLoaded已经触发,addEventListener执行时已经监听不到了

但IE8和IE8以下浏览器并不支持DOMContentLoaded事件,所以还需要另辟蹊径来解决此问题。

document.ready的核心是DOMContentLoaded事件,firefox、chrome、opera、safari、ie9 都可以使用addEventListener(‘DOMContentLoaded',fn,false)进行事件绑定,而ie6~8不支持DOMContentLoaded事件,所以要针对ie6~8做兼容性处理。

(10).isBind=true,将变量的值修改为true。

您可能感兴趣的文章:

  • JS、CSS以及img对DOMContentLoaded事件的影响
  • 浅谈js中startsWith 函数不能在任何浏览器兼容的问题
  • Base64(二进制)图片编码解析及在各种浏览器的兼容性处理
  • JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
  • 微信浏览器弹出框滑动时页面跟着滑动的实现代码(兼容Android和IOS端)
  • JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
  • 浅谈解决360兼容模式浏览器的方法
  • JS兼容所有浏览器的DOMContentLoaded事件
addEventListener(‘DOMContentLoaded',fn,false)

/*执行事件队列
 *
 *@param    null
 *@execute  循环执行队列中的事件处理程序
 *@caller   bindReady()
 */
function execFn(){
    if (!isReady) {
        isReady = true;
        for (var i = 0; i < eventQueue.length; i ) {
            eventQueue[i].call(window);
        };
        eventQueue = [];
    };
};

(11).if(window.addEventListener){document.addEventListener('DOMContentLoaded',execFn,false);},如果是标准浏览器则使用addEventListener注册事件处理函数。

版权声明:本文由ca888发布于ca888圈内,转载请注明出处:JS包容全数浏览器的DOMContentLoaded事件