【js】设置页面document事件导致子元素事件失效的原因及解决方式(阻止事件冒泡)

现在我们有这样一个需求:有一个按钮,我们点击它的时候屏幕上会出现一个div,而当我们点击屏幕任意空白处的时候,div消失。
点击空白处消失,这个需求应用还是比较广泛的,但是实施起来却不是那么顺利。
html:

    <button>出现</button>
    <div></div>

css:

div{
        display: none;
        width:100px;
        height:100px;
        background: pink;
  }

1、我们来为按钮添加一个点击事件,可以顺利执行,点击后div出现。

        var btn=document.getElementsByTagName("button")[0];
        var div=document.getElementsByTagName("div")[0];
        btn.onclick = function () {
            div.style.display="block";
        }
点击出现按钮后

2、我们为document添加点击事件,使div消失。

        document.onclick = function () {
            div.style.display="none";
        }
点击出现按钮后

这个时候我们发现我们的btn的点击事件居然失效了,怎么点都出不来。

这涉及到一个问题——事件冒泡

在JS中,当一个元素接收到事件,会把接收到的事件一次传给它的父元素,直到window。
刚刚我们点击按钮,却传到了它的父元素,如body,所以默认就执行了我们document的点击事件,导致div一直是消失状态。我们要做的就是阻止事件冒泡

3、解决方案:阻止事件冒泡

在事件函数内获取事件,并添加stopPropagation方法:

        btn.onclick = function (ev) {
            div.style.display="block";
            var ev = window.event||ev;  //ev传入参数并且放在这里是为了兼容低版本火狐浏览器,其它使用window.event即可,为兼容全部写入。
            ev.stopPropagation();
        }
点击出现按钮后

点击空白后

我们的代码可以正常运行了,但是stopPropagation方法在低版本ie是不兼容的(本人测试ie8不兼容),为兼容,我们使用ie专有的cancelBubble=true的方法。
兼容ie8:

        btn.onclick = function (ev) {
            div.style.display="block";
            var ev = window.event||ev;  //ev传入参数并且放在这里是为了兼容低版本火狐浏览器,其它使用window.event即可,为兼容全部写入。
            ev.cancelBubble=true;
        }

全部兼容,可使用一个三目运算符判断使用:

        btn.onclick = function (ev) {
            div.style.display="block";
            var ev = window.event||ev;
            ev.stopPropagation? ev.stopPropagation():ev.cancelBubble=true;
        }

这样就可以完美运行啦,按钮事件不会再传递到父元素了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。