DOM事件

总结下HTML JS React vue 中事件函数的区别

事件类型

注意
代码从上往下执行,在DOM事件中,如果先在<script>里获取对象再通过<div>定义对象会报错,因为这个对象的定义是出现在了获取的后面,你想要获取的时候还没定义。此时可以在<script>里使用鼠标事件中的onload(例子在下方)

关于this指向

  • 在事件触发的(function)函数中,this是对该DOM对象的引用。
  • 可以通过console.log(this)来看this在这个函数中指的是什么。

onload 事件

  • 页面或图像加载完成后立即发生。
  • onload 通常用于 <body> 元素,在页面完全载入后(包括图片、css文件等等。)执行脚本代码。
  • 该事件可作用于以下 HTML 标签:<body>, <frame>, <frameset>, <iframe>, <img>, <input type="image">, <link>, <script>, <style>
  • 例子

语法:
在 HTML 中:

1
<body onload="SomeJavaScriptCode">

在 JavaScript 中:

1
window.onload=function(){SomeJavaScriptCode};

鼠标事件

  • onclick:鼠标点击时触发
  • onmousedown:鼠标按钮在元素上按下时触发
  • onmousemove:每次鼠标指针移动时都会触发
  • onmouseover:鼠标滑过指定对象上时触发
  • onmouseout:鼠标离开时触发
  • onmouseenter:类似onmouseover,唯一的区别是 onmouseenter 事件不支持冒泡
  • onmouseleave:类似onmouseout,唯一的区别是 onmouseleave 事件不支持冒泡
  • onmouseup:在元素上松开鼠标按钮时触发
  • onfoucs:获得焦点时触发 (只能用于:input标签type为text、password
    textarea标签)
  • onblur:失去焦点时触发(blur v.使……模糊不清)
  • onchange:域的内容改变时发生 (一般作用于(下拉框)select或checkbox或radio)
  • onsubmit:表单中的确认按钮被点击时发生 (onsubmit事件不是加在按钮上,而是表单上)
  • onresize:当调整浏览器窗口的大小时触发
  • onscroll:拖动滚动条滚动时触发

