zoukankan      html  css  js  c++  java
  • 跨浏览器事件的其他问题(小记)

    今天来总结下在项目中事件使用的以下问题 

    *DOMContentLoaded在不同浏览器的实现

      什么是DOMContentLoaded? 它是firefox为了处理在页面DOM结构建立后(无需下载js,css,img等图片资源)绑定事件的一个方法,对于IE是没有这个方法的,但是在IE中可以模拟出这个方法来,来达到同样的目的。我们经常使用jquery的 $(document).ready(function(){});或者百度的tangram框架的时候, baidu.dom.ready(function(){})其实是对这个方法在不同浏览器中做了一个封装。

    在IE中的实现方式,我们可以参考这个文档http://javascript.nwbox.com/IEContentLoaded/ ,他的原理是:在IE下,DOM的某些方法只有在DOM解析完成后才可以调用,doScroll就是这样一个方法,当然反过来当能调用doScroll的时候即是DOM解析完成之时。下面我们来看看jquery和tangram的实现方式,来加深理解

    1)jquery

     bindReady: function() {

    if ( readyList ) {
    return;
    }
    readyList = jQuery.Callbacks( "once memory" );
    // Catch cases where $(document).ready() is called after the
    // browser event has already occurred.
    if ( document.readyState === "complete" ) {
    // Handle it asynchronously to allow scripts the opportunity to delay ready
    return setTimeout( jQuery.ready, 1 );
    }
     
    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
    // 给加载在document上去。
    document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
     
    // 确保事件真正的执行
    window.addEventListener( "load", jQuery.ready, false );
     
    // 如果是IE的事件模式
    } else if ( document.attachEvent ) {
    // ensure firing before onload,
    // 如果是是iframe的形式的话
    document.attachEvent( "onreadystatechange", DOMContentLoaded );
     
    // 确保这个函数被真正的使用了
    window.attachEvent( "onload", jQuery.ready );
     
    // 如果是IE序列的浏览器,并且不是在iframe使用
    // continually check to see if the document is ready
    var toplevel = false;
     
    try {
    toplevel = window.frameElement == null;
    } catch(e) {}
             //如果支持doScroll 并且不是在iframe的时候
    if ( document.documentElement.doScroll && toplevel ) {
    doScrollCheck();
    }
    }
    }

     // 在IE序列浏览器下,检测 DOM ready  

    function doScrollCheck() {
    if ( jQuery.isReady ) {
    return;
    }
     
    try {

    document.documentElement.doScroll("left");
    } catch(e) {
    setTimeout( doScrollCheck, 1 );
    return;
    }
     
    //执行该要执行的函数
    jQuery.ready();
    }

    在代码中我都解释了。

    2)tangram:

    (function() {
     
        var ready = baidu.dom.ready = function() {
            var readyBound = false,
                readyList = [],
                DOMContentLoaded;
     
            if (document.addEventListener) {
                DOMContentLoaded = function() {
                    document.removeEventListener('DOMContentLoaded', DOMContentLoaded, false);
                    ready();
                };
     
            } else if (document.attachEvent) {
                DOMContentLoaded = function() {
                    if (document.readyState === 'complete') {
                        document.detachEvent('onreadystatechange', DOMContentLoaded);
                        ready();
                    }
                };
            }
     
            function ready() {
                if (!ready.isReady) {
                    ready.isReady = true;
                    for (var i = 0, j = readyList.length; i < j; i++) {
                        readyList[i]();
                    }
                }
            }
     
            function doScrollCheck(){
                try {
                    document.documentElement.doScroll("left");
                } catch(e) {
                    setTimeout( doScrollCheck, 1 );
                    return;
                }   
                ready();
            }
     
            function bindReady() {
                if (readyBound) {
                    return;
                }
                readyBound = true;
     
                if (document.addEventListener) {
     
                    document.addEventListener('DOMContentLoaded', DOMContentLoaded, false);
                    window.addEventListener('load', ready, false);
     
                } else if (document.attachEvent) {
     
                    document.attachEvent('onreadystatechange', DOMContentLoaded);
                    window.attachEvent('onload', ready);
     
                    var toplevel = false;
     
                    try {
                        toplevel = window.frameElement == null;
                    } catch (e) {}
     
                    if (document.documentElement.doScroll && toplevel) {
                        doScrollCheck();
                    }
                }
            }
            bindReady();
     
            return function(callback) {
                ready.isReady ? callback() : (readyList[readyList.length] = callback);
            };
        }();
     
        ready.isReady = false;
    })();
    可以看出tangram的实现方式和jquery一样的。

    *阻止事件默认行为

    判断是否支持 preventDefault 函数,如果不支持的话,就将事件的属性returnValue 设置为false,常见的写法为
     if (event.preventDefault) {

           event.preventDefault();
     } else {
           event.returnValue = false;

    *阻止事件传播

    判断是否支持stopPropagation,如果不支持的话,就将事件的属性cancelBubble设置为true,常见的写法为 

       if (event.stopPropagation) {
           event.stopPropagation();
       } else {
           event.cancelBubble = true;

       } 

    *获取对象

    target = event.srcElement ||event.target

    *获取鼠标事件的X,Y坐标

     x = event.pageX !== 0 ?event.pageX:event.clientX +document.body.scrollLeft||document.documentElement.scrollLeft;

       y = event.pageY !== 0 ?event.pageY:event.clientY +document.body.scrollTop||document.documentElement.scrollTop;

    *获取键盘的键值

    value = event.which || event.keyCode; 

    *事件的其他属性

      事件的相关对象,处理从一个节点到其子节点中处理很方便的,标准浏览器是支持  relatedTarget ,在IE下是不一样的。

     var reltarget = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement:e.fromElement;

    *事件注意点 

       绑定事件的时候一定要搞清楚事件的对象,事件句柄,事件的触发条件

    欢迎大家拍砖。。 

  • 相关阅读:
    制作企业IT解决方案的几项训练
    Community Server 1.0 Beta安装使用记录
    SharePoint Portal Server定制之区域模板定义
    从售前工作的角度了解SharePoint产品和技术
    活动目录的应用组策略
    企业客户组织结构在售前工作中的作用
    Community Server 1.0 Beta安装使用记录(二)
    2004年钢铁行业信息化现状
    IT解决方案编写小结
    关于软件系统架构设计的一些新思想
  • 原文地址:https://www.cnblogs.com/yupeng/p/2397263.html
Copyright © 2011-2022 走看看