как узнать об использовании метода event preventdefault
Действия браузера по умолчанию
Многие события автоматически влекут за собой действие браузера.
Если мы обрабатываем событие в JavaScript, то зачастую такое действие браузера нам не нужно. К счастью, его можно отменить.
Отмена действия браузера
Есть два способа отменить действие браузера:
В следующем примере при клике по ссылке переход не произойдёт:
Обычно значение, которое возвращает обработчик события, игнорируется.
В других случаях return не нужен, он никак не обрабатывается.
Пример: меню
Рассмотрим меню для сайта, например:
Данный пример при помощи CSS может выглядеть так:
Кстати, использование здесь делегирования событий делает наше меню очень гибким. Мы можем добавить вложенные списки и стилизовать их с помощью CSS – обработчик не потребует изменений.
Некоторые события естественным образом вытекают друг из друга. Если мы отменим первое событие, то последующие не возникнут.
Опция «passive» для обработчика
Почему это может быть полезно?
Есть некоторые события, как touchmove на мобильных устройствах (когда пользователь перемещает палец по экрану), которое по умолчанию начинает прокрутку, но мы можем отменить это действие, используя preventDefault() в обработчике.
Поэтому, когда браузер обнаружит такое событие, он должен для начала запустить все обработчики и после, если preventDefault не вызывается нигде, он может начать прокрутку. Это может вызвать ненужные задержки в пользовательском интерфейсе.
Опция passive: true сообщает браузеру, что обработчик не собирается отменять прокрутку. Тогда браузер начинает её немедленно, обеспечивая максимально плавный интерфейс, параллельно обрабатывая событие.
event.defaultPrevented
Рассмотрим практическое применение этого свойства для улучшения архитектуры.
Помните, в главе Всплытие и погружение мы говорили о event.stopPropagation() и упоминали, что останавливать «всплытие» – плохо?
Давайте посмотрим практический пример.
По умолчанию браузер при событии contextmenu (клик правой кнопкой мыши) показывает контекстное меню со стандартными опциями. Мы можем отменить событие по умолчанию и показать своё меню, как здесь:
Теперь в дополнение к этому контекстному меню реализуем контекстное меню для всего документа.
При правом клике должно показываться ближайшее контекстное меню.
Как это поправить? Одно из решений – это подумать: «Когда мы обрабатываем правый клик в обработчике на кнопке, остановим всплытие», и вызвать event.stopPropagation() :
Теперь контекстное меню для кнопки работает как задумано. Но цена слишком высока. Мы навсегда запретили доступ к информации о правых кликах для любого внешнего кода, включая счётчики, которые могли бы собирать статистику, и т.п. Это слегка неразумно.
Как мы можем видеть, event.stopPropagation() и event.preventDefault() (также известный как return false ) – это две разные функции. Они никак не связаны друг с другом.
Есть также несколько альтернативных путей, чтобы реализовать вложенные контекстные меню. Одним из них является единый глобальный объект с обработчиком document.oncontextmenu и методами, позволяющими хранить в нём другие обработчики.
Объект будет перехватывать любой клик правой кнопкой мыши, просматривать сохранённые обработчики и запускать соответствующий.
Итого
Действий браузера по умолчанию достаточно много:
Все эти действия можно отменить, если мы хотим обработать событие исключительно при помощи JavaScript.
Технически, отменяя действия браузера по умолчанию и добавляя JavaScript, мы можем настроить поведение любого элемента. Например, мы можем заставить ссылку работать как кнопку, а кнопку вести себя как ссылка (перенаправлять на другой URL).
Но нам следует сохранять семантическое значение HTML элементов. Например, не кнопки, а тег должен применяться для переходов по ссылкам.
Помимо того, что это «хорошо», это делает ваш HTML лучше с точки зрения доступности для людей с ограниченными возможностями и с особых устройств.
Делегирование событий
На предыдущем занятии мы с вами познакомились с таким важным механизмом как погружение и всплытие событий для вложенных элементов. Так вот, используя механизм всплытия, в JavaScript реализуется такой прием разработки как делегирование событий. Что это такое? Предположим, у нас есть вот такая страница с неким меню:
Добавим в скрипт следующие строчки:
Теперь кликая по элементам li мы в консоли видим соответствующие строчки. Однако, если кликнуть между этими элементами, то сработает обработчик для ul и мы увидим все пункты меню. Это не то, что нам нужно. Поэтому немного перепишем обработчик:
Здесь метод closest вернем ближайший дочерний элемент li, а если его нет, то значение null. Далее, мы проверяем: если li равно null, то завершаем работу обработчика. Обновим документ и видим, что теперь все работает гораздо лучше.
Но нам в нашей задаче нужно не получать содержимое элементов li, а выполнять определенные действия при выборе того или иного пункта меню. Как это лучше сделать? В практике программирования на JavaScript существует один очень эффективный и элегантный способ решить эту задачу. Для этого нам понадобятся нестандартные атрибуты, начинающиеся с префикса data-. Добавим к нашим тегам li следующие параметры:
А в обработчике будем читать этот атрибут:
Теперь при клике по пункту меню будем получать команду, которую следует выполнить. Для удобства все эти команды можно прописать как методы некоторого объекта:
И вызывать их вот таким универсальным кодом:
Щелкая по первым двум пунктам, откроется окно с сообщением. А при кликах по другим пунктам ничего не будет происходить, т.к. указанные методы не будут найдены в объекте menuActs.
Как видите, благодаря делегированию событий, получили довольно красивое и элегантное решение для обработки элементов пунктов меню, не привязанное к конкретной разметке. В дальнейшем можно относительно просто добавлять и менять это меню без существенной перестройки кода.
Кстати, используя прием с нестандартными атрибутами, в JavaScript удобно реализовывать обработчики общего назначения. Например, для отображения или сокрытия с экрана браузера некоторого элемента. Для примера, предположим, что у нас есть вот такая кнопка:
с атрибутом data-toggle-menu и значением main_menu. Создадим универсальный обработчик, который будет использовать этот атрибут, чтобы показать или скрыть элемент с указанным id:
Обратите внимание, что общий обработчик мы вешаем на объект document, который является корневым для DOM-дерева, то есть, все элементы внутри HTML-документа являются дочерними для этого объекта. Поэтому, когда событие всплывает до document, мы берем ссылку event.target на элемент, в котором событие произошло и смотрим значение его атрибута data-toggle-id. Если оно существует, то ищем элемент с указанным id, и если такой элемент находится, то меняем его видимость на противоположное значение. В результате наше меню то скрывается, то показывается.
Здесь может возникнуть вопрос: почему мы повесили универсальный обработчик через метод addEventListener, а не через свойство onclick объекта document? Дело в том, что на свойстве onclick уже может висеть какой-либо нужный обработчик и меняя его можно порушить работу сайта. Тогда как метод addEventListener лишь добавляет еще один обработчик к уже существующим и никаких дополнительных проблем это не должно вызывать. Особенно так удобно делать при разработке больших проектов, работая в команде: каждый программист может через addEventListener назначить свои обработчики и это никак не повлияет на работоспособность всего проекта.
Во второй части этого занятия рассмотрим события, которые браузер выполняет автоматически. Что это за события? Например, если мы вместо кнопки разместим вот такую ссылку:
то наш скрипт перестанет работать, так как браузер при клике будет выполнять переход к странице ex1.htm, то есть, перегружать текущий документ. Как сделать так, чтобы этого не происходило, то есть отменить действие браузера по умолчанию? Здесь есть два способа: наше событие onclick должно вернуть значение false:
или же выполнить метод event.preventDefault() в обработчике события:
Когда может понадобиться такое прерывание действия браузера по умолчанию? Предположим, что мы создаем контекстное меню для всего документа:
Нажимая на правую кнопку мыши, мы увидим в консоли сообщение и контекстное меню по умолчанию от браузера. Но мы не хотим, чтобы стандартное меню отображалось. Для этого добавим в обработчик строку:
Теперь щелкая правой кнопкой мыши, будем видеть только сообщение в консоли.
Далее, нам говорят, что нужно еще сделать отдельное контекстное меню для элементов главного меню. И мы добавляем в наш скрипт такие строчки:
Но при щелчке правой кнопкой мыши, мы теперь видим два контекстных меню, так как событие oncontextmenu всплыло до уровня document и там тоже сработал обработчик этого события. Естественным желанием будет остановить всплытие события:
Теперь наше событие продолжает всплывать, но контекстное меню документа будет отображаться, только если никакое другое ранее не было вызвано. Благодаря свойству
мы можем узнать было ли в дочерних элементах вызван метод
и если да, то defaultPrevented принимает значение true. Иначе, оно будет равно false. Как видите, все достаточно просто.
Последнее, что отметим на этом занятии, в методе addEventListener можно использовать вот такой необязательный третий аргумент:
который сигнализирует браузеру, что добавляемый обработчик события не собирается прерывать действие по умолчанию браузера. Например:
Здесь возникнет ошибка, так как мы вызываем event.preventDefault(), хотя указали, что не будем этого делать. Зачем вообще нужно заранее говорить JavaScript-машине, что мы не собираемся прерывать обработку события? Дело в том, что некоторые действия, вроде скроллинга документа, особенно на смартфонах, желательно выполнять быстро и без задержек. Чтобы увеличить время реакции мы можем сразу сказать, что можно делать скроллинг, не дожидаясь окончания обработки текущего события в нашем скрипте. В некоторых браузерах (Firefox, Chrome) это свойство
Итак, на этом занятии мы рассмотрели механизм делегирования событий и узнали как можно обрабатывать действия браузера по умолчанию.
Видео по теме
JavaScipt (DOM) #1: объектная модель документа DOM и BOM
JavaScipt (DOM) #3: методы поиска элементов в DOM: querySelector, querySelectorAll, getElementById
JavaScipt (DOM) #4: свойства DOM-узлов: nodeName, innerHTML, outerHTML, data, textContent, hidden
JavaScipt (DOM) #5: работа с нестандартными свойствами DOM-элементов: getAttribute, setAttribute, dataset
JavaScipt (DOM) #6: создание и добавление элементов DOM createElement, append, remove, insertAdjacentHTML
JavaScipt (DOM) #9: HTML-документ: размеры (clientWidth, innerWidth), положение (pageYOffset, scrollBy)
JavaScipt (DOM) #11: обработчики событий: onclick, addEventListener, removeEventListener, event
JavaScipt (DOM) #12: погружение и всплытие событий: stopPropagation, stopImmediatePropagation, eventPhase
JavaScipt (DOM) #14: события мыши mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter
JavaScipt (DOM) #15: события клавиатуры keydown, keyup, событие скроллинга scroll
JavaScipt (DOM) #18: события change, input, cut, copy, paste, submit элементов input и select
JavaScipt (DOM) #20: события load, error; атрибуты async, defer тега script
JavaScipt (DOM) #21: пример предзагрузки изображений с помощью javascript
JavaScipt (DOM) #22: пример создания начала игры арканоид
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Свойства и методы объекта события в JavaScript
Как получить информацию о событии?
Получить детальную информацию о событии в обработчике можно посредством объекта события ( Event ). Данный объект создаёт браузер, когда это событие происходит. В него он помещает много различной информации. Например, для события click : какая клавиша нажата, координаты курсора и др.
Объект события в соответствии со стандартом всегда передаётся обработчику посредством первого аргумента:
Например, выведем детальную информацию в консоль при клике на элемент:
Свойства и методы объекта события
Свойства объекта Event :
Методы объекта Event :
Свойства объекта события MouseEvent
Например, получим координаты курсора при перемещении по документу (событие mousemove ):
Так как в разметке элементы вложены друг в друга, то курсор в большинстве случаев всегда находится одновременно над несколькими элементами. Но взаимодействие всегда осуществляется с тем, кто расположен глубже других (т.е. ближе к нам по оси Z). Если элементы находятся не в основном потоке, то в этом случае с тем, у кого больше значение свойства z-index. Но если элементы имеют одинаковое значение z-index, то тогда ближе к нам будет уже тот, кто из них глубже расположен.
Например, при движении мыши будем выводить информацию о элементе (его значение id ), который в данный момент создаёт событие mousemove :
Свойства объекта события KeyboardEvent
Объект KeyboardEvent позволяет обрабатывать взаимодействия пользователя с клавиатурой:
Отличие target от currentTarget
События в браузере по умолчанию всплывают. Из-за этого:
Например, рассмотрим этот код:
Использование target и relatedTarget
Свойство relatedTarget предназначено для определения дополнительной цели, связанной с событием.
Задачи
1. Удаление элемента при клике на нем
Необходимо написать JavaScript сценарий, который будет при клике на элементе удалять его из DOM.
2. Перемещение блока с помощью клавиш «WASD»
Нужно создать код, который будет при нажатии клавиш «WASD» перемещать элемент #box по странице.
3. Одновременное нажатие кнопок
Напишете код, который будет при одновременном нажатии клавиш Z и X показывать в верхней части экрана сообщение.
Создаваемое сообщение должно иметь следующую разметку:
event.preventDefault() function not working in IE
Following is my JavaScript (mootools) code:
In all browsers except IE, this works fine. But in IE, this causes an error. I have IE8 so while using its JavaScript debugger, I found out that the event object does not have a preventDefault method which is causing the error and so the form is getting submitted. The method is supported in case of Firefox (which I found out using Firebug).
11 Answers 11
to achieve the same result.
And in order not to get an error, you can test for the existence of preventDefault:
You can combine the two with:
If you bind the event through mootools’ addEvent function your event handler will get a fixed (augmented) event passed as the parameter. It will always contain the preventDefault() method.
Try out this fiddle to see the difference in event binding. http://jsfiddle.net/pFqrY/8/
For all jQuery users out there you can fix an event when needed. Say that you used HTML onclick=»..» and get a IE specific event that lacks preventDefault(), just use this code to get it.
After that e.preventDefault(); works fine.
I know this is quite an old post but I just spent some time trying to make this work in IE8.
It appears that there are some differences in IE8 versions because solutions posted here and in other threads didn’t work for me.
Let’s say that we have this code:
In my IE8 preventDefault() method exists because of jQuery, but is not working (probably because of the point below), so this will fail.
Even if I set returnValue property directly to false:
This also won’t work, because I just set some property of jQuery custom event object.
Only solution that works for me is to set property returnValue of global variable event like this:
Just to make it easier for someone who will try to convince IE8 to work. I hope that IE8 will die horribly in painful death soon.
event.preventDefault() vs. return false
When I want to prevent other event handlers from executing after a certain event is fired, I can use one of two techniques. I’ll use jQuery in the examples, but this applies to plain-JS as well:
1. event.preventDefault()
2. return false
Is there any significant difference between those two methods of stopping event propagation?
For me, return false; is simpler, shorter and probably less error prone than executing a method. With the method, you have to remember about correct casing, parenthesis, etc.
Also, I have to define the first parameter in callback to be able to call the method. Perhaps, there are some reasons why I should avoid doing it like this and use preventDefault instead? What’s the better way?
14 Answers 14
return false from within a jQuery event handler is effectively the same as calling both e.preventDefault and e.stopPropagation on the passed jQuery.Event object.
e.preventDefault() will prevent the default event from occuring, e.stopPropagation() will prevent the event from bubbling up and return false will do both. Note that this behaviour differs from normal (non-jQuery) event handlers, in which, notably, return false does not stop the event from bubbling up.
From my experience, there is at least one clear advantage when using event.preventDefault() over using return false. Suppose you are capturing the click event on an anchor tag, otherwise which it would be a big problem if the user were to be navigated away from the current page. If your click handler uses return false to prevent browser navigation, it opens the possibility that the interpreter will not reach the return statement and the browser will proceed to execute the anchor tag’s default behavior.
The benefit to using event.preventDefault() is that you can add this as the first line in the handler, thereby guaranteeing that the anchor’s default behavior will not fire, regardless if the last line of the function is not reached (eg. runtime error).
This is not, as you’ve titled it, a «JavaScript» question; it is a question regarding the design of jQuery.
jQuery and the previously linked citation from John Resig (in karim79’s message) seem to be the source misunderstanding of how event handlers in general work.
Fact: An event handler that returns false prevents the default action for that event. It does not stop the event propagation. Event handlers have always worked this way, since the old days of Netscape Navigator.
The documentation from MDN explains how return false in an event handler works
What happens in jQuery is not the same as what happens with event handlers. DOM event listeners and MSIE «attached» events are a different matter altogether.
Generally, your first option ( preventDefault() ) is the one to take, but you have to know what context you’re in and what your goals are.
When using jQuery, return false is doing 3 separate things when you call it:
You can hang a lot of functions on the onClick event for one element. How can you be sure the false one will be the last one to fire? preventDefault on the other hand will definitely prevent only the default behavior of the element.
is the w3c specified way of canceling events.
You can read this in the W3C spec on Event cancelation.
Also you can’t use return false in every situation. When giving a javascript function in the href attribute and if you return false then the user will be redirected to a page with false string written.
I think the best way to do this is to use event.preventDefault() because if some exception is raised in the handler, then the return false statement will be skipped and the behavior will be opposite to what you want.
But if you are sure that the code won’t trigger any exceptions, then you can go with any of the method you wish.
My opinion from my experience saying, that it is always better to use
Practically to stop or prevent submit event, whenever we required rather than return false event.preventDefault() works fine.
The main difference between return false and event.preventDefault() is that your code below return false will not be executed and in event.preventDefault() case your code will execute after this statement.
When you write return false it do the following things for you behind the scenes.
e.preventDefault();
It simply stops the default action of an element.
prevents the hyperlink from following the URL, prevents the submit button to submit the form. When you have many event handlers and you just want to prevent default event from occuring, & occuring from many times, for that we need to use in the top of the function().
The reason to use e.preventDefault(); is that in our code so something goes wrong in the code, then it will allow to execute the link or form to get submitted or allow to execute or allow whatever action you need to do. & link or submit button will get submitted & still allow further propagation of the event.
return False;
It simply stops the execution of the function().
» return false; » will end the whole execution of process.
The reason to use return false; is that you don’t want to execute the function any more in strictly mode.
Basically, this way you combine things because jQuery is a framework which mostly focuses on HTML elements, you basically preventing the default, but at the same time, you stop propagation to bubble up.
So we can simply say, return false in jQuery is equal to:
return false is e.preventDefault AND e.stopPropagation
But also don’t forget it’s all in jQuery or DOM related functions, when you run it on the element, basically, it prevents everything from firing including the default behaviour and propagation of the event.
So basically this code below:
is equal to this code:
From my experience event.stopPropagation() is mostly used in CSS effect or animation works, for instance when you have hover effect for both card and button element, when you hover on the button both card and buttons hover effect will be triggered in this case, you can use event.stopPropagation() stop bubbling actions, and event.preventDefault() is for prevent default behaviour of browser actions. For instance, you have form but you only defined click event for the submit action, if the user submits the form by pressing enter, the browser triggered by keypress event, not your click event here you should use event.preventDefault() to avoid inappropriate behavior. I don’t know what the hell is return false; sorry.For more clarification visit this link and play around with line #33 https://www.codecademy.com/courses/introduction-to-javascript/lessons/requests-i/exercises/xhr-get-request-iv
Prevent Default
Calling preventDefault() during any stage of event flow cancels the event, meaning that any default action normally taken by the implementation as a result of the event will not occur. You can use Event.