DOM

本文详细介绍了DOM的概念、应用场景和标准,强调了DOM在网页内容操作中的重要性。通过DOM树的概念,解释了如何查找元素,包括按节点关系、HTML特征、选择器等方法。此外,还探讨了DOM中的添加删除元素、属性管理和样式修改,以及常用DOM对象如Image、Select和Table的操作。同时,文章还涉及了BOM(浏览器对象模型),讲解了window对象的角色、历史管理和位置信息。最后,详细讨论了事件处理,包括事件模型、事件对象和事件绑定的各种方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.概述

1.概念

Document Object Model专门操作网页内容的一套对象和函数的集合
JS=ECMAScript + DOM + BOM 核心语法+操作网页+操作浏览器软件

2.场景

今后只要操作网页的内容,都用DOM。

3.DOM标准

DOM其实是一套对象和函数的标准——W3C制定
统一所有浏览器开发网页内容的标准;几乎所有浏览器100%兼容DOM标准

4.方法

增删改查元素 + 事件处理

二.DOM树

1.概念

内存中,保存当前网页中所有内容的树形结构

2.使用原因

树形结构是最直观的存储上下级包含关系的结构。而网页中的所有元素内容都是上下级包含关系的。

3.结构

1)当浏览器读到网页时,先在内存中创建网页的根节点对象:document
2)浏览器按从上到下的顺序读取网页内容,每读到一项网页内容,就创建一个节点对象,并挂到指定父节点下。

三.查找元素

1.不需要查找就可直接获得的元素

1)根节点对象:document
2)元素:document.documentElement
3)元素:document.head
4)元素:document.body

2.按节点间关系查找

(1)使用场景

如果已经获得一个节点对象,找周围附近的节点对象时

(2)方法

1)节点树:包含所有网页内容的完整树结构
①父子关系
a.获得一个元素的父节点:节点.parentNode
b.获得一个元素的所有直接子节点: 节点.childNodes
返回多个直接子节点组成的类数组对象;可用下标访问指定位置的子节点
c.获得一个元素的第一个直接子节点: 节点.firstChild
d.获得一个元素的最后一个直接子节点: 节点.lastChild
②兄弟关系
a.获得当前元素相邻的前一个兄弟节点: 节点.previousSibling
b.获得当前元素相邻的后一个兄弟节点: 节点.nextSibling
③弊端:节点树包含所有节点,包括看不见的空字符节点,给查找元素造成了极大的障碍,
程序员只关心元素节点。不关心文字节点
2)元素树:仅包含元素节点的树结构
①父子关系
a.获得一个元素的父元素:元素.parentElement
b.获得一个元素的所有直接子元素: 元素.children
返回多个直接子节点组成的类数组对象;可用下标访问指定位置的子节点
c.获得一个元素的第一个直接子元素: 元素.firstElementChild
d.获得一个元素的最后一个直接子元素: 元素.lastElementChild
②兄弟关系
a.获得当前元素相邻的前一个兄弟元素: 元素.previousElementSibling
b.获得当前元素相邻的后一个兄弟元素: 元素.nextElementSibling
③优点:不包含看不见的空字符,不会受到空字符的干扰

DOM Tree Hello

标题一

### (4)缺点 按节点间关系查找,必须先有一个节点,才能找周围的关系

3.按HTML特征查找

(1)使用场景

在还未获得元素的情况下,执行首次查找,都用按HTML特征查找

(2)方法

1)按id查找一个元素
var elem=document.getElementById(“id值”);
①必须用document调用
②只能找到一个符合条件的元素;万一有两个id一样,只能找第一个
2)按标签名查找多个元素
var elems=任意父元素.getElementsByTagName(“标签名”);
①可以用任意父元素调用;用哪个父元素调用就只在哪个父元素下查找
②返回多个元素组成的类数组对象
③不仅查找直接子元素,且查找所有后代
3)按class名查找多个元素
var elems=任意父元素.getElementsByClassName(“class名”);
①可以用任意父元素调用;用哪个父元素调用就只在哪个父元素下查找
②返回多个元素组成的类数组对象
③不仅查找直接子元素,且查找所有后代
④仅靠其中一个class,就可以找到元素
4)按name属性值查找多个元素
var elems=document.getElementsByName(“name值”);
专门用于找表单中的有name属性的表单元素
①必须用document调用
②返回多个元素组成的类数组对象

