Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preventDefault,stopPropagation,return false三者的区别 #13

Open
ZengLingYong opened this issue Jan 15, 2019 · 0 comments
Open

preventDefault,stopPropagation,return false三者的区别 #13

ZengLingYong opened this issue Jan 15, 2019 · 0 comments

Comments

@ZengLingYong
Copy link
Owner

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

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 之间的区别》

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant