“preventDefault()” или “return false”?

229
29 марта 2017, 17:49

Не раз замечал, что в различных кодах используют то preventDefault(), то return false. И это касается, как маленьких, так и больших проектов.

По старинке, я привык использовать во всём return false, но недавно задумался: может preventDefault() лучше чем return? Почему его так часто используют?

Так всё же что лучше использовать: preventDefault() или return false?

var type = null; 
 
for(var i = 0; i <= 1; i++){ 
  document.querySelectorAll('[name="type"]')[i].onclick = function() { 
    type = this.value; 
  }; 
}; 
 
document.querySelector('a').onclick = function(e) { 
  if(type == 'pd'){ 
    e.preventDefault(); 
    alert('Прервано функцией preventDefault()!'); 
  }else if(type == 'rf'){ 
    alert('Прервано функцией return false!'); 
    return false; 
  }; 
};
body {font-family: arial;}
<p> 
  <input type="radio" name="type" value="pd"> - preventDefault; 
  <input type="radio" name="type" value="rf"> - return false; 
</p> 
<a href="javascript:alert('Произошёл переход по ссылке!');">Ссылка</a>

Answer 1

return false из обработчика события jQuery так же, как вызов обоих e.preventDefault и e.stopPropagation у переданного jQuery.Event события.

  • e.preventDefault() остановит обработку события по умолчанию,
  • e.stopPropagation() остановит всплытие события по DOM
  • return false остановит их оба.
  • e.stopImmediatePropagation предотвращает всплытие всех подобных событий (полезно, когда на элементе есть несколько обработчиков одного события)

В обычных (не-jQuery) обработчиках событий return false не запрещает всплывание(bubbling) события.

Также return false; в ванильном js не запрещает обработку события по умолчанию из addEventListener обработчиков.
Он работает только из el.onclick хендлеров.

Source: John Resig

Any benefit to using event.preventDefault() over "return false" to cancel out an href click?

Вольный перевод ответа с enSO

Вывод:

В jquery - полезнее return false
В vanillaJS - лучше его не использовать, он работает только с onclick-like обработчиками.

В IE8 и ниже необходимо заменить stopPropagation на cancelBubble, а preventDefault на return false;

Демонстрация

Третья ссылка совершает переход несмотря на return false

document.getElementById('a1').addEventListener('click', function(e){ 
 console.log('preventDefault - clicked'); 
 e.preventDefault(); 
}); 
 
document.getElementById('a2').onclick = function(){ 
 console.log('return false from onclick'); 
 return false; 
}; 
 
document.getElementById('a3').addEventListener('click', function(){ 
 console.log('return false - clicked'); 
 return false; 
})
<a id="a1" href="/">preventDefault</a><br/> 
<a id="a2" href="/">return false from onclick</a><br/> 
<a id="a3" href="/">return false</a><br/>

Answer 2

Хорошая статья.

  • Если вы всего лишь хотите предотвратить действие браузера по умолчанию, то вам следует использовать preventDefault метод.
  • stopPropagation, который останавливает всплытие (bubbling) события к родительским элементам.
  • return false может отменить действие браузера при использовании в DOM Level 0 (inline-обработчик).
  • stopImmediatePropagation запрещает вызов всех остальных обработчиков даже на текущем событии.

// Отменяем действие браузера, в данном случае - переход по ссылке 
document.querySelector('#preventDefault').addEventListener('click', function(e){ 
  e.preventDefault(); 
  console.info('preventDefault: %s', this.href); 
}); 
 
// При клике на span - меняем цвет 
// Можно убедится в этом кликом по тексту 
document.querySelector('#stopPropagationSpan').addEventListener('click', function(e){ 
  this.style.color = 'green'; 
}); 
// А вот клик по ссылке не даст всплыть событию до span, смены цвета не будет 
document.querySelector('#stopPropagationLink').addEventListener('click', function(e){ 
  e.stopPropagation(); 
  e.preventDefault(); // Просто для демонстрации, если убрать - переход будет 
  console.info('stopPropagation: %s', this.href); 
}); 
 
// Навешано 2 обработчика 
// Без stopImmediatePropagation будет смена цвета с зелёного (green) на синий (blue) 
// Однако, мы заблокировали дальнейшие обработчики, поэтому цве будет только зелёный 
document.querySelector('#stopImmediatePropagation').addEventListener('click', function(e){ 
  e.stopImmediatePropagation(); 
  e.preventDefault(); // Просто для демонстрации, если убрать - переход будет 
  this.style.color = 'green'; 
}); 
document.querySelector('#stopImmediatePropagation').addEventListener('click', function(e){ 
  this.style.color = 'blue'; 
});
<a href='normalLink'>Обычная ссылка, переход будет.</a><br /><br /> 
<a href='returnFalse' onclick='this.style.color = "black"; return false;'>Перехода нет, блокируется через "return false".</a><br /><br /> 
<a href='preventDefault' id='preventDefault'>preventDefault()</a><br /><br /> 
<span id='stopPropagationSpan'> 
  <a href='stopPropagation' id='stopPropagationLink'>stopPropagation()</a><br /> 
  А тут клик отловится через span! 
</span><br /><br /> 
<a href='stopImmediatePropagation' id='stopImmediatePropagation'>stopImmediatePropagation()</a>

READ ALSO
JavaScript: Переход при клике по строке таблицы

JavaScript: Переход при клике по строке таблицы

Имеется таблица, которая генерируется посредством ASPNET:

289
Angular 2 | Как связать 2 разных меню между собой?

Angular 2 | Как связать 2 разных меню между собой?

Всем привет! Изучаю angular 2 и столкнулся с проблемкой

268
Конвертировать дату в формате timestamp

Конвертировать дату в формате timestamp

Здравствуйте! Требуется помощь

254