批改状态:合格
老师批语:
<script>// 正常都在主线程里执行 代码的"书写顺序"与"执行顺序" 一致console.log(1);console.log(2);console.log(3);console.log("--------");// 现在给console.log(2) 加一个定时任务console.log(1);// 定时任务: setTimeout(函数,等待时间)// 要等待三秒后才执行,这三秒理论上说,是什么也做不了,代码到这里就"阻塞"setTimeout(() => console.log(2), 3000);// 这个时候 js引擎将 setTimeout(() => console.log(2), 3000); 脱离"主线程",放到了"任务队列"的地方console.log(3);// 当主线程上已没有任务的时候,由"事件循环"将这个任务重新放回到主线程中执行// 定时任务就是一个异步任务,只要是异步任务,就不在主线程执行,到任务队列中,等"事件循环"来找它// 执行机制// 1. 同步任务: 主线程// 2. 异步任务: 任务队列, 由"事件循环"来调度// 哪些是异步任务?// 1. 定时任务, 2. 事件, 3, IO操作(input,output), 4. http请求// 怎么实现异步? 回调函数</script>
<form action=""><input type="text" onkeydown="console.log(this.value);" /><!-- 为什么慢半拍? --><!-- 因为dom渲染是同步任务,keydown事件是异步任务,所以总是获取的上一个数据 --><!-- 解决方案很粗暴,就是异步事件等等,等同步的dom渲染完了再执行 --><input type="text" onkeydown="setTimeout(()=>console.log(this.value),0);" /><!-- <input type="text" oninput="console.log(this.value);" /> --></form>
<body style="display: grid; gap: 0.5em"><!-- 1. 事件属性 --><button onclick="alert('hello')">事件属性</button><!-- 2. 元素对象 --><button>元素对象</button><script>const btn2 = document.querySelector("button:nth-of-type(2)");btn2.onclick = () => console.log(111);btn2.onclick = _ => console.log(222);btn2.onclick = $ => console.log(333); // 会进行覆盖 只会执行这一个// 移除// btn2.onclick = null;</script><!-- 3. 事件监听器 --><button>事件监听器</button><script>const btn3 = document.querySelector("button:nth-of-type(3)");// btn3.addEventListener(事件类型, 事件回调,是否冒泡false/捕获true)let i = 0;btn3.addEventListener("click", () => { i += 0.5;console.log(i)});btn3.addEventListener("click", () => { console.log(i)});btn3.addEventListener("click", () => { console.log(i)}); // 会全部执行// 删除 比较麻烦 只能用 removeEventListener 进行移除 并且添加的匿名函数无法移除let show = () => console.log(444);btn3.addEventListener("click", show);// 删除btn3.removeEventListener("click", show);</script><!-- 4. 事件派发 --><button>事件派发</button><script>const btn4 = document.querySelector("button:nth-of-type(4)");// let i = 0;btn4.addEventListener("click", () => {i += 0.5;console.log("恭喜你, 又赚了: " + i + " 元");});// 4.1创建一个自定义事件const myclick = new Event("click");// 4.2派发 触发自定义事件// btn4.dispatchEvent(myclick);// btn4.dispatchEvent(myclick);// setTimeout: 定时器,用于执行一次性的定时任务// setInterval: 定时器, 用于执行间歇性的定时任务// setInterval(() => btn4.dispatchEvent(myclick), 3000);</script>
在一个对象上触发某类事件,如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序, 那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活)
事件冒泡允许多个操作被集中处理, 把事件处理器添加到一个父级元素上,避免把事件处理器添加到多个子级元素上,
事件冒泡机制有时候是不需要的,需要阻止掉,通过 event.stopPropagation() 来阻止。
事件委托:就是利用冒泡的原理,把事件加到父级上,通过判断事件来源的子集,执行相应的操作,事件委托首先可以极大减少事件绑定次数,提高性能;其次可以让新加入的子元素也可以拥有相同的操作。 事件委托的关系是将子元素的事件委托到父元素上。
<!-- event: 事件对象 --><button onclick="show(event)">click</button><ul><li>item1</li><li>item2</li><li>item3</li><li>item4</li><li>item5</li></ul><script>function show(ev) {// ev: 事件对象// console.log(ev);// ev中有二个特别重要的属性// 1. 事件绑定者(主体) currentTarget// console.log(ev.currentTarget);// 2.事件触发者(目标) target// console.log(ev.target);// console.log(ev.target === ev.currentTarget); //返回 true}const lis = document.querySelectorAll("li");// 循环给每一个li添加点击事件// lis[0].onclick = function(){alert(111)}lis.forEach(function (li) {li.onclick = function (ev) {console.log(ev.target);};});// lis.forEach(li => (li.onclick = ev => console.log(ev.currentTarget)));// onclick这种通过 事件属性 的添加的事件,是冒泡事件// 冒泡: 子元素的同名事件,会沿着dom树向上逐级触发上级元素的同名事件// 获取 html === document.documentElement// 事件委托:document.querySelector("ul").onclick = (ev) => {// 1.事件绑定者// console.log(ev.currentTarget);// 2. 事件触发者// console.log(ev.target);// console.log(ev.target.textContent);// console.log(ev.target === ev.currentTarget); //返回false};</script>
<!-- 阻止默认行为 :event.preventDefault() 阻止冒泡事件 : event.stopPropagation()上述两个操作可以合并为:return false; --><form action="" method="post" id="login" onsubmit="return false"><label class="title">用户登录</label><label for="email">邮箱:</label><input type="email" id="email" name="email" value="" autofocus /><label for="password">密码:</label><input type="password" id="password" name="password" /><button name="submit">登录</button></form><script>// formconst login = document.forms.login;// submit: 提交事件 这里直接提交会报错 表单有一个默认的提交行为 推荐用 禁用默认行为 onsubmit="return false"// login.onsubmit = () => console.log("提交了");// 这个也可以 禁用表单的提交行为// 阻止默认行为 event.preventDefault()// login.onsubmit = ev => ev.preventDefault();// 为什么要禁用原生的提交行为?因为我想在提交进行验证和处理login.submit.onclick = ev => {// 阻止冒泡事件 : event.stopPropagation()ev.stopPropagation();// 每个表单元素都有一个form属性,与所属的表单绑定console.log(ev.currentTarget.form);// 非空验证isEmpty(ev.currentTarget.form);};function isEmpty(form) {if (form.email.value.length === 0) {alert("邮箱不能为空");form.email.focus();return false;} else if (form.password.value.trim().length === 0) {alert("密码不能为空");form.email.focus();return false;} else {alert("验证通过");}}</script>
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号