美文网首页技术文档前端开发那些事
preventDefault,stopPropagation,r

preventDefault,stopPropagation,r

作者: 以乐之名 | 来源:发表于2017-08-31 22:41 被阅读138次

    逛帖子的时候看到道友发的前端面试题,

    preventDefault(), stopPropagation(), return false三者的区别

    这三者的使用想必大家并不陌生,但是细想之下还是有可究之处。

    preventDefault()

    阻止元素在浏览器中的默认行为

    <a id="link" href="http://wuliv.com">网站</a>
    $('#link').click(function(event){
        event.preventDefault(); // 阻止了a链接href的访问或跳转
    })
    

    stopPropagation()

    事件冒泡:当一个元素上的事件被触发时,比如鼠标点击了一个按钮,同样的事件将会在该按钮元素的所有父级/祖先元素上触发。这一个过程就被称为事件冒泡。它是由子级元素先触发,父级元素后触发,由内而外(由下往上)的一个流程。与之顺序相反的是事件捕获。

    事件捕获:父级元素先触发,子级元素后触发,在此仅做了解。

    <body>
      <div id="inner">
        <p>事件冒泡例子</p>
        <button id="btn">我要弹个框</button>
      </div>
    </div>
    
    $('#btn').click(function(event){
      event.stopPropagation(); // 阻止了事件冒泡,不会触发"#inner, body"的点击事件  
      console.log('#btn')
    })
    
    $('#inner').click(function(event){
        // #btn 阻止了冒泡,这里不会执行
        // 如果不使用stopPropagation, 当#btn点击时,这里也会执行
        console.log('#inner')
    })
    
    $('body').click(function(event){
        // #btn 阻止了冒泡,.btn点击不会影响到我
        // 如果不使用stopPropagation, 当#btn点击时,这里也会执行
        console.log('body')
    })
    
    // 使用了stopPropagation()输出
    '#btn'
    
    // 不使用stopPropagation()输出
    '#btn'
    '#inner'
    'body'
    

    stopImmediatePropagation()

    阻止对象绑定的剩余的事件处理函数方法的执行,并阻止当前事件的冒泡。
    可以理解为stopImmediatePropagation是stopPropagation的升级版,除了阻止冒泡,还能阻止结束掉当前对象未执行的其它绑定事件方法。

    jQuery中一个对象可以绑定多个事件方法,执行顺序会按照绑定的先后顺序来执行

    <body>
        <div id="inner">
            <p>stopImmediatePropagation()例子</p>
            <button id="btn">按钮</btn>
        </div>
    </body>
    
    $('body').click(function(event){
        // body 点击
        console.log('body');
    });
    
    $('#inner').click(function(event){
        // #inner 点击
        console.log('#inner');
    })
    
    $('#btn').click(function(event){
        // 第一个#btn点击
        e.stopImmediatePropagation();
        console.log('#btn 1');
    })
    
    $('#btn').click(function(event){
        // 第二个#btn点击
        console.log('#btn 2')
    })
    
    // 最终输出
    '#btn 1' // (因为stopImmediatePropagation阻止了#btn绑定的剩余未执行的事件方法,并且阻止了冒泡)
    
    // 如果不使用stopImmediatePropagation, 将输出
    '#btn 1'
    '#btn 2'
    '#inner'
    'body'
    同个对象执行顺序按绑定顺序执行,冒泡则由内向外执行
    
    

    return false

    “return false” 相信不少同学会用来阻止元素在浏览器中的默认行为,
    拿它当preventDefault()使用,但其实“return false”做的事情不仅仅只是阻止默认行为

    当调用“return false”时,它执行了以下三件事情

    1. event.preventDefault()
    2. event.stopPropagation()
    3. 停止回调函数执行并立即返回

    1,2点还好理解,那么第3点是怎么回事?
    return语句会终止函数的执行并返回函数的值。所以不管是否返回false或是其它值,return语句后面的代码都不会执行。而返回false,使它具备了preventDefault和stropPropagation的功能

    $('a').click(function(){
        return false; // return false直接返回了,并不会执行alert
        alert('我没有被弹出来');
    })
    
    // preventDefault 和 stopPropagation 并不会阻止回调函数的执行
    

    总结

    很多jQuery教程在代码演示中用“return false”来阻止执行浏览器的默认行为。
    久而久之,很多同学习惯滥用“return false”来代替preventDefault

    大多数情况下,我们仅仅是想要它执行跟preventDefault的功能而已,但它却自作主张地帮你执行了另外两步操作。
    比较好的编程习惯是,需要用到该事件方法再去调用,否则应该避免冗余事件的执行。
    就像prevnetDefault完成它该有的工作,并不会阻止父节点继续处理事件,使得代码更加灵活,更易于维护。

    日常开发中还是要慎用“return false”,除非你同时需要preventDefault和stopPropagation,并且确定你的回调函数执行完成后调用,那么你可以使用“return false”,否则还是用preventDefault 或 stopPropagation 更好些。

    作者:以乐之名
    本文原创,有不当的地方欢迎指出。转载请指明出处。

    参考文章:《preventDefault()、stopPropagation()、return false 之间的区别》

    相关文章

      网友评论

        本文标题:preventDefault,stopPropagation,r

        本文链接:https://www.haomeiwen.com/subject/wbncjxtx.html