(3)缺点

一次只能按一个条件查找,当查找条件复杂(需要多个条件反复查找才能找到元素)时,代码会很繁琐,步骤会很多

4.按任意选择器查找元素

(1)仅查找一个符合条件的元素

var elem=任意父元素.querySelector(“选择器”);
①用任意父元素调用
如果采用指定父元素,调用函数时必须是相对于父元素内的相对选择器
比如:document.querySelector(“table>tbody td:last-child”)
table.querySelector(“tbody td:last-child”)
②只能返回1个元素
③不仅查找直接子元素,且在所有后代中查找

(2)查找所有符合条件的元素

var elems=任意父元素.querySelectorAll(“任意选择器”);
①用任意父元素调用,缩小范围
②可返回所有符合条件的元素的类数组对象
③不仅查找直接子元素,且在所有后代中查找

(3)缺点

用选择器查找,效率不如用HTML特征查找高。

(4)总结

①如果只要一个条件,就能找到想要的元素时,首选按HTML特征查找;
②如果查找条件复杂时,需要多个条件才能找到想要的元素时,就首选按选择器查找

5.示例:购物车

(1)需求:3个

    a.点击+/-号,数量变化

    b.数量变化,导致小计变化

    c.小计变化,导致总计变化

(2)DOM 4步

几乎所有交互效果,都可以按DOM4步完成
a.查找触发事件的元素
b.绑定事件处理函数
c.查找要修改的元素
d.修改元素

(3)事件概述

浏览器自动触发的或用户手动触发的页面中元素内容和状态的改变
事件处理函数:当事件发生时,自动执行的函数
使用场景:只要希望在一个元素上发生指定事件时,能执行一项自定义任务就要用事件处理函数
方法:事件处理函数需要在编写程序时,就提前绑定到(赋值给)元素的事件属性;
其实每个元素上都提前定义了一批空(null)的事件属性,都是以onxxx开头
比如:为一个btn绑定一个单击事件处理函数;提前告诉btn,当有人单击你时自动执行事件
btn.οnclick=function(){ … }

(4)this

今后,只要在事件处理函数中获得当前正在触发事件的元素对象本身,都用this。
所有事件处理函数中的this,永远指.前的当前元素对象
案例:使用Selector API实现购物车客户端计算

使用Selector API实现购物车客户端计算
商品名称单价数量小计
iPhone6¥4488.00 - 1 + ¥4488.00
iPhone6 plus¥5288.00 - 1 + ¥5288.00
iPad Air 2¥4288.00 - 1 + ¥4288.00
Total: ¥14064.00

2.属性

(1)字符串类型的HTML标准属性

HTML标准中规定的属性(比如:title,class,href,src,target,id)
方法一:用最初的核心DOM函数
var 属性值=元素.getAttribute(“属性名”); 获取元素属性相对应的属性值
元素.setAttribute(“属性名”,“属性值”); 设置元素属性相对应的属性值
var bool=元素.hasAttribute(“属性名”); 判断是否含该属性true/false
元素.removeAttribute(“属性名”); 删除该属性

方法二:HTML DOM——核心DOM函数的简化版
将所有的HTML标准属性都提前定义在了元素对象上,属性值暂时都是""
元素.属性 获得属性值
元素.属性=值 修改属性值
元素.属性!=="" 判断是否包含属性
元素.属性="" 移除属性
总结:今后只要是HTML标准属性,都可用.访问
特例:class属性,虽然是标准属性,但不能直接用.访问;因为class是js的关键词;
今后凡是使用class属性,一律更名为className,使用className等于使用class

(2)bool类型(状态属性)的HTML标准属性

不需要属性值,放在元素上就起作用的属性
(比如:disabled,checked,selected)
他们的值都是bool类型,而核心DOM的4个函数只能操作字符串类型的标准属性,所以状态属
性只能用.访问(简化版方式操作)
案例1:实现伸缩二级菜单

1. 实现伸缩二级菜单
  • 考勤管理
    • 日常考勤
    • 请假申请
    • 加班/出差
  • 信息中心
    • 通知公告
    • 公司新闻
    • 规章制度
  • 协同办公
    • 公文流转
    • 文件中心
    • 内部邮件
    • 即时通信
    • 短信提醒
案例2:全选和取消全选 全选和取消全选

管理员列表

