惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

TaoSecurity Blog
TaoSecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Cisco Talos Blog
Cisco Talos Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
美团技术团队
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
Engineering at Meta
Engineering at Meta
人人都是产品经理
人人都是产品经理
月光博客
月光博客
T
Tor Project blog
P
Privacy & Cybersecurity Law Blog
Recorded Future
Recorded Future
I
Intezer
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
罗磊的独立博客
V
V2EX
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
A
About on SuperTechFans
Scott Helme
Scott Helme
Vercel News
Vercel News
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
B
Blog
博客园 - 叶小钗
WordPress大学
WordPress大学
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
IT之家
IT之家
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
小众软件
小众软件
博客园 - Franky
Microsoft Azure Blog
Microsoft Azure Blog
AWS News Blog
AWS News Blog

博客园 - 匆匆

Grunt常见问题 一个小型的类库 JavaScript 设计模式 HTML5常见问题 改版提示,新手指南 前端开发规范文档 常用正则表达式 JavaScript String 对象扩展方法 JavaScript String 对象常用方法 JavaScript Array 对象扩展方法 JavaScript Array 对象常用方法 JavaScript 常见基础问题二 JavaScript 常见基础问题一 JavaScript与网页性能 跨浏览器的本地存储解决方案 常用CSS书写技巧 Gridview用法大总结(牛年珍藏版) 总结一些常用功能源码 JS类库
页面中添加事件、阻止事件传播、事件删除
匆匆 · 2012-01-01 · via 博客园 - 匆匆

一、添加事件

方法一:直接将事件脚本内嵌XHTMl中(弹出‘clicked’)

<input type="button" onclick="alert('clicked');" value="click me"/>

 方法二:将事件脚本独立于函数(弹出‘clicked’)

<input type="button" onclick="clickEvent();" value="click me" />
<script type="text/javascript">
    function clickEvent() {
        alert("clicked");
    }
</script>

方法三:行为结构完全分离(弹出‘clicked again’,仅会执行最后那个绑定的事件),此方法一个元素的同一事件只允许一个处理器,仅会执行一次。

<input type="button" id="Example" value="click me" />
<script type="text/javascript">
    var btn = document.getElementById("Example");
    btn.onclick = function () {
        alert("clicked");
    };
    btn.onclick = function () {
        alert("clicked again");
    };
</script>

方法四:监听事件(IE6,IE7,IE8,依次弹出‘clicked again’、‘clicked’,其他浏览器,依次弹出‘clicked’、‘clicked again’),原因是W3C标准的addEventListener方法执行事件的顺序是按照事件注册的顺序执行的。而IE的attachEvent方法则相反,后注册的事件先觖发,先注册的事件后触发。

<input type="button" id="Example" value="click me" />
<script type="text/javascript">
    function addEvent(eventTarget, eventType, evrntHandler) {
        if (eventTarget.addEventListener) {
            eventTarget.addEventListener(eventType, evrntHandler, false);
        }
        else if (eventTarget.attachEvent) {
            eventType = "on" + eventType;
            eventTarget.attachEvent(eventType, evrntHandler)
        }
        else { eventTarget["on" + eventType] = evrntHandler; }
    }
    var btn = document.getElementById("Example");
    addEvent(btn, "click", function () {
        alert("clicked");
    });
    addEvent(btn, "click", function () {
        alert("clicked again");
    });
</script>

 综上,在添加事件中,方法四是最佳选择。

二、阻止事件冒泡

事件在嵌套函数中会传播,在以下代码中,点击inner,依次弹出‘inner’、‘middle’、‘out’,点击middle,依次弹出‘middle’、‘out’,点击out,弹出‘out。addEventListener(event,function,capture/bubble)函数的第三个参数: true表示在捕获阶段,false表示在冒泡阶段。为了兼容IE的事件处理,所以设置为false,如果第三个参数设置为true,在标准浏览器中,点击inner,依次弹出‘out’、‘middle’、‘inner’。

