事件监听Event listener

指使计算机能随时发现事件的发生

设置事件监听

DOM0级事件监听-只能监听冒泡

oBox. onxxx=function(){
}

DOM2级事件监听-捕获&冒泡皆可监听

// 事件名click不加on
oBox.addEventListener('click', function () {
}, true);

其中,true监听捕获阶段;false监听冒泡阶段
IE6~8 不支持 addEventListener

事件监听类型

鼠标事件监听

事件名事件描述
onclick当鼠标单击某个对象
ondblclick当鼠标双击某个对象
onmousedown当某个鼠标按键在某个对象上被按下
onmouseup当某个鼠标按键在某个对象上被松开
onmousemove当某个鼠标按键在某个对象上被移动
onmouseenter当鼠标进入某个对象(相似事件onmouseover)
onmouseleave当鼠标离开某个对象(相似事件onmouseout)
<style>
	.box {
	    width: 200px;
	    height: 200px;
	    background-color: red;
	}
</style>

<body>
	<div class='box' id="box"></div>
	<script>
		var oBox = document.getElementById('box');
		oBox.onclick = function () {
		    alert('你好,我是点击事件函数');
		}
	</script>
</body>

键盘事件监听

事件名事件描述
onkeypress当某个键盘的键被按下(系统按钮如箭头键和功能键无法得到识别)
onkeydown当某个键盘的键被按下(系统按钮可以识别,并且会先于onkeypress发生)
onkeyup当某个键盘的键被松开

案例- 按键移动盒子

<div id="box"></div>
    <script>
        var oBox = document.getElementById('box');
        // t表示盒子的top属性值
        // l表示盒子的left属性值
        var t = 200;
        var l = 200;
        document.onkeydown = function (e) {
            switch (e.keyCode) {
                case 37:
                    l -= 3;
                    break;
                case 38:
                    t -= 3;
                    break;
                case 39:
                    l += 3;
                    break;
                case 40:
                    t += 3;
                    break;
            }
            oBox.style.top = t + 'px';
            oBox.style.left = l + 'px';
        }
    </script>

表单事件监听

事件名事件描述
onchange当用户改变域的内容
onfocus当某元素获得焦点(比如tab键或鼠标点击)
onblur当某元素失去焦点
onsubmit当表单被提交
onreset当表单被重置
<body>
 <form id='myform' action="">
        <p>
            姓名:
            <input type="text" name="nameField">
        </p>
        <p>
            年龄:
            <input type="text" name="ageField">
        </p>
        <p>
            <input type="submit">
        </p>
    </form>
    <script>
        var myform = document.getElementById('myform');
        // 表单的name属性打点调用
        var nameField = myform.nameField;
        var ageField = myform.ageField;
        nameField.onchange = function () {
            console.log('您修改了姓名');
        }
        nameField.oninput = function () {
            console.log('您正在修改姓名');
        }
        nameField.onfocus = function () {
            console.log('姓名框已得到焦点');
        }
        nameField.onblur = function () {
            console.log('姓名框已失去焦点');
        }
        myform.onsubmit = function () {
            console.log("您正在提交表单");
        }
    </script>
</body>

页面事件监听

事件名事件描述
onload当页面或图像被完成加载
onunload当用户退出页面
*更多有关窗口或页面的事件在BOM课程中介绍

事件传播(先从外到内,再从内到外)

观察

 <style>
      #box1 {
        width: 202px;
        height: 202px;
        border: 1px solid black;
        padding: 50px;
      }

      #box2 {
        width: 100px;
        height: 100px;
        border: 1px solid black;
        padding: 50px;
      }

      #box3 {
        width: 100px;
        height: 100px;
        border: 1px solid black;
      }