全选管理员ID姓名操作
1Tester修改 删除
2Manager修改 删除
3Analyst修改 删除
4Admin修改 删除

})()

### (3)自定义扩展属性 概念:HTML标准中没有规定的,程序员自发添加的属性 使用场景:①在客户端临时缓存数据,减少向服务器端发送请求的次数 ②代替其它选择器,用于选择触发事件的元素,绑定事件处理函数 方法:1)添加自定义扩展属性 ①在html页面中写死:<元素 data-自定义属性名="值"> 比如: ②用程序动态设置:只能用setAttribute,不能用. 比如:img.setAttribute("data-m","m.png") 结果: 2)修改自定义扩展属性:只能用setAttribute() 3)读取自定义扩展属性的值:只能用getAttribute() 比如:var m=img.getAttribute("data-m") 强调:因为自定义扩展属性只出现在页面中,不在内存中,所以只能用getAttribute() setAttribute()...来访问,不能用.访问 网页中的元素也是内存中的对象; 案例:实现多标签效果 读取并修改元素的属性

实现多标签页效果

  • //javascript:;将a设置成普通按钮样式 10元套餐
  • 30元套餐
  • 50元包月
10元套餐详情:
 每月套餐内拨打100分钟,超出部分2毛/分钟
30元套餐详情:
 每月套餐内拨打300分钟,超出部分1.5毛/分钟
50元包月详情:
 每月无限量随心打

3.样式

(1)修改内联样式

元素.style.css属性=“值”; 比如:div.style.display=“block”
强调:①css属性名如果带-,要去横线变驼峰; 比如:z-index -> zIndex
②如果css属性值带单位,则必须加单位; 比如:元素.style.width=64+“px”;
缺点:如果批量修改多个css属性时,使用style一次只能改一个css属性。代码会很繁琐。
解决方法:今后,只要是批量修改元素的样式都要先将多个css属性定义为一个class,再
用元素.className="class名"一句话批量应用
案例:登录验证页面

实现带样式的表单验证

增加管理员

姓名: *
10个字符以内的字母、数字或下划线的组合
密码: *
6位数字

五.添加删除

1.添加一个新元素:3步

(1)先创建一个空元素

var 新元素对象=document.createElement(“标签名”);
比如:var a=document.createElement(“a”); 结果:

(2)设置空元素的关键属性

标签名.属性名=“属性值”; 比如:a.href=“http://tmooc.cn”;
标签名.innerHTML=“HTML代码片段”; 比如:a.innerHTML=“go to tmooc”;
结果: go to tmooc

(3)将新元素挂载到DOM树上的指定位置上

1)在指定父元素末尾追加子元素
父元素.appendChild(新元素);
比如:body.appendChild(a); 将a元素追加到body元素下子元素的末尾
2)插入到现有一个元素之前
父元素.insertBefore(新元素,现有元素);
比如:body.insertBefore(a,h1); 将a插入到h1之前
3)替换现有的一个元素
父元素.replaceChild(新元素,现有元素);
比如:body.replaceChild(a,h1); 用a替换body下的h1

(4)优化

尽量减少操作DOM树的次数
每操作一次DOM树,浏览器都要重绘整个页面,效率很低,会造成闪屏
方法:1)如果同时添加父元素和子元素时,应该先在内存中将所有子元素添加到父元素中,最
后再一次性将父元素整体添加到DOM树——只重绘一次
2)如果父元素已经在页面上了,要添加多个平级子元素,借助文档片段
概念:内存中临时保存多个平级子元素的虚拟父元素
方法:①临时创建文档片段托盘对象
var frag=document.createDocumentFragment();
②将子元素临时添加到文档片段对象中
frag.appendChild(子元素);
③将文档片段添加到页面中指定的父元素下
父元素.appendChild(frag);
④结果:frag将子元素都送到父元素指定位置后,就释放了,不占用页面空间
案例:动态创建表格

动态创建表格
姓名薪资年龄
案例:二级联动列表 二级联动列表 —请选择— 北京市 天津市 河北省

2.删除

任意父元素.removeChild(孩子); 或者 孩子.parentNode.removeChild(孩子);

六.DOM常用对象

1.概念

HTML DOM是对原有DOM函数和对象的简化
HTML DOM对一些常用的元素对象也提供了简化的函数和属性
比如:

2.Image对象