需要知道:

  • onmousedown(按下鼠标)与onmouseup(松开鼠标)组成了onclick(鼠标点击)事件。
  • onmouseover或onmousemove都必须和onmouseout结合才能实现移入移出不同效果的功能。(onmouseover的例子onmousemove的例子

onmousemove与onmouseover的区别

  • 时间上 onmousemove 事件触发后,再触发 onmouseover 事件。
  • 动作上 onmouseover 只在刚进入区域时触发。onmousemove 除了刚进入区域触发外,在区域内移动鼠标,也会触发该事件。
    (当鼠标移动很快时,可能不会触发这两个事件。)
  • onmouseover 与 onmousemove 的区别是:
    onmousemove在每次鼠标移动时,都会触发,以此获得当前坐标值,用来判断这个点是否落在指定元素内。onmouseover,则会在进入对象时就触发,且仅会触发这一次
    当鼠标移过当前对象时就产生了onmouseover事件(onmouseover有个移入移出的过程),当鼠标在当前对象上移动时就产生了onmousemove事件,只要是在对象上移动而且没有移出对象的,就是onmousemove事件。

例子

用canvas标签,创建了一个画布,并画了一个小矩形,我想让鼠标悬停到矩形区域时改变矩形填充色,这里只能监听整个画布,看起来应该用over,实际上用的却是move
因为,move在每次鼠标移动时,都会触发,会获得当前坐标值,用来判断这个点是否落在矩形内。若是用over,则会在进入画布时就触发,且仅会触发这一次,之后鼠标在画布内移动,一直都处于over状态,就不会触发,直到鼠标离开这个画布区域,失效。


HTML事件中调用JS函数时不加括号

  • 加括号就是直接执行函数了,不加括号则是指向函数地址,当发生事件时才去调用函数。
  • 事件=function(){}或者事件=函数名都是可以的,不能使用事件=(function(){})(参数)事件=函数名()
  • 如果事件绑定函数想要传参可以使用xx.onclick=function(){函数名(参数);},也就是绑定一个函数,函数在触发onclick时执行,函数内容是执行你想传参的那个函数。

对window使用onload的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<head>
<script>
// 页面加载完成后才执行
window.onload=function(){
// 获取box
var box =document.getElementById("box");
var clicked=function(){
alert("我被点击了!");
}
box.onclick=clicked;
}
</script>
</head>
<body>
<div id="box">这是一个box</div>
</body>

onfocus事件

  • 只能用于:input标签type为text、password
  • textarea标签

onfocus和onblur事件的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.box{
padding:50px;
}
.left,.tip{
float:left;
}
.left{margin-right:10px;}
.tip{display:none;font-size:14px;}
</style>
<script>
window.onload=function(){
// 获取文本框和提示框
var phone=document.getElementById("phone"),
tip=document.getElementById("tip");
// 给文本框绑定激活的事件
phone.onfocus=function(){
// 让tip显示出来
tip.style.display='block';
}
// 给文本框绑定失去焦点的事件
phone.onblur=function(){
// 获取文本框的值,value用于获取表单元素的值
var phoneVal=this.value;
// 判断手机号码是否是11位的数字
// 如果输入正确,则显示对号图标,否则显示错号图标
if(phoneVal.length**11 && isNaN(phoneVal)**false){
tip.innerHTML='<img src="E:/慕课网 前端小白入门系列课程完整版/JavaScript/6.javascriptDoM事件/img/right.png">';
}else{
tip.innerHTML='<img src="E:/慕课网 前端小白入门系列课程完整版/JavaScript/6.javascriptDoM事件/img/error.png">';
}
}
}
</script>
</head>
<body>
<div class="box">
<div class="left">
<input type="text" id="phone" placeholder="请输入手机号码">
</div>
<div class="tip" id="tip">
请输入有效的手机号码
</div>
</div>
</body>

实现效果可以看E:\慕课网 前端小白入门系列课程完整版\JavaScript\6.javascriptDoM事件\index4.html

“onchange:域的内容改变时发生”的例子

change事件,一般作用域(下拉框)select或checkbox或radio。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
// 页面加载(注意这是对DOM0级事件的命名函数调用,不要括号)
window.onload=init;

// 初始化
function init(){
// 获取下拉菜单
var menu=document.getElementById("menu");
// 给菜单绑定change事件,一般作用域select或checkbox或radio
menu.onchange=function(){
// 获取当前选中的值
var bgcolor=this.value;
// var bgcolor=menu.options[menu.selectedIndex].value;

// 可以先打印出来看看选中选项以后得到的value是什么
// console.log(bgcolor);

// 设置body的背景色
//如果bgcolor为空,则下面的脚本将不执行,否则是选择的颜色
if(bgcolor**""){
return;
}else{
document.body.style.background=bgcolor;
}
}
}
</script>
</head>
<body>
<div class="box">
请选择您喜欢的背景色:
<select name="" id="menu">
<option value="">请选择</option>
<option value="#f00">红色</option>
<option value="#0f0">绿色</option>
<option value="#00f">蓝色</option>
<option value="#ff0">黄色</option>
<option value="#ccc">灰色</option>
</select>
</div>
</body>

html中使用js中的onchange

注意
事件函数中调用函数都不用括号。
不建议使用html事件,建议使用DOM事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>

<head>
<script type="text/javascript">
function upperCase(x)
{
var y=document.getElementById(x).value
document.getElementById(x).value=y.toUpperCase()
}
</script>
</head>

<body>

Enter your name: <input type="text" id="fname" onchange="upperCase(this.id)">

</body>
</html>

效果


onchange事件编程练习

注意: if的条件判断一定要注意是两个等号!!

要求实现下列功能:

  1. 选择下拉列表中不同的选项,页面中的d iv就设置成不同的背景颜色,div中的内容也发生变化。
    • 比如:选择黄色选项,div的背景颜色就变为黄色,文本内容就变为“我的背景颜色变成了yellow色”
  2. 当选择下拉列表中的“请选择”时,div的背累颜色变成白色,文本变为“我没有发生任何变化”

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<head>
<style type="text/css">
#div {
width: 300px;
height: 300px;
border: 2px solid gray;
margin: 100px 0 0 200px;
display: none;
}
</style>
<script type="text/javascript">
// 页面加载完成后才执行
window.onload = function () {
// 获取下拉框与文字
var colorSelect = document.getElementById("color");
var bgText=document.getElementById("div");
// console.log(bgText.innerHTML)
// 绑定事件
colorSelect.onchange = choose;
function choose() {
// console.log(this.value);
var bgColor=this.value;
// 选择颜色时让下方文字框可见
bgText.style.display="block";
// 一定要注意是两个等号!
if(bgColor**"0"){
bgText.innerHTML="我没有变化呀";
}else{
bgText.innerHTML="我变成"+bgColor+"色了诶";
document.body.style.background=bgColor;
}

}
}
</script>
</head>

<body>
<div>
<span>请选择您喜欢的颜色:</span>
<select name="" id="color">
<option value="0">请选择</option>
<option value="yellow">黄色</option>
<option value="orange">橘色</option>
<option value="pink">粉色</option>
<option value="purple">紫色</option>
</select>
</div>
<div id="div">我是下方文字</div>
</body>

地址:E:\慕课网 前端小白入门系列课程完整版\JavaScript\6.javascriptDoM事件\test.html


onsubmit事件