</style>
<body>
   <div id="box1">
     <div id="box2">
       <div id="box3"></div>
     </div>
   </div>
   <script>
     var oBox1 = document.getElementById("box1");
     var oBox2 = document.getElementById("box2");
     var oBox3 = document.getElementById("box3");
     // 打乱监听事件函数顺序,结果依然如此
     //事件传播从内到外,与监听事件函数顺序无关
     oBox2.onclick = function () {
       console.log("我是box2的onclick");
     };
     oBox3.onclick = function () {
       console.log("我是box3的onclick");
     };
     oBox1.onclick = function () {
       console.log("我是box1的onclick");
     };
   </script>
</body>

观察结果:从内到外;不确切,因为DOM0级事件只能监听冒泡阶段
实际结论:先从外到内,然后再从内到外

最内部元素不区分捕获和冒泡阶段

执行结果:
在这里插入图片描述

 oBox1.addEventListener(
    "click",
    function () {
      console.log("我是box1的捕获阶段");
    },
    true
  );
  oBox2.addEventListener(
    "click",
    function () {
      console.log("我是box2的捕获阶段");
    },
    true
  );

  oBox3.addEventListener(
    "click",
    function () {
      console.log("我是box3的捕获阶段");
    },
    true
  );

  oBox1.addEventListener(
    "click",
    function () {
      console.log("我是box1的冒泡阶段");
    },
    false
  );
  oBox2.addEventListener(
    "click",
    function () {
      console.log("我是box2的冒泡阶段");
    },
    false
  );
  oBox3.addEventListener(
    "click",
    function () {
      console.log("我是box3的冒泡阶段");
    },
    false
  );

同名事件互相覆盖问题

若给元素设置相同的两个或多个同名事件,
DOM0级写法后面写的会覆盖先写的;
而DOM2级会按顺序执行

事件对象

事件处理函数提供一个形式参数,它是一个对象,封装了本次事件的细节
这个参数通常用单词event或字母e来表示

oBox.onmousemove = function (e) {
      //对象e就是这次事件的“事件对象”
  };

鼠标位置

属性属性描述
clientX鼠标指针相对于浏览器的水平坐标
clientY鼠标指针相对于浏览器的垂直坐标
pagex鼠标指针相对于整张网页的水平坐标
pageY鼠标指针相对于整张网页的垂直坐标
offsetX鼠标指针相对于事件源元素的水平坐标
offsetY鼠标指针相对于事件源元素的垂直坐标

e.charCode

表示用户输入字符的“字符码”
通常用于onkeypress事件中

字符字符码
0~948~57
A~Z65~90
a~z97~122

e.keyCode

表示用户按下按键的“键码”
通常用于onkeydown事件和onkeyup中

按键键码
0~948~57
a~z(不分大小写)65~90
方向键(左、上、右、下)37、38、39、40
回车键13
空格键32
<body>
    <input id='field1' type="text">
    <h1 id='info1'></h1>
    <input id='field2' type="text">
    <h1 id='info2'></h1>
    <script>
        var oField1 = document.getElementById('field1');
        var oInfo1 = document.getElementById('info1');
        var oField2 = document.getElementById('field2');
        var oInfo2 = document.getElementById('info2');
        oField1.onkeypress = function (e) {
            oInfo1.innerText = '您输入的字符的字符码是' + e.charCode;
        }
        oField2.onkeydown = function (e) {
            oInfo2.innerText = '您按下的按键的键码是' + e.keyCode;
        }
     </script>
</body>

e.preventDefault()-阻止默认动作

1)DOM2级
e.preventDefault()
2)DOM0级
最后加:return false;
例:阻止表单默认动作


      Form.onsubmit = function () {
        return false;
      }; //可阻止默认提交动作

案例-当标在盒子中向下滚动,数字加1;反之,数字减1
onmousewheel鼠标滚轮事件
deltaY属性表示鼠标滚动方向,向下滚动时返回正值,向上滚动时返回负值

<div id="box"></div>
<h1 id="info">0</h1>
<script>
  var oBox = document.getElementById("box");
  var oInfo = document.getElementById("info");
  var a = 0;
  oBox.onmousewheel = function (e) {
    /* 页面较长时,使用阻止默认事件
    即用户在盒子内部滚动鼠标滚轮时,不会引发页面滚动条的滚动 */
    e.preventDefault();
    if (e.deltaY > 0) {
      a--;
    } else {
      a++;
    }
    oInfo.innerText = a;
  };
</script>

e.stopPropagation()-阻止继续传播

在一些场合,非常有必要切断事件继续传播,否则会造成页面特效显示出bug
案例

<style>
  #box {
    width: 200px;
    height: 200px;
    background-color: red;
  }
</style>

<body>
	<div id="box">
		<button id="btn">按我</button>
	</div>
	<script>
		 var oBox = document.getElementById("box");
		 var oBtn = document.getElementById("btn");
		 //   oBox.onclick = function () {
		 //     console.log("我是盒子");
		 //   };
		 //   oBtn.onclick = function (e) {
		 //     //阻止冒泡-点击btn只打印我是按钮
		 //     e.stopPropagation();
			 //     console.log("我是按钮");
			 //   };
		 oBox.addEventListener(
		   "click",
		   function (e) {
		     // 阻止捕获-点击btn只打印我是盒子
		     e.stopPropagation();
		     console.log("我是盒子");
		   },
		   true
		 );
		 oBtn.addEventListener(
		   "click",
		   function () {
		     console.log("我是按钮");
		   },
		   true
		 );
	</script>
</body>

事件委托

性能问题

作用1-批量添加事件监听

每一个事件监听注册都会消耗一定的系统内存,而批量添加事件监听数量太多,导致内存消耗更大
例如:每个<1i>的事件处理函数都是不同的函数,占用更多内存

<ul id="list">
  <li>列表项</li>
  <li>列表项</li>
  <li>列表项</li>
  <li>列表项</li>
</ul>
<script>
  var oList = document.getElementById("list");
  var lis = oList.getElementsByTagName("li");
  // 循环语句,给元素批量添加监听
  for (var i = 0; i < lis.length; i++) {
    lis[i].onclick = function () {
      //this指代点击的元素
      this.style.color = "red";
    };
  }
</script>

作用2-实现自动绑定事件

新增元素不能自动获得事件监听
原理:利用事件冒泡机制,将后代元素事件委托给祖先元素

e.target-事件源元素

触发此事件的最早元素,即“事件源元素”

e.currentTarget-事件处理程序附加到的元素

使用场景

1)需要批量添加事件监听时
2)当有动态元素节点上树时
例1:点击任一个li元素,事件都会通过冒泡传递给祖先元素

<body>
    <button id="btn">按我添加新的li列表项</button>
    <ul id="list">
      <li>默认项</li>
      <li>默认项</li>
      <li>默认项</li>
    </ul>
    <script>
      var oBtn = document.getElementById("btn");
      var oList = document.getElementById("list");
      oList.onclick = function (e) {
        // e.target表示用户真正点击的那个元素
        e.target.style.color = "red";
      };
      oBtn.onclick = function () {
        var oLi = document.createElement("li");
        oLi.innerText = "我是新来的";
        oList.appendChild(oLi);
      };
    </script>
</body>

例2:

<button id="btn">按我添加新的li列表项</button>
<ul id="list">
	<li>默认项</li>
	<li>默认项</li>
	<li>默认项</li>
</ul>
<script>
	var oList = document.getElementById("list");
	var oBtn = document.getElementById("btn");
	// onmouseenter不冒泡
	//相当于事件处理函数直接附加给了DOM节点
	oList.onmouseenter = function (e) {
	// e.target表示用户真正点击的那个元素
		e.target.style.color = "red";
	};
	oBtn.onclick = function () {
		// 创建新的li元素
		var oLi = document.createElement("li");
		// 写内容
		oLi.innerText = "我是新来的";
		// 上树
		oList.appendChild(oLi);
	};
</script>

onmouseenter&onmouseover
都表示“鼠标进入"
区别:onmouseenter不冒泡,onmouseover冒泡。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值