一个元素
唯一的简化,就是在创建元素时:new Image();
强调:通常只有两个元素可以用new简写:
其它元素依然需要document.createElement()创建

3.Select对象

一个元素(以下简化的方式.前都是select对象)
简化:1)属性
.selectedIndex 获得select下选中的option的下标位置
.options 获得select下所有option元素的集合
.options.length或.length 获得select下所有option元素的个数
2)方法
.add(option)或.appendChild(option) 追加一个option;
区别:.add()不支持frag,.appendChild()支持frag
.remove(i) 移除i位置的一个option

4.Option对象

一个元素
唯一的简化,就是在创建时:new Option(内容文本,value);
比如:var option=new Option("-请选择-",0); frag.appendChild(new Option(c.name));
结果:-请选择-

5.Table对象

代表页面上一个

元素

(1)table管着行分组

创建行分组:table.createTHead()
table.createTBody()
table.createTFoot()
删除行分组:table.deleteTHead()
table.deleteTFoot()
获得行分组:table.tHead
table.tFoot
table.tBodies[i]

(2)行分组管着行

创建行:var tr=tbody.insertRow(i); 在tbody中第i行位置插入一个新行,并返回刚添加的新行
对象,便于后续对新行中添加格和数据。
var tr=tbody.insertRow(0); 在tbody开头插入一个新行
var tr=tbody.insertRow(); 在rbody结尾追加一个新行
强调:insertRow()不但创建新行,而且立刻将新行添加到tbody中
删除行:tbody.deleteRow(i); 删除tbody中i位置的行
问题:i要求是行在tbody内部的相对下标位置,而一个tr对象的相对下标位置无法自动
获得,可以自动获得的tr.rowIndex()是相对于整个表中的下标位置,和
tbody.deleteRow()的要求错位。
方法:今后只要删除行的标准写法都是:table.deleteRow(tr.rowIndex);
因为.前的主语变成整个table,所以deleteRow()要求就变为使用整个表中的下
标,就和tr.rowIndex的意义相符了。
获取行:tbody.rows[i]

(3)行管着格

添加格:var td=tr.insertCell(i)
通常都是在行末尾追加一格:var td=tr.insertCell()
删除格:tr.deleteCall(i)
获取格:tr.cells[i]
补充知识点对话框:prompt()输入框 alert()警告框 confirm()确认框,需要写判断是否确定

动态创建表格
姓名薪资年龄删除

6.Form对象

代表一个元素

(1)获取表单对象

其实也不需要查找就可直接获得。因为表单对于所在的网页极其重要,所以网页就将本页面内的元素都保存在一个forms集合中,可用[i]获取某一个表单对象。
var form=document.forms[i];
比如:如果一个页面中只有一个则var form=document.forms[0]
属性:form.elements 获得表单中所有表单元素的集合
form.elements.length或form.length 获得表单中所有表单元素的个数

(2)获取表单中的表单元素

比如:
普通方法:var 表单元素=form.elements[id/i/name];
比如:var txtName=form.elements[“username”]
简写:如果一个表单元素有name属性,可直接用.name方法获得;
var 表单元素=form.elements[id/i/name];可简写为:form.username;

(3)方法

表单元素.focus() 让当前表单元素自动获得焦点

实现带样式的表单验证

增加管理员

姓名: *
10个字符以内的字母、数字或下划线的组合
密码: *
6位数字

七.BOM

1.BOM概述

Browser Object Model 操作浏览器窗口的对象和函数
JS=ECMAScript + DOM + BOM
核心语法 操作网页内容 操作浏览器窗口
ES标准 W3C标准 没有标准,极大的兼容性问题,所以用的越来越少

2.window对象:3个角色

(1)顶替了ES标准中的global,充当全局作用域对象

    浏览器中:var a=10;   window.a输出10
    window.parseInt()   window.parseFloat()   window.Array   window.Date   window.RegExp

(2)包含所有原生的对象和函数:ES+DOM+BOM

(3)还代表当前正在打开的窗口

1)打开和关闭窗口
window.close() 关闭当前窗口的意思,新chrome浏览器禁止随意关闭窗口,弹出黄色警告
window.open() 关闭窗口
2)完整窗口大小
window.outerWidth 可获得当前窗口的总宽度
window.outerHeight 可获得当前窗口的总高度
3)文档显示区大小:浏览器窗口中专门用于显示网页的区域
window.innerWidth 可获得当前文档显示区宽
window.innerHeight 可获得当前文档显示区高

