异步编码笔记

异步编码和事件

事件是什么?

用户单击按钮\鼠标位置发生变化\通过网络搜集数据\窗口大小发生变化\定时器到期\浏览器位置发生变化. 这些都会出发事件

不必处理所有事件,只需处理在意的事件.

事件处理程序

我们编写处理程序来处理事件

从代码角度看,处理程序就是一段函数. 事件发生时, 其处理程序函数就会被调用.

为了让处理程序在事件发生时被调用, 你首先要注册它. 注册的方式有多种, 具体采用哪种取决于事件的类型.

创建事件处理程序的方法

    let image = document.getElementById("zero");
    image.addEventListener("click", showAnswer); //这里是click不是onclick; 而且, 这里没有().
    
    function showAnswer() {
        image.src = "zero.jpg";
    }
    var image = document.getElementById("zero");
    image.onclick = showAnswer; // 这里是onclick, 不是click; 同时,这里没有()
    
    function showAnswer() {
        var image = document.getElementById("zero");
        image.src = "zero.jpg";
    }
<body>
    <img id="zero" src="https://ftp.bmp.ovh/imgs/2020/09/008c66919d994041.jpg" onclick="showAnswer()"> //这里是调用函数,需要加括号
        
    <script type="text/javascript">
        function showAnswer() {
            var image = document.getElementById("zero");
            image.src = "https://ftp.bmp.ovh/imgs/2020/09/9ee7bcf72b2d1a0a.jpg";
        }
    </script>
</body>

同样是用函数showAnswer

  1. 方法2是引用函数,所以函数名称后不加括号。

  2. 方法3是在html中调用函数,函数名称后要加括号。

  3. 两张图片的地址:

模糊图片
清晰图片

  1. onload 是 window 对象的一个属性
  2. 事件对象有属性也有方法
  3. 不编写函数的情况下,不能注册事件处理程序

异步的概念和编码思路

以响应事件的方式组织代码, 需要考虑对可能发生的事件以及代码应该如何响应这些事件. 通常说,这种代码是异步的.

异步编码仅在相应的事件发生时,才会被调用.

异步编码方式,不再逐步的编写代码来实现算法, 而是将处理各种事件的众多程序整合起来,构成一个应用程序.

单击改变图片链接的案例

大体步骤

  1. 访问DOM这个图像对象, 并将其属性onclick设置为处理程序

    1. 需要保证网页加载完毕并创建DOM之后再运行, 因此要使用 window.onload(如果script链接放在body标签的末尾, 则可省略此步骤)
    2. 在JavaScript中函数的定义函数的顺序不重要.
  2. 在这个处理程序中编写代码, 改变图片的链接地址(可以是本地地址, 也可以是URL地址)

    1. 在window.onlad和事件处理程序showAnswer中都需要调用document.getElementById("zero");这是因为window.onload在页面加载完成后执行,但是showAnswer是在用户单击图片的时候才被调用. 因此必须在两个函数中都写通过id获取元素的代码.

    模糊图片URL链接    清晰图片URL链接

    1. 设置图片的src属性和通过代码setAttribute("src","https://s1.ax1x.com/2020/09/22/wqsSPA.jpg")得到的结果是一样的, 但不是所有的元素都有src属性, 也不是所有的属性都能用元素.属性名="设定值";的方法修改.因此对那些不能用赋值的方式更改属性的情况, 可以用getAttribute()方法来获取属性; 通过setAttribute()方法来设置属性

一个处理程序解决所有的图片

通过元素标签获取元素

方法1: var image=document.getElementsByTagName("img");
方法2: var images=document.querySelectorAll("img"); (书中并没有介绍方法2, 以下的说明都是针对"方法1"展开的;通过方法2改变元素属性,也需要像方法以一样借助循环完成)

  1. 返回的是类似于数组的对象列表
  2. 在Elements中有一个s, 这以为着可能得到的是多个元素(也可能只是一个元素)
  3. 用引号 "" 将标签名括起, 但不包含 < >

