踩坑:preventDefault
preventDefault
这个用来阻止默认行为。什么是默认行为呢?在初学的时候,最常举得例子就是<a>
标签,它的点击事件出发后,默认行为就是进行跳转。
现在如果想要阻止点击<a>
标签后的跳转行为,就可以使用preventDefault
<div><a id='a' href="http://www.baidu.com">《《传送门》》</a>
</div><script>const aElement = document.querySelector('#a');aElement.addEventListener('click', e => e.preventDefault());
</script>
兼容性鼠标事件
<div id='outer'><div id='inner'></div>
</div><script>const outer = document.querySelector('#outer');const inner = document.querySelector('#inner');outer.addEventListener('mousedown', () => {console.log('outer-mousedown');});outer.addEventListener('mouseup', () => {console.log('outer-mouseup');});inner.addEventListener('mousedown', () => {console.log('inner-mousedown');});inner.addEventListener('mouseup', () => {console.log('inner-mouseup');});
</script>
看上面的例子,如果点击#inner
会发生什么?首先会触发mousedown
事件,由于都是在冒泡阶段进行处理,所以输出inner-mousedown
、outer-mousedown
;然后触发mouseup
同样在冒泡阶段处理,输出inner-mouseup
、outer-mouseup
。
最终会输出:
inner-mousedown
outer-mousedown
inner-mouseup
outer-mouseup
上面的结果不难看懂,接下来做一些修改:
<div id='outer'><div id='inner'></div>
</div><script>const outer = document.querySelector('#outer');const inner = document.querySelector('#inner');outer.addEventListener('mousedown', () => {console.log('outer-mousedown');});outer.addEventListener('mouseup', () => {console.log('outer-mouseup');});inner.addEventListener('mousedown', () => {console.log('inner-mousedown');});inner.addEventListener('mouseup', () => {console.log('inner-mouseup');});inner.addEventListener('pointerdown', e => {console.log('inner-pointerdown');e.preventDefault();});</script>
这次,在inner
上绑定了一个pointerdown
事件,点击之后发现,只输出了inner-pointerdown
,也就是说,mouse
相关的事件一个都没有触发。
这就是题目说的,mousedown
是pointerdown
的默认行为,可能会有疑问:如果将outer
的mousedown
放在捕获阶段处理呢?其实这里产生了一个误区,捕获和冒泡仅仅会影响相同事件的处理顺序,也就是说,如果将outer
的mousedown
在捕获阶段处理,也仅仅只是让outer
的mousedown
先于inner
的mousedown
,和其他事件没有关系。
回到上面的问题,由于mousedown
是pointerdown
的默认行为,所以pointerdown
先于mousedown
触发,因此,先触发inner
的pointerdown
,之后,本来要触发默认行为,inner
触发一个mousedown
事件,但是被通过e.preventDefault()
阻止了,所以,并没有触发mousedown
事件。
现在,已经弄清楚两个mousedown
为什么没有触发了,还有一个问题两个mouseup
为什么没有触发?举一反三,是因为mousedown
没有触发,也就是说,mouseup
是mousedown
的默认行为,因此,必须先触发mousedown
才能触发mouseup
。也可以做个实验,在最初的例子中,阻止inner
的mousedown
的默认行为。
关于这一段的问题,MDN有详细的解释:
The browser may map generic pointer input to mouse events for compatibility with mouse-based content. This mapping of events is called compatibility mouse events. Authors can prevent the production of certain compatibility mouse events by canceling the pointerdown event but note that:
- Mouse events can only be prevented when the pointer is down.
- Hovering pointers (e.g. a mouse with no buttons pressed) cannot have their mouse events prevented.
- The
mouseover
,mouseout
,mouseenter
, andmouseleave
events are never prevented (even if the pointer is down).
阻止mousedown的默认行为,会阻止blur
假设有一个输入框,在blur
事件触发时,会执行一些操作;有另一个按钮,在按钮电击时,执行某些操作,但是,不希望触发输入框的blur
事件。
这就和上面所说的默认行为一样,如果输入框要触发blur
事件,一定会在其他元素上触发mousedown
,反过来说,一个非输入框的元素触发mousedown
,它的默认行为就是输入框触发blur
。
<input type="text" id='input'>
<div id='dom'>
</div><script>const dom = document.querySelector('#dom');const input = document.querySelector('#input');dom.addEventListener('mousedown', e => e.preventDefault());input.addEventListener('blur', () => console.log('input-blur'));
</script>
这时,点击#dom
时,默认情况下#input
失去焦点,触发blur
,但这里阻止了这种默认行为。
注意,如果将上面的dom结构改成:
<div id='dom'><input type="text" id='input'>
</div><script>const dom = document.querySelector('#dom');const input = document.querySelector('#input');dom.addEventListener('mousedown', e => e.preventDefault());input.addEventListener('blur', () => console.log('input-blur'));input.addEventListener('focus', ()=>console.log('input-focus'));
</script>
这次再点击,就会发现#input
连焦点都没办法获取,这和上面的原因也一样,mousedown
的默认行为也有获取焦点focus
,如果阻止默认行为,获取焦点的事件也会被阻止。
踩坑:preventDefault相关推荐
- Vant-UI 表单组件(Field组件):验证表单元素表单提交 - 踩坑篇
Vant-UI 表单组件(Field组件):验证表单元素&&表单提交: 示例截图 · 如下: 示例 · 详细代码 · 如下: <template><div class ...
- 使用VUE仿写【E宠商城】踩坑点
使用VUE仿写[E宠商城]踩坑点 1.无论是否是否写了!important 父元素的规则 都是被子元素继承的 继承的样式优先级小 所以这边的字体大小还是保留reset那边的样式!!! 2.canvas ...
- weex 一个传说级巨坑-- 2018最新版weex踩坑指南(weex navigator 多界面跳转)
先说结论,本人极度非常 不推荐weex作为任何商用开发 有很多人会说了... 你瞎扯.. 你看别人阿里.. 啊飞猪... 啊那个支付宝... 人家不是用得好好的么... 当然这也是我们公司作为技术选型 ...
- 【golang程序包推荐分享】分享亿点点golang json操作及myJsonMarshal程序包开发的踩坑经历 :)
目录[阅读时间:约5分钟] 一.概述 1.Json的作用 2.Go官方 encoding/json 包 3. golang json的主要操作 二.Json Marshal:将数据编码成json字符串 ...
- java调用clang编译的so_写Java这么久,JDK源码编译过没?编译JDK源码踩坑纪实
好奇害死羊 很多小伙伴们做Java开发,天天写Java代码,肯定离不开Java基础环境:JDK,毕竟我们写好的Java代码也是跑在JVM虚拟机上. 一般来说,我们学Java之前,第一步就是安装JDK环 ...
- python导入类有红线_python踩坑系列之导入包时下划红线及报错“No module named”问题...
python踩坑系列之导入包时下划红线及报错"No module named"问题 使用pycharm编写Python时,自己写了一个包(commontool),在同级另一个路径下 ...
- mysql运维工资_MySQL运维踩坑
image ZERO 背景 本文主要是介绍在MySQL使用运维过程中所遇到的一些坑爹的地方,予自己以做记录! 前言 因操作系统重装之后,安装了mysql5.7,而由此带来了一系列的问题,现将解决这些m ...
- 微信跳一跳高分辅助踩坑
旧博文,搬到 csdn 原文:http://rebootcat.com/2018/01/08/wechat_jump_hack/ 最近挺火的微信跳一跳 最近新版微信的『跳一跳』小程序着实火了一把,也把 ...
- 【踩坑记录】记一次MySQL主从复制延迟的坑
最近开发中遇到的一个MySQL主从延迟的坑,记录并总结,避免再次犯同样的错误. 情景 一个活动信息需要审批,审批之后才能生效.因为之后活动要编辑,编辑后也可能触发审批,审批中展示的是编辑前的活动内容, ...
- 分布式深度学习最佳入门(踩坑)指南
点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨Lyon@知乎(已授权) 来源丨https://zhuanla ...
最新文章
- Java项目:就业管理系统设计和实现(java+springboot+ssm)
- android 循环平移动画
- mysql grant all详解_grant all赋权后mysql.user表权限字段还是N,但能登录和新建表
- 安装zabbix及LNMP的平台的搭建
- pythonsklearn乳腺癌数据集_Python的Sklearn库中的数据集
- 物联网架构----EMQ-Hook了解、连接Kafka发送消息
- 嵌入式Linux入门3:Linux服务器搭建
- mysql 追加水印_php 使用GD库为页面增加水印示例代码
- 元宇宙里过节,英伟达快速打造「冬日仙境」,占地 16 万平米!
- PID神经网络控制【神经网络二十六】
- 百数巡检领域系统能力展示
- ASO学习笔记整理——关键字优化步骤
- 3397. 【GDOI2014模拟】雨天的尾巴
- Kafka 与 RabbitMQ 如何选择使用哪个?
- I Want to Know
- 爬虫基础篇之IP代理池
- Ubuntu下修改字体
- 【编译原理】词法分析器语法分析器
- 建筑材料行业采购合同电子化,数商云采购商城系统助力企业采购业务更规范高效
- oracle查看crs状态,使用crs_stat工具查看资源状态