注意: onsubmit事件不是加在按钮上,而是form表单上。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<!-- 表单中的确认按钮被点击时发生 -->
<p>当提交表单是,触发函数并弹出提示信息。</p>
<form action="demo-form.php" id="form_ok">
输入名字: <input type="text" name="fname">
<input type="submit" value="提交">
</form>
<script>
// 获取表单(不是确认按钮!)
var ok=document.getElementById("form_ok");
// 绑定事件
ok.onsubmit=myFunction;
function myFunction() {
alert("表单已提交");
}
</script>
</body>

E:\慕课网 前端小白入门系列课程完整版\JavaScript\6.javascriptDoM事件\onsubmit.html


三个比较简单的鼠标事件

想了解可以看index6.html

  • onmousedown:鼠标按钮在元素上按下时触发
  • onmousemove:在鼠标指针移动时发生
  • onmouseup:在元素上松开鼠标按钮时触发

经常作用于window对象的两个事件

  • onresize:当调整浏览器窗口的大小时触发
  • onscroll:拖动滚动条滚动时触发

事件处理

  • 总结:
    • html事件函数必须带(),否则不执行
      • event必须在绑定时传入才能获取ondragstart="drag(event)"
      • 注意:传入的实参必须是event,不能是别的名字,形参可自定义
    • js事件函数不需要()
      • event不用传入即可获取到
      • 不传参则必须命名为event。如果想要传入,则实参和形参都可以自定义名字
    • react事件函数不能有(),否则会立即执行
      • event不用显示传入,但在函数接收参数时需要写明,比如定义函数时接收3个参数id, title, event实际传参时fn(123, 快乐标题)(可参考《React知识点汇总(基础使用1)>)
      • 可以使用 e(或者任何你喜欢的变量名)作为事件处理函数的参数来接收事件对象
    • vue事件函数有没有()都可以(带不带的区别存在于$event传参方式(参考))
      • ()则需要显示传入$event
      • 没有()则隐式传入了$event,可直接获取
      • 注意:实参必须是$event,不能是别的名字,当然,定义形参时可以是你喜欢的名字

HTML 事件处理

  • DOM事件写在html中不符合 行为、结构、样式 相分离的原则
  • 尽量不要把DOM事件写在HTML中
    1. 多元素绑定相同事件时,效率低。
    2. 不建议在HTML元素中写JavaScript代码。(将页面元素写在HTML内,JS代码写在<script>内会更好)
  • HTML中的语法<element onclick="SomeJavaScriptCode">
  • 直接绑定在html上的事件函数不需要手动销毁,HTML 元素上直接绑定的事件函数是直接附加到该元素上的,因此当该元素被销毁或移除时,相应的事件函数也会被自动清理,不会导致内存泄漏
  • 以onclick举例:
    1
    2
    3
    4
    <!-- event必须传入才能获取到 -->
    <button onclick="clickHandle(event)">
    激活按钮
    </button>
    1
    2
    3
    function clickHandle(e){
    document.getElementById("demo").innerHTML = e;
    }
  • html例子

JS 事件处理(DOM事件)

  • 注意:JS代码要在HTML代码加载完成后执行
  • 获取DOM元素=>绑定事件函数

DOM 0级事件处理

  • 优点:符合 行为、结构、样式 相分离的原则。还可以选出DOM元素集合通过for循环统一操作。
  • 缺点:每个DOM元素只能绑定一个同类事件。例如绑定onclick,当你想再绑定onclick会发现他被覆盖了。
  • 语法(以onclick举例)object.onclick=function(){SomeJavaScriptCode};
  • 不需要手动销毁,它通过直接在 HTML 元素的事件属性上指定函数来定义事件处理逻辑,所以当元素被移除或销毁时,事件函数也会被自动清理,不会导致内存泄漏
  • 以onclick举例:
    1
    2
    3
    4
    5
    <body>
    <p>单击按钮触发函数。</p>
    <button id="btn">点我</button>
    <p id="demo"></p>
    </body>
    1
    2
    3
    4
    5
    6
    7
    8
    <script>
    // event不用传入即可获取到
    // 不传参则必须命名为event。如果想要传入,则实参和形参都可以自定义名字
    function clickHandle(){
    document.getElementById("demo").innerHTML = "Hello World!" + event;
    }
    document.getElementById("btn").onclick = clickHandle
    </script>

