吴志勇的博客 吴志勇的博客
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

吴志勇

......
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML5&CSS3

  • CSS预处理语言

  • JavaScript

    • JavaScript

      • 01 【基础语法与基本数据类型】
      • 02 【JS表达式与操作符】
      • 03 【流程控制语句】
      • 04 【对象】
      • 05 【函数(上)】
      • 06 【函数(下)】
      • 07 【数组及常用方法】
      • 08 【标准库之Date对象】
      • 09 【标准库之Math对象和String对象】
      • 10 【标准库之RegExp对象】
      • 11 【标准库之JSON对象 JSON5】
      • 12 【语法之错误处理机制】
      • 13 【语法之编程风格】
      • 14 【语法之console 对象与控制台】
      • 15 【严格模式】
      • 16 【DOM概述】
      • 17 【Document 节点】
      • 18 【节点的关系和内部操作】
      • 19 【节点的增删改查】
      • 20 【节点的集合】
      • 21【节点的属性】
      • 22 【事件监听】
      • 23 【事件对象与鼠标事件】
      • 24 【键盘事件】
      • 25 【进度事件和表单事件】
        • 1.文档的加载
        • 2.进度事件的种类
        • 3.表单事件的种类
          • 3.1 input 事件
          • 3.2 select 事件
          • 3.3 change 事件
          • 3.4 invalid 事件
          • 3.5 reset 事件,submit 事件
      • 26 【触摸事件和其它常见事件】
      • 27 【三大家族scroll、offset、client】
      • 28 【事件传播】
      • 29【定时器和延时器】
      • 30【BOM和浏览器环境概述】
      • 31【window 对象】
      • 32 【Navigator 对象和Screen 对象】
      • 33 【History对象和Location对象】
      • 34 【表单和FormData 对象】
      • 35【Storage接口】
      • 36 【节流和防抖】
    • 01 【AJAX概述和基本使用】
    • jquery
    • ES6教程

  • nodejs

  • webpack

  • VUE

  • react

  • Typescript
  • 前端
  • JavaScript
  • JavaScript
wuzhiyong
2024-09-22

25 【进度事件和表单事件】

# 25 【进度事件和表单事件】

# 1.文档的加载

浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。 如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载, 此时将会无法正常获取到DOM对象,导致DOM操作失败。

解决方式一: 可以将js代码编写到body的下边

<body>  
		<button id="btn">按钮</button>  
  
		<script>  
			var btn = document.getElementById("btn");  
			btn.onclick = function(){  
		  
			};  
	</script>  
</body>
1
2
3
4
5
6
7
8
9
10

解决方式二: 将js代码编写到window.onload = function(){}中 window.onload对应的回调函数会在整个页面加载完毕以后才执行, 所以可以确保代码执行时,DOM对象已经加载完毕了

<script>  
    window.onload = function(){  
        var btn = document.getElementById("btn");  
        btn.onclick = function(){  
        };  
    };  
</script>
1
2
3
4
5
6
7

# 2.进度事件的种类

进度事件用来描述资源加载的进度,主要由 AJAX 请求、<img>、<audio>、<video>、<style>、<link>等外部资源的加载触发,继承了ProgressEvent接口。它主要包含以下几种事件。

  • abort:外部资源中止加载时(比如用户取消)触发。如果发生错误导致中止,不会触发该事件。
  • error:由于错误导致外部资源无法加载时触发。
  • load:外部资源加载成功时触发。
  • loadstart:外部资源开始加载时触发。
  • loadend:外部资源停止加载时触发,发生顺序排在error、abort、load等事件的后面。
  • progress:外部资源加载过程中不断触发。
  • timeout:加载超时时触发。

注意,除了资源下载,文件上传也存在这些事件。

下面是一个例子。

image.addEventListener('load', function (event) {
  image.classList.add('finished');
});

image.addEventListener('error', function (event) {
  image.style.display = 'none';
});
1
2
3
4
5
6
7

上面代码在图片元素加载完成后,为图片元素添加一个finished的 Class。如果加载失败,就把图片元素的样式设置为不显示。

有时候,图片加载会在脚本运行之前就完成,尤其是当脚本放置在网页底部的时候,因此有可能load和error事件的监听函数根本不会执行。所以,比较可靠的方式,是用complete属性先判断一下是否加载完成。

function loaded() {
  // ...
}