几乎可以给任意元素设定单击处理程序, 不是必须按钮或者链接; 不在网页中显示出来的元素, 不支持单击事件, 比如 script head

触发事件的元素, 被称为目标(target). 例如: 用户单击特定图像时, 这个图像就是目标

处理程序的形参可以是事件对象, 而触发事件的目标就是事件对象的target属性

大多数文档对象模型(DOM)事件发生时, 都会向事件处理程序传递一个事件对象. 事件对象包含一些有关事件的常规信息,如事件是哪个元素触发的; 以及事件是何时发生的等等. 你还将获得事件的特有信息, 比如用户单击鼠标的位置坐标

注意: 在IE8或更低版本中,不能用这种方法获取事件对象.需要用其他方法.

事件对象的常见属性

| 名称 | 用途 |
|::|::|
|target|存储触发事件的对象.可以是不同的对象,通常是元素对象|
|type|是一个字符串,如"click","load"指出了发生的是哪种事件|
|timeStamp|事件是何时发生的|
|keyCode|刚按下了哪个键(事件是onkeypress和onkeydown有很大区别,详见OneNote笔记和菜鸟教程)|
|clientX|距离浏览器窗口的左边缘有多远|
|clientY|距离浏览器窗口的上边缘有多远|
|touches|在触屏设备上,可用来确定用户用了多少根手指来触摸屏幕|
|button|鼠标的按键(0=左键;1=中键;2=右键...)|

事件和列队

事件几乎在不间断的发生, 只需处理需要的事件即可

事件会被放入列队, 再遍历这个列队, 并在必要时调用处理程序

必须按照列队一个一个的处理.JavaScript只有一个事件列队和一个控制线程.但是多个目标对象可以异步

浏览器依照列队逐步处理每个事件, 因此要尽可能的让处理程序简短而高效

有基于网络的事件\定时器事件\与网页相关的DOM事件\与浏览器相关的BOM事件等

学好事件非常重要

其他事件

鼠标除了单击双击事件之外, 还有很多

常用DOM事件列表

属性 属性说明
onclick 鼠标单击
ondbclick 鼠标双击
oncontextmenu 鼠标右键打开上下文菜单时触发
onmousedown 鼠标按键按下
onmouseup 鼠标按键松开
onmouseenter 鼠标移动到元素上时
onmouseleave 鼠标移出元素
onmousemove 鼠标移动
onmouseover 鼠标移到某元素上
onmouseout 鼠标从某元素移开

键盘的事件

属性 属性说明
onkeypress 某个键被按下,然后松开
onkeydown 某个键被按下
onkeyup 某个键被松开

键盘的按键相对比较复杂,其中涉及到onkeypress 属性的用法, 和keyCode 事件属性. 在键盘代码转换过程中,还涉及到 Unicode 值的转换方法fromCharCode() 方法

如果你想查看是否按下了 "ALT", "CTRL", "META""SHIFT" 键,可使用 altKey, ctrlKey, metaKeyshiftKey 属性

setTimeout() 的工作原理

setTimeout(code/function, milliseconds, param1) 里面有三个参数

code/function 表示时间间隔之后需要执行的代码。

milliseconds 表示执行代码之前的时间间隔, 这里的单位是毫秒

param1/param2/... 表示传递给函数的参数

前两个参数必须要有,最后一个参数根据情况设置

浏览器跟踪所有的定时器(可以同时有多个定时器)及其需要调用的处理程序

倒计时结束,触发了时间事件. 浏览器调用你传入的函数, 以执行相应的事件处理程序.

当调用处理程序之后, 对定时器的处理到此结束

使用 setTimeout 时,向一个函数传递了另一个函数

我们定义了一个函数,再将他传递给setTimeout(它实际上是个方法)

从本质上说, 函数setTimtout创建了一个倒计时的定时器, 并将其关联了一个处理程序. 当定时器倒计时到零后,将调用这个处理程序. 为告诉setTimeout应调用哪个定时器,需要向他传递一个指向处理程序函数的引用.

其他语言中, 向函数传递函数的方法可能是不行的, 但是JavaScript是支持这样的方式. 尤其是在编写响应式代码的时候,经常会用到.