DOM 2级事件处理(事件监听)

  • addEventListener("事件名" , "事件处理函数" , "布尔值");
    • false 事件冒泡; true 事件捕获
  • 优点相比前两个就多了。可以选择是事件流。可绑定多个同类事件。事件名可以组成字符串。
  • 注意:使用addEventListener绑定事件,等结束后及时使用removeEventListener移除监听
    • 需要在元素被销毁或移除之前清理事件监听器,以确保事件处理函数不会继续被调用,从而避免潜在的内存泄漏问题
  • 例子
    1
    2
    3
    <p>该实例使用了 addEventListener() 方法向文档中添加点击事件。</p>
    <p>尝试点击文档的任何地方。</p>
    <p id="demo"></p>
    1
    2
    3
    4
    5
    6
    7
    8
    <script>
    // event不用传入即可获取到
    // 不传参则必须命名为event。如果想要传入,则实参和形参都可以自定义名字
    function clickHandle(){
    document.getElementById("demo").innerHTML = "Hello World!" + event;
    }
    document.addEventListener("click", clickHandle);
    </script>

React事件处理

  • 可参考《React知识点汇总(基础使用1)》
  • React 元素的事件处理和 DOM 元素类似。但是有一点语法上的不同:
    • React 事件绑定函数的命名采用驼峰式写法,而不是小写。
  • 在类中书写时注意在构造函数中使用bind()绑定事件函数的this指向。
  • 事件对象:
    • event不用显示传入,但在函数接收参数时需要写明,比如定义函数时接收3个参数id, title, event,实际传参时fn(123, 快乐标题)(可参考《React知识点汇总(基础使用1)>)
    • 可以使用 e(或者任何你喜欢的变量名)作为事件处理函数的参数来接收事件对象
  • 销毁事件:
    • 大多数事件处理函数不需要手动销毁,因为 React 会自动处理事件的绑定和解绑。使用 onClick 等内置的事件处理函数时,React 会在组件挂载时自动为相应的元素添加事件监听器,并自动在组件卸载时自动移除事件监听器,以避免潜在的内存泄漏问题。这是因为 React 实际上是通过合成事件来处理事件的,而不是直接将事件绑定到真实的 DOM 元素上
    • 如果你在 componentDidMount 中添加原生的 DOM 事件,或者在组件挂载后动态地添加了事件监听器,你需要手动在componentWillUnmount的时候移除事件监听器
  • 以onClick举例
    1
    2
    3
    4
    5
    6
    // JSX语法中
    <button onClick={activateLasers}>
    激活按钮
    </button>

    // activateLasers函数另写
  • 具体事例:当使用 ES6 class 语法来定义一个组件的时候,事件处理函数会成为类的一个方法
    例如,Toggle 组件渲染一个让用户切换开关状态的按钮的例子

vue事件处理

  • vue事件函数有没有()都可以(带不带的区别存在于$event传参方式(参考))
    • ()则需要显示传入$event
    • 没有()则隐式传入了$event,可直接获取
    • 注意:实参必须是$event,不能是别的名字,当然,定义形参时可以是你喜欢的名字
  • 销毁事件:
    • 和react一样,大多时候不需要手动销毁
    • 使用 @click 等内置的事件处理函数时,Vue 会在组件渲染时自动为相应的元素添加事件监听器,并在组件销毁时自动移除事件监听器
    • 手动使用原生的 DOM 事件绑定,或者在组件渲染后动态地添加了事件监听器,你需要手动在beforeDestroy中移除事件监听器
  • html例子对应的vue例子:
    1
    2
    3
    4
    5
    <!-- 事件处理函数无()则$event隐式传入 -->
    <div id="div1" @drop="drop" @dragover="allowDrop"></div>
    <br>
    <!-- 事件处理函数有()则$event显示传入 -->
    <img decoding="async" loading="lazy" id="drag1" src="~assets/images/wangwangLogo.png" draggable="true" @dragstart="drag($event)" width="50" height="50">
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    methods: {
    allowDrop(ev) {
    console.log('---allowDrop')
    ev.preventDefault();
    },
    drag(ev) {
    console.log('---drag')
    ev.dataTransfer.setData("Text",ev.target.id);
    },
    drop(ev) {
    console.log('---drop')
    ev.preventDefault();
    let data=ev.dataTransfer.getData("Text");
    ev.target.appendChild(document.getElementById(data));
    },
    }

同时传入自定义参数与event

  • html正常显示传入<button onclick="myFunction(1, event)">点我</button>
  • js使用addEventListener时可使用闭包或者使用bind方法:
    • 方法1:
      1
      2
      3
      4
      5
      6
      7
      8
      // 使用闭包:
      const param1 = 'Hello';
      const param2 = 'World';

      element.addEventListener('click', function(event) {
      // 在这里可以使用 event 对象和其他参数
      console.log(param1, param2, event);
      });
    • 方法2:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      // 使用bind:
      const param1 = 'Hello';
      const param2 = 'World';

      function handleClick(param1, param2, event) {
      // 在这里可以使用 event 对象和其他参数
      console.log(param1, param2, event);
      }

      element.addEventListener('click', handleClick.bind(this, param1, param2));
  • vue正常显示传入<el-button @click="clickBtn(1, $event)">默认按钮</el-button>

, ,