if (image.complete) {
  loaded();
} else {
  image.addEventListener('load', loaded);
}
1
2
3
4
5
6
7
8
9

由于 DOM 的元素节点没有提供是否加载错误的属性,所以error事件的监听函数最好放在<img>元素的 HTML 代码中,这样才能保证发生加载错误时百分之百会执行。

<img src="/wrong/url" onerror="this.style.display='none';" />
1

loadend事件的监听函数,可以用来取代abort事件、load事件、error事件的监听函数,因为它总是在这些事件之后发生。

req.addEventListener('loadend', loadEnd, false);

function loadEnd(e) {
  console.log('传输结束,成功失败未知');
}
1
2
3
4
5

loadend事件本身不提供关于进度结束的原因,但可以用它来做所有加载结束场景都需要做的一些操作。

另外,error事件有一个特殊的性质,就是不会冒泡。所以,子元素的error事件,不会触发父元素的error事件监听函数。

# 3.表单事件的种类

# 3.1 input 事件

input事件当<input>、<select>、<textarea>的值发生变化时触发。对于复选框(<input type=checkbox>)或单选框(<input type=radio>),用户改变选项时,也会触发这个事件。另外,对于打开contenteditable属性的元素,只要值发生变化,也会触发input事件。

input事件的一个特点,就是会连续触发,比如用户每按下一次按键,就会触发一次input事件。

input事件对象继承了InputEvent接口。

该事件跟change事件很像,不同之处在于input事件在元素的值发生变化后立即发生,而change在元素失去焦点时发生,而内容此时可能已经变化多次。也就是说,如果有连续变化,input事件会触发多次,而change事件只在失去焦点时触发一次。

下面是<select>元素的例子。

/* HTML 代码如下
<select id="mySelect">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
</select>
*/

function inputHandler(e) {
  console.log(e.target.value)
}

var mySelect = document.querySelector('#mySelect');
mySelect.addEventListener('input', inputHandler);
1
2
3
4
5
6
7
8
9
10
11
12
13
14

上面代码中,改变下拉框选项时,会触发input事件,从而执行回调函数inputHandler。

# 3.2 select 事件

select事件当在<input>、<textarea>里面选中文本时触发。

// HTML 代码如下
// <input id="test" type="text" value="Select me!" />

var elem = document.getElementById('test');
elem.addEventListener('select', function (e) {
  console.log(e.type); // "select"
}, false);
1
2
3
4
5
6
7

选中的文本可以通过event.target元素的selectionDirection、selectionEnd、selectionStart和value属性拿到。

# 3.3 change 事件

change事件当<input>、<select>、<textarea>的值发生变化时触发。它与input事件的最大不同,就是不会连续触发,只有当全部修改完成时才会触发,另一方面input事件必然伴随change事件。具体来说,分成以下几种情况。

  • 激活单选框(radio)或复选框(checkbox)时触发。
  • 用户提交时触发。比如,从下列列表(select)完成选择,在日期或文件输入框完成选择。
  • 当文本框或<textarea>元素的值发生改变,并且丧失焦点时触发。

下面是一个例子。

// HTML 代码如下
// <select size="1" onchange="changeEventHandler(event);">
//   <option>chocolate</option>
//   <option>strawberry</option>
//   <option>vanilla</option>
// </select>

function changeEventHandler(event) {
  console.log(event.target.value);
}
1
2
3
4
5
6
7
8
9
10

如果比较一下上面input事件的例子,你会发现对于<select>元素来说,input和change事件基本是等价的。

# 3.4 invalid 事件

用户提交表单时,如果表单元素的值不满足校验条件,就会触发invalid事件。

<form>
  <input type="text" required oninvalid="console.log('invalid input')" />
  <button type="submit">提交</button>
</form>
1
2
3
4

上面代码中,输入框是必填的。如果不填,用户点击按钮提交时,就会触发输入框的invalid事件,导致提交被取消。

# 3.5 reset 事件,submit 事件

这两个事件发生在表单对象<form>上,而不是发生在表单的成员上。

reset事件当表单重置(所有表单成员变回默认值)时触发。

submit事件当表单数据向服务器提交时触发。注意,submit事件的发生对象是<form>元素,而不是<button>元素,因为提交的是表单,而不是按钮。

上次更新: 2024-09-30 01:09:25

← 24 【键盘事件】 26 【触摸事件和其它常见事件】→

Copyright © 2020-2025 wuzhiyong
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式