How to correctly use preventDefault(), stopPropagation(), or return false; on events

How to correctly use preventDefault(), stopPropagation(), or return false; on events

I’m sure this has been written about many times before and probably has hundreds of answers on StackOverflow.

Despite this we still find ourselves going through code bases and repeatedly finding the misuse (or interchangeable use, or combined use) of event.preventDefault(), event.stopPropagation() and return false;.

So today we’re going to learn what the differences are between the three, and exactly how they function.

preventDefault(), stopPropagation(), and return false; are not interchangeable, nor are they tools of trial-and-error.

We’ll start off with a pretty common UI pattern — a file upload panel — and see how each of them affect its behaviour.

https://github.com/FineUploader/fine-uploader

Image courtesy of FineUploader

HTML

<div class="file-upload">
    <input type="file" name="upload-file" class="file-upload__input" style="display: none;" />

    <div class="file-upload__drop-zone">
        <span class="file-upload__drop-zone-text">Drop files here</span>
        <a href="#" class="file-upload__btn--upload">Upload files</a>
    </div>
</div>

Our HTML consists of three parts:

  1. An input to handle the file upload dialog. This is hidden (display: none;) , as we will be triggering the upload dialog using the following two elements.
  2. A div with the class of file-upload__dropzone which acts as the main ‘drop zone’ where we will be able to drag-and-drop files (code not included) or click to open a file upload dialog.
  3. An a tag with the class of file-upload__btn--upload which will act as the “Upload files” button, which when clicked will open a file upload dialog.

JavaScript

function fileUpload() {
  document.querySelector(‘.file-upload__input‘).click();
}

const dropzone = document.querySelector(‘.file-upload__drop-zone‘);
const button = document.querySelector(‘.file-upload__btn--upload‘);

dropzone.addEventListener(‘click‘, fileUpload);
button.addEventListener(‘click‘, fileUpload);

Our JavaScript, like our HTML, also consists of three parts:

  1. A fileUpload function to trigger the click event on the file upload input.
  2. Assigning both the dropzone div and a button to variables.
  3. Adding event listeners to those, which when clicked invoke the fileUpload function.

If we were to try this out now, we may see some odd behaviour — after the first dialog has opened and we have chosen our file, a second one will open prompting us again. Keep reading and all will be revealed.

event.preventDefault()

Prevents the browsers default behaviour (such as opening a link), but does not stop the event from bubbling up the DOM.

In our scenario, clicking on the “Upload files” button will invoke the fileUpload function, as we would expect.

Being an a tag, however, it also has a default behaviour — this being to navigate the browser to the location in the href attribute. In this instance we have this set to #, which in most browsers will just cause the page to jump back to the top.

Jumping back to the top of the page is not really our desired behaviour, so we can prevent this by using the preventDefault method. This prevents the default behaviour of an element.

Modifying our JavaScript code, we can fix this so that clicking the link prevents the default behaviour of navigating to the location in the href attribute, but still opens the file upload dialog.

dropzone.addEventListener(‘click‘, fileUpload);

button.addEventListener(‘click‘, (event) => {
  event.preventDefault();
  fileUpload();
});

Here we have taken the click event and prevented its default behaviour using event.preventDefault(), then invoked the fileUpload() function.

We still have the dialog box popping up twice, but hopefully the next section will solve this issue.

event.stopPropagation()

Prevents the event from bubbling up the DOM, but does not stop the browsers default behaviour.

For an in-depth explanation of event bubbling, I’d recommend this article about event propagation. But essentially, when an event is called on an element, that event bubbles up the DOM and gets called on all of the elements parents.

In our case, that means that when we click on the “File upload” button, that click event is also called on all of its parent elements, including our dropzone.

To see this in action, we can remove the fileUpload() call in the button event listener and the function will still be invoked when we click on the button because the click event will bubble up the DOM and be called on the dropzone.

dropzone.addEventListener(‘click‘, fileUpload);

button.addEventListener(‘click‘, event => event.preventDefault());

This bubbling is an example of event propagation, which is where the stopPropagation method comes into play. We can use it to prevent this default bubbling behaviour so that the event is only registered by the element it is called upon.

dropzone.addEventListener(‘click‘, fileUpload);

button.addEventListener(‘click‘, event => event.stopPropagation());

Now we see that not only does the click event not bubble up the DOM, but by removing the preventDefault method call the a tag acts as it should again, by navigating to its href attribute.

But this isn’t what we want. We wanted to call the fileUpload function and also prevent the element’s default behaviour and prevent the event from bubbling up the DOM.

We could use both preventDefault and stopPropagation then call the fileUpload function, like so.

dropzone.addEventListener(‘click‘, fileUpload);

button.addEventListener(‘click‘, (event) => {
  event.preventDefault();
  event.stopPropagation();
  fileUpload();
});

return false;

Usually seen in jQuery code, it Prevents the browsers default behaviour, Prevents the event from bubbling up the DOM, and immediately Returns from any callback.

In vanilla JavaScript, returning false doesn’t have any effect on the default behaviour or event propagation of the element, as we can see here, it acts exactly as it did at the start.

dropzone.addEventListener(‘click‘, fileUpload);

button.addEventListener(‘click‘, (event) => {
  fileUpload();
  return false;
});

It calls the click event on the button, also navigating to it’s href value, then bubbles up the DOM, calling the click event on the dropzone too.

However…