(4)打开新链接的方式

1)在当前窗口打开新链接,可后退
html:
js:window.open(“url”,"_self")
2)在当前窗口打开新链接,禁止后退
js:location.replace(“新url”)
原理:用新的url地址,替换history中旧的地址,保证history中只有一条url,以此禁止后退
3)在新窗口打开新链接,可同时打开多个
html:
js:window.open(“url”,"_blank")
4)在新窗口打开新链接,只能打开一个
html:
js:window.open(“url”,“自定义新窗口名”)
原理:其实每个窗口在浏览器内存中都有一个唯一的名字,用来标识这个窗口。
浏览器规定相同名称的窗口只能打开一个;新打开的同名窗口会覆盖现有的重名窗口
target:①如果打开链接时,使用自定义窗口名,则反复点击链接,只能打开一个
②预定义窗口_self:自动获取当前窗口的名字给新窗口,新窗口会覆盖当前窗口
③预定义窗口_blank:空白,不指定新窗口名,浏览器会自动在底层分配,保证不重
复;不限制打开的新窗口个数

打开新链接方式总结

1. 在当前窗口打开新链接,可后退

go to tmooc
go to tmooc

2. 在当前窗口打开新链接,禁止后退

go to tmooc

3. 在新窗口打开新链接,可打开多个

go to tmooc
go to tmooc

4. 在新窗口打开新链接,只能打开一个

go to tmooc
go to tmooc

3.window.history

保存当前窗口打开后,成功访问过的url的历史记录数组。

(1)原理

当前窗口只要成功访问过一个url,url就会被push到history中保存。
能否前进后退,取决于现在正在看的url,在history前后是否有其它已经浏览过的url

(2)函数

只给我们开放了一个函数javascript:history.go(i)
history.go(1) 前进一步
history.go(-1) 后退一步
history.go(-2) 后退两步
history.go(0) 刷新

(3)案例

①在1_history.html中:javascript:history.go(1) javascript:history.go(2)
②在2_history.html中:javascript:history.go(-1) javascript:history.go(1)
③在3_history.html中:javascript:history.go(-2) javascript:history.go(-1)
④在1_history.html中live server运行
⑤依次点2,3
⑥可使用自定义的链接,实现前进和后退
文件:1_history.html

使用 history 对象

9-1.html

1   2   3  

前进一次   前进二次  
文件:2_history.html 使用 history 对象

9-2.html

1   2   3  

后退一次   前进一次  
文件:3_history.html 使用 history 对象

9-3.html

1   2   3  

后退二次   后退一次  

4.window.location

专门保存地址栏中url信息的对象,并提供了打开新链接的方法。

(1)属性

可分段获得url的各个组成部分
完整url:location.href
http://127.0.0.1:5500/BOM/10_location.html?
协议 主机/IP 端口 相对路径
username=dingding&pwd=123456&favs=running#top
查询字符串 锚点地址
协议:location.protocol
主机+端口:location.host
主机:location.hostname
端口:location.port
相对路径:location.pathname
查询字符串:location.search
锚点地址:location.hash

(2)方法

①在当前窗口打开新链接,可后退:location.href=“新url”
②在当前窗口打开新链接,禁止后退:location.replace(“新url”)
③刷新:location.reload()

5.window.navigator

保存浏览器配置信息的对象
navigator.userAgent 获得浏览器名称、内核、版本号相关信息
navigator.plugins 获得浏览器中安装的插件信息列表
navigator.plugins[“插件全名”]!==undefined 判断是否安装某个插件
IE8~IE10 MSIE版本号
Firefox Firefox/版本号
OPR Chrome/版本号 Safari/版本号 OPR/版本号
Edge Chrome/版本号 Safari/版本号 Edge/版本号
Chrome Chrome/版本号 Safari/版本号
Safari Safari/版本号
案例:如何判断正在使用的浏览器的名称和版本号以及判断是否安装指定插件

navigator对象常用属性

八.事件

1.概念

事件:浏览器自动触发的或用户手动触发的页面内容,状态的改变
事件处理函数:当事件发生时自动调用的函数
事件处理函数中的this永远指当前触发事件的元素
绑定事件处理函数:每个元素对象上都有一批on开头的特殊属性,这些属性会在事件发生时自动触
发对应的属性。
如果希望事件发生时,按照我们的意愿执行操作,就要提前将一个自定义函数
赋值给on开头的对应属性保存起来。当事件发生时,会自动调用提前保存的函数