setTimeout 是window全局对象的一个方法, 因此省略写作setTimeout

window.onload 也可以省略写作onload. 但因为考虑到图片等各种媒体文件的onload方法, 所以通常不做省略, 还是会写作window.onload

可以创建任意数量的定时器

P412 的例子中, 将第三个参数传递给执行函数. 需要复习阅读.

事件对象主要用于DOM事件处理程序. setTimeout 不向事件处理程序传递对象, 因为时间事件并非由特定的元素触发.

P412 的例子中showAnswer 是一个处理程序, 并且在其程序内,创建了另一个处理程序rebulr

setInterval() 方法

setInterval(code/function, milliseconds, param1) 里面有三个参数

code/function 表示时间间隔之后需要执行的代码。

milliseconds 表示执行代码之前的时间间隔, 这里的单位是毫秒

param1/param2/... 表示传递给函数的参数

间断的循环一个函数, 直到用 clearInterval 方法让其停止

停止 setInterval 的例子

<script>
var myVar = setInterval(function(){ myTimer() }, 1000);

function myTimer() {
    var d = new Date();
    var t = d.toLocaleTimeString();
    document.getElementById("demo").innerHTML = t;
}

function myStopFunction() {
    clearInterval(myVar);
}
</script>

在js中, 很多事件都是DOM事件(如单击触发事件)或定时器事件. 此外, 还有与API相关的事件, 如Geolocation\LocalStorage\Web Worker 等JavaScript API触发事件. 最后还有一系列的I/O相关事件,例如使用XmlHttpRequest向Web服务器请求数据时引发的事件以及使用Web套接字引发的事件.

要点

  • 大多数JavaScript代码都是用来响应事件的
  • 可编写代码来响应事件类型众多
  • 要响应事件, 可以编写并注册一个事件处理程序. 例如, 要指定事件处理程序, 可将事件处理程序付给元素的onclick属性.
  • 浏览器并非响应所有的事件, 可以只处理你感兴趣的事件.
  • 我们将函数用作事件处理程序, 因为它们能够让你编写事件发生时再执行的代码
  • 编写处理事件的代码不同于从头到尾执行的代码. 事件处理程序的运行时间和运行顺序都是不确定的, 他们是异步的.
  • 发生在DOM元素上的事件(DOM事件)导致一个event传递给事件处理程序
  • enent对象(事件对象)包含一些属性,这些属性提供了有关事件的额外信息, 其中包括事件的类型("click"或"onload")和目标(触发事件的对象).
  • 对于较旧版本的IE浏览器, 其处理事件的方式与书中不同, 需要时再另外处理
  • 可能在短时间内发生很多事件. 发生的事件太多, 浏览器无法实时处理, 这些事件将会按照发生的顺序存储到事件列队中, 让浏览器能够依次调用每个事件处理程序
  • 浏览器每次只能执行一个事件处理程序
  • 函数setTimeout和setInterval都用于创建在指定时间过后发生的事件
  • 方法getElementsByTagName返回一个NodeList, 其中包含0个\1个或更多个元素对象. NodeList类似与数组, 你可以对其进行迭代.

事件群英谱

事件 事件说明
click 在网页中单击(或轻按)时触这个事件
resize 每当用户调整浏览器大小时,都将触发这个事件
load 浏览器加载网页完成触发的事件
unload 用户关闭浏览器窗口或切换到其他网页时,将触发这个事件
play 用户单击网页中<video>元素的播放按钮时,将触发这个事件
pause 用户单击<video>元素的暂停按钮时,将触发这个事件
dragstart 用户拖拽网页中的元素时,将触发这个事件
drop 用户放下拖拽的元素时
mousemove 在元素上移动鼠标时
mouseover 用户将鼠标指向元素时,将触发这个事件
mouseout 用户将鼠标从元素上移开时将触发这个事件
keypress 用户按下任何键,都将触发这个事件
touchstart 在触摸设备上,用户触摸并按住元素时,将触发这个事件
touchend 用户停止触摸时,将触发这个事件
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容