<script type="text/javascript">
    function addEvent(eventTarget, eventType, evrntHandler) {
        if (eventTarget.addEventListener) {
            eventTarget.addEventListener(eventType, evrntHandler, false);
        }
        else if (eventTarget.attachEvent) {
            eventType = "on" + eventType;
            eventTarget.attachEvent(eventType, evrntHandler)
        }
        else { eventTarget["on" + eventType] = evrntHandler; }
    }
    addEvent(window, "load", function () {
        var out = document.getElementById("out");
        var middle = document.getElementById("middle");
        var inner = document.getElementById("inner");
        addEvent(out, "click", function () { alert("out") })
        addEvent(middle, "click", function () { alert("middle") })
        addEvent(inner, "click", function () { alert("inner") })
    });
</script>
<div style="padding:20px;background:red" id="out">
    <div style="padding:20px;background:green" id="middle">
        <div style="padding:20px;background:white" id="inner">
        </div>
    </div>
</div>

如何阻止事件传播?以下代码可以解决,点击inner,弹出‘inner’,点击middle,弹出‘middle’,点击out,弹出‘out’

<script type="text/javascript">
    function addEvent(eventTarget, eventType, evrntHandler) {
        if (eventTarget.addEventListener) {
            eventTarget.addEventListener(eventType, evrntHandler, false);
        }
        else if (eventTarget.attachEvent) {
            eventType = "on" + eventType;
            eventTarget.attachEvent(eventType, evrntHandler)
        }
        else { eventTarget["on" + eventType] = evrntHandler; }
    }
    function cancelPropagation(event) {
        event = window.event || event;
        if (document.all) {
            event.cancelBubble = true;
        } else {
            event.stopPropagation();
        }
    }
    addEvent(window, "load", function () {
        var out = document.getElementById("out");
        var middle = document.getElementById("middle");
        var inner = document.getElementById("inner");
        addEvent(out, "click", function () { alert("out") })
        addEvent(middle, "click", function (evt) {
            alert("middle");
            cancelPropagation(evt);
        });
        addEvent(inner,"click",function(evt){
            alert("inner");
            cancelPropagation(evt);
        });
    });
</script>
<div style="padding:20px;background:red" id="out">
    <div style="padding:20px;background:green" id="middle">
        <div style="padding:20px;background:white" id="inner">
        </div>
    </div>
</div>

 如果想解除相应的绑定事件,我们可以用以下代码解决。

<script type="text/javascript">
    function addEvent(eventTarget, eventType, evrntHandler) {
        if (eventTarget.addEventListener) {
            eventTarget.addEventListener(eventType, evrntHandler, false);
        }
        else if (eventTarget.attachEvent) {
            eventType = "on" + eventType;
            eventTarget.attachEvent(eventType, evrntHandler)
        }
        else { eventTarget["on" + eventType] = evrntHandler; }
    }
    function removeEvent(eventTarget, eventType, evrntHandler) {
        if (eventTarget.removeEventListener) {
            eventTarget.removeEventListener(eventType, evrntHandler, false); 
        }
        else if (eventTarget.detachEvent) {
            eventType = "on" + eventType;
            eventTarget.detachEvent(eventType, evrntHandler) 
        }
        else { eventTarget["on" + eventType] = null; } 
    }
    addEvent(window, "load", function () {
        var ok = document.getElementById("ok");
        var switchBtn = document.getElementById("switchBtn");
        var flag = true;
        addEvent(switchBtn, "click", function () {
            if (flag) {
                addEvent(ok, "click", show);
                switchBtn.value = "removeEvent";
                flag = false;
            }
            else {
                removeEvent(ok, "click", show);
                switchBtn.value = "addEvent";
                flag = true; 
            }
        });
    });
    function show() {
        alert("I am here");
    }
</script>
<input type="button" value="addEvent" id="switchBtn" /><input type="button" value="Try to click me^_^" id="ok" />

三、其他区别

1、 DOM标准的addEventListener方法执行事件的顺序是按照事件注册的顺序执行的。而attachEvent方法则相反–后注册的事件先觖发,先注册的事件后触发;
2、 DOM标准的浏览器文本节点也会冒泡,而IE内核的浏览器文本节点不会冒泡;
3、 DOM标准的浏览器事件对象与IE内核的浏览器事件不同。