2.绑定事件处理函数

(1)在HTNL中

提前在js中定义好一个事件处理函数;事件处理函数必须写在事件之前

<元素 on事件名=“事件处理函数()”>
缺点:不符合内容与行为分离的原则,不便于维护和重用

(2)在js中用赋值方式

元素对象.οnclick=function(){ …this指当前触发事件的元素对象 }
缺点:一个事件只能绑定一个处理函数,不灵活

(3)在js中用添加事件监听对象的方式

元素对象.addEventListener(“事件名”,处理函数);
强调:真正的事件名是没有on前缀的:click change focus blur load
原理:
btnShoot.addEventListener(“click”,function(){ 发射普通子弹 })
btnShoot.addEventListener(“click”,function(){ 发射跟踪导弹 })
结果:单击btnShoot,会先后发射两种子弹
①其实,浏览器中有一个巨大的事件监听队列;我们为每个元素绑定的事件监听对象都会被添加到监
听队列中;
②当事件发生时,浏览器采用遍历监听队列的方式,找到符合条件的事件监听对象,并执行其中的处
理函数。找到几个符合条件的,就执行几个符合条件的事件处理函数

(4)移除事件监听对象

元素对象.removeEventListener(“事件名”,处理函数)
强调:移除监听对象时,元素,事件名和处理函数都要和添加时完全相同。
如果一个处理函数可能被移除,则添加监听时就要使用有名称的函数,不能使用匿名函数

...

3.事件模型

概念:从触发事件开始,到所有事件处理函数执行完,所经历的过程。
包括3个阶段:1)捕获:由外(document)向内(实际触发事件的元素)记录各级父元素上绑定的相同
事件的处理函数,只记录,不执行。
2)目标触发:优先触发目标元素上的处理函数
目标元素:最初实际触发事件的那个元素
3)冒泡:由内向外,依次触发各级父元素上收集的相同事件的处理函数

4.事件对象

概念:在事件发生时,浏览器自动创建的,收集事件相关信息的对象。并提供了改造事件的函数。
场景:想获得事件信息时:点了那个元素,点在什么位置…
想改造事件默认的行为:取消冒泡
方法:(1)获取:不用自己创建,事件对象总是作为处理函数的第一个实参默认传入。
我们只要在定义处理函数时,提前定义一个形参接住
元素.οnclick=function(e){ //当事件发生时:e自动收到浏览器给的event对象 }
元素.addEventListener(“click”,function(e){//e自动收到浏览器给的event对象})
(2)功能
1)取消冒泡:e.stopPropagation();
概念:当前元素处理函数执行完,停止继续执行父元素上的处理函数
场景:只要不希望触发父元素上的处理函数时,都要取消冒泡

事件处理

2)事件委托/事件代理
优化: 由于浏览器触发事件,是采用遍历监听数组中每个监听对象来匹配并触发处
理函数的。数组中监听对象多,遍历速度慢,数组中监听对象少,遍历快。
所以尽量减少事件监听的个数
场景:多个平级子元素,要绑定相同的事件处理函数时,只要在父元素绑定一次即可
方法:①只要在父元素上统一绑定一次事件处理函数即可;点击子元素时,会自
动冒泡到父元素上,执行提前委托好的处理函数。
②获得当前点击的子元素
e.target代替this 记录了事件最初触发的目标元素,不随冒泡而改变。
然而this会随冒泡一起改变,冒泡到哪里执行,this就指哪个元素,所以不能
用this
③判断当前点的元素是否是想要的
在正式执行逻辑前,都要先判断目标元素是否是想要的。
哪些属性可作为区分的条件:节点名/标签名nodeName,className
强调:nodeName保存的是全大写的标签名

计数器
1 2 3 4
C + - =
4)鼠标坐标:事件对象在事件发生时,就自动获得了鼠标在屏幕中的位置 ①相对于当前显示屏左上角的距离: e.screenX, e.screenY ②相对于浏览器文档显示区左上角的距离: e.clientX, e.clientY ③相对于当前点击的元素左上角的距离: e.offsetX, e.offsetY

<!doctype html>

在当前显示区范围内实现点不到的小方块
注:id属性会自动成为全局变量,代表当前元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值