…in the context of jQuery, returning false will immediately exit the event listeners callback. This has the effect of both:

  1. Preventing the default behaviour — navigating the browser to the a tag’s href attribute.
  2. Stopping any event propagation — stopping the click event from bubbling up the DOM.

If we refactor our code to jQuery, we can see this in practice.

const dropzone = $(‘.file-upload__drop-zone‘);
const button = $(‘.file-upload__btn--upload‘);

$(dropzone).on(‘click‘, fileUpload);

$(button).on(‘click‘, (event) => {
  fileUpload();
  return false;
});

We call the fileUpload method, then return false to prevent any default behaviour or event propagation.

Conclusion

We should use these tools correctly and wisely.

Next time when we’re in this kind of situation, we shouldn’t just play around with event.preventDefault(), event.stopPropagation() and return false; until we get the desired result.

We should think what it is we want to achieve, and how to get there — not through trial-and-error and luck — but through thinking through the problem and applying the correct solution.

原文地址:https://www.cnblogs.com/chucklu/p/11165455.html

时间: 2024-11-14 00:52:03

How to correctly use preventDefault(), stopPropagation(), or return false; on events的相关文章

js 阻止事件冒泡和默认行为 preventDefault、stopPropagation、return false

preventDefault: preventDefault它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为.既然是说默认行为,当然是元素必须有默认行为才能被取消,如果元素本身就没有默认行为,调用当然就无效了.什么元素有默认行为呢?如链接<a>,提交按钮<input type=”submit”>等.当Event对象的cancelable为false时,表示没有默认行为,这时即使有默认行为,调用 preventDefault也是不会起作用的. 我们都知道,链接&

preventDefault()、stopPropagation()、return false 之间的区别

"return false"之所以被误用的如此厉害,是因为它看起来像是完成了我们交给它的工作,浏览器不会再将我们重定向到href中的链接,表单也不会被继续提交,但这么做到底有什么不对呢? 可能在你刚开始学习关于jQuery事件处理时,看到的第一个例子就是关于如何阻止浏览器执行默认行为,比如下面这段演示click事件的代码 $("a.toggle").click(function () { $("#mydiv").toggle(); return

JS preventDefault ,stopPropagation ,return false

所谓的事件有两种:监听事件和浏览器对特殊标签元素的默认行为事件.监听事件:在节点上被监听的事件操作,如 select节点的change事件,a节点的click事件.浏览器的默认事件:特定页面元素上带的功能,如a标签的href跳转,表单的提交事件.执行监听事件在先,浏览器默认事件在后,所以可以在监听事件函数中,阻止浏览器的默认行为.区别:preventDefault() 阻止浏览器默认事件 stopPropagation() 阻止事件的冒泡 return false; 阻止后续的所有行为 1 <!

jQuery中preventDefault()、stopPropagation()、return false 之间的区别

一.preventDefault()方法,阻止浏览器默认行为 浏览器有很多默认行为,比如form表单的submit按钮一点击,默认行为就要开始提交表单. 再比如 <a href="http://www.klmai.cn">内部优惠券</a> a链接一点击默认触发的行为就是浏览器地址栏变化后跳转到指定的网站.要阻止这种默认行为我们可以用preventDefault()方法.实例如下: <div class="div1"> 阻止浏览器

js阻止事件冒泡stopPropagation()、cancelBubble、preventDefault()、return false的分析

事件冒泡,举个列子: <li> <a href='http://www.baidu.com'>点击a</a> </li> <script> $('li').click(function () { alert('点击了li'); }); $('a').click(function () { alert('点击了a'); }); </script> 当你点击a的时候,会先弹出‘点击了a’,再弹出‘点击了li’,最后跳转到百度.简单理解就是

jQuery中return false,e.preventDefault(),e.stopPropagation()的区别

e.stopPropagation()阻止事件冒泡 <head> <title></title> <script src="http://cordial99.blog.163.com/blog/Scripts/jquery-1.4.1.js" type="text/javascript"></script> </head> <body> <table> <tr>

stopPropagation, preventDefault 和 return false 的区别

因为有父, 子节点同在, 因为有监听事件和浏览器默认动作之分. 使用 JavaScript 时为了达到预期效果经常需要阻止事件和动作执行. 一般我们会用到三种方法, 分别是 stopPropagation(), preventDefault() 和 return false. 它们之间有什么区别, 该何时使用呢? 将在本文中进行讲解. 术语 监听事件, 在在节点上能被监听的页面操作. 如: select 节点的 change 事件, a 节点的 click 事件.浏览器默认动作, 指特定页面元素

关于js中return false、event.preventDefault()和event.stopPropagation()

在平时项目中,如果遇到需要阻止浏览器默认行为,大家经常会用return false;和event.preventDefault()来阻止,但对它俩的区别还是有些一知半解,于是看了文档,查了些资料,在此总结下它俩的区别,顺便带上event.stopPropagation()一起区分下. 一.原生js中: 关于return false和preventDefault: 在W3C Document Object Model Events Specification1.3版本中提到过: The Event

浅谈 return false 和preventDefault stopPropagation stopImmediatePropagation 的正确用法

1.使用return false实际上做了3件事:(谨慎使用) event.preventDefault(); event.Propagation(); 停止回掉函数执行并立即返回 2.event.preventDefault()  ----->阻止浏览器继续执行默认行为 3.event.stopPropagation() ----->停止事件冒泡 event bubbling 4. stopImmediatePropagation ------>停止一个事件继续执行 link:http