两天更新完毕,建议关注收藏点赞
友情链接:
HTML&CSS&LESS&Bootstrap&Emmet
Axios & AJAX & Fetch
BOM DOM
待整理 js2
- Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API ( BOM 和 DOM)。官方文档点击跳转
目录
- BOM
- DOM
- 一般获取元素
- 层级关系获取元素
- 事件event
- JS 特效三大系列【offset】【scroll】【client】
- 操作元素
BOM
BOM (Browser Object Model,简称BOM) 是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
DOM
核心要点:增删改查,创建,属性操作,事件操作
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。
- DOM树
DOM树 又称为文档树模型,把文档映射成树形结构,通过节点对象对其处理,处理的结果可以加入到当前的页面。
文档:一个页面就是一个文档,DOM中使用document表示
节点:网页中的所有内容,在文档树中都是节点(标签、属性、文本、注释等),使用node表示
标签节点:网页中的所有标签,通常称为元素节点,又简称为“元素”,使用element表示
DOM把这些节点都看作对象。 - 总结
创建
- document.write
- innerHTML
- createElement
增 - appendChild
- insertBefore
删 - removeChild
改
主要修改dom的元素属性,dom元素的内容、属性, 表单的值等 - 修改元素属性: src、href、title等
- 修改普通元素内容: innerHTML 、innerText
- 修改表单元素: value、type、disabled等
- 修改元素样式: style、className
查
主要获取查询dom的元素 - DOM提供的API 方法: getElementById、getElementsByTagName 古老用法 不太推荐
- H5提供的新方法: querySelector、querySelectorAll 提倡
- 利用节点操作获取元素: 父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡
属性操作
主要针对于自定义属性。 - setAttribute:设置dom的属性值
- getAttribute:得到dom的属性值
- removeAttribute移除属性
事件操作
给元素注册事件, 采取 事件源.事件类型 = 事件处理程序
一般获取元素
document.getElementById(id)
参数:id值,区分大小写的字符串
返回值:元素对象 或 null<body><div id="time">2019-9-9</div><script>// 因为我们文档页面从上往下加载,所以先得有标签 所以我们script写到标签的下面var timer = document.getElementById('time');console.log(timer);console.log(typeof timer);// console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法console.dir(timer);</script>
</body>document.getElementsByTagName('标签名') 或者
element.getElementsByTagName('标签名')
作用:根据标签名获取元素对象
参数:标签名
返回值:元素对象集合(伪数组,数组元素是元素对象)
注意:getElementsByTagName()获取到是动态集合,即:当页面增加了标签,这个集合中也就增加了元素。document.getElementsByClassName()是h5新增的方法,有浏览器兼容性问题<script>// 1.获取元素 获取的是 tbody 里面所有的行
var trs = document.querySelector('tbody').querySelectorAll('tr');// 2. 利用循环绑定注册事件
for (var i = 0; i < trs.length; i++) {// 3. 鼠标经过事件 onmouseovertrs[i].onmouseover = function() {// console.log(11);this.className = 'bg';}// 4. 鼠标离开事件 onmouseouttrs[i].onmouseout = function() {this.className = '';}
}
</script>
<script>// 1. 全选和取消全选做法: 让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可// 获取元素var j_cbAll = document.getElementById('j_cbAll'); var j_tbs = document.getElementById('j_tb').getElementsByTagName('input'); // 全选按钮注册事件j_cbAll.onclick = function() {// this.checked 当前复选框的选中状态console.log(this.checked);for (var i = 0; i < j_tbs.length; i++) {j_tbs[i].checked = this.checked;}}// 给所有的子复选框注册单击事件for (var i = 0; i < j_tbs.length; i++) {j_tbs[i].onclick = function() {// flag 控制全选按钮是否选中var flag = true;// 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中for (var i = 0; i < j_tbs.length; i++) {if (!j_tbs[i].checked) {flag = false;break; }}// 设置全选按钮的状态j_cbAll.checked = flag;}}</script>
- querySelector 和 querySelectorAll 是两种常用的 DOM 查询方法。
- querySelector只能选择第一个匹配的节点;
- querySelectorAll可以选择多个节点,以","分隔开,返回的是个数组;
querySelector 返回指定选择器的第一个元素对象
里面的选择器需要加符号 .box #nav
var firstBox = document.querySelector('.box');//获取特殊元素
document.body //body元素对象
document.documentElement //html元素对象
层级关系获取元素
节点就是前面DOM树中的所有节点,网页的所有内容都是节点。节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个
基本属性。
元素节点 nodeType 为 1
属性节点 nodeType 为 2
文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)
//父级节点 返回最近的一个父节点或者null
node.parentNode//返回包含指定节点的子节点的集合,该集合为即时更新的集合。
//包含了所有的子节点,包括元素节点,文本节点等。
//如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes
parentNode.childNodes//是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回
//是得到了各个浏览器的支持
parentNode.children//第一个或最后一个 找不到则返回null。同样,也是包含所有的节点。
//子节点 不仅仅是元素节点
parentNode.firstChild
parentNode.lastChild//返回第一个子元素节点,找不到则返回null。
//注意:这两个方法有兼容性问题,IE9 以上才支持。
parentNode.firstElementChild
parentNode.lastElementChild//综上
//firstChild 和 lastChild 包含其他节点,操作不方便
//firstElementChild 和lastElementChild 又有兼容性问题
//如果要第一个子元素节点,使用 parentNode.chilren[0]
//如果是最后一个子元素节点,使用 parentNode.chilren[parentNode.chilren.length - 1]//兄弟节点 返回当前元素的下一个兄弟节点,找不到则返回null。包含所有的节点。
node.nextSibling
node.previousSibling//兄弟元素节点 注意:这两个方法有兼容性问题, IE9 以上才支持。
node.nextElementSibling
node.previousElementSibling//使用自己封装的获取兄弟节点函数 同时解决兼容性
function getNextElementSibling(element) {var el = element;while (el = el.nextSibling) {if (el.nodeType === 1) {return el;}}return null;
}//下拉菜单
var nav = document.querySelector('.nav');
var lis = nav.children; // 得到4个小li
for (var i = 0; i < lis.length; i++) {lis[i].onmouseover = function() {this.children[1].style.display = 'block';}lis[i].onmouseout = function() {this.children[1].style.display = 'none';}
}
事件event
事件是可以被 JavaScript 侦测到的行为。简单理解: 触发— 响应机制。
- 事件三要素
事件源(谁):触发事件的元素
事件类型(什么事件): 例如 click 点击事件
事件处理程序(做啥):事件触发后要执行的代码(函数形式),事件处理函数 - 执行事件步骤
获取事件源,注册事件(绑定事件),添加事件处理程序(采用函数赋值形式) - 常见的鼠标事件
<body><button id="btn">唐伯虎</button><script>// 点击一个按钮,弹出对话框// 1. 事件是有三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素//(1) 事件源 事件被触发的对象 谁 按钮var btn = document.getElementById('btn');//(2) 事件类型 如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下//(3) 事件处理程序 通过一个函数赋值的方式 完成btn.onclick = function() {alert('点秋香');}</script>
</body>
JS 特效三大系列【offset】【scroll】【client】
//offset
1. offsetLeft : 用于获取元素到最近的定位父盒子的左侧距离 * 计算方式: 当前元素的左边框的左侧到定位父盒子的左边框右侧
* 如果父级盒子没有定位, 那么会接着往上找有定位的盒子
* 如果上级元素都没有定位,那么最后距离是与body的left值 2. offsetTop : 用于获取元素到最近定位父盒子的顶部距离* 计算方式:当前元素的上边框的上侧到定位父盒子的上边框下侧 * 如果父级盒子没有定位,那么会接着往上找有定位的盒子 * 如果上级元素都没有定位,那么最后距离是与body的top值 3. offsetWidth :用于获取元素的真实宽度(除了margin以外的宽度) 4. offsetHeight : 用于获取元素的真实高度(除了margin以外的高度) 5. offsetParent :用于获取该元素中有定位的最近父级元素 * 如果当前元素的父级元素都没有进行定位,那么offsetParent为body//与 style . ( left / top / width / height ) 的区别:
1. offset系列的是只读属性,而通过style的方式可以读写
2. offset系列返回的数值类型(结果四舍五入),style返回的是字符串
3. style 可以返回没有定位的元素的left值和top值,而 offsetLeft 和 offsetTop 不可以//scroll1. scrollHeight :元素中内容的实际高度(没有边框) * 如果内容不足,就是元素的高度 2. scrollWidth : 元素中内容的实际宽度(没有边框)* 如果内容不足,就是元素的宽度 3. scrollTop : onscroll事件发生时,元素向上卷曲出去的距离 4. scrollLeft : onscroll事件发生时,元素向左卷曲出去的距离//兼容问题
* 未声明 DTD: 谷歌,火狐,IE9+支持 document.body.scrollTop/scrollLeft
* 已经声明DTD:IE8以下支持 document.documentElement.scrollTop/scrollLeft
* 火狐/谷歌/ie9+以上支持的 window.pageYOffest/pageXOffest
//兼容代码
function getScroll() {return {left: window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft || 0,top: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0};
}//client
1. clientWidth : 获取网页可视区域的宽度 2. clientHeight: 获取网页可视区域的高度 3. clientX : 获取鼠标事件发生时的应用客户端区域的水平坐标 4. clientY : 获取鼠标事件发生时的应用客户端区域的垂直坐标//兼容问题//由浏览器对象不同导致 * 未声明 DTD: 谷歌,火狐,IE9+支持 document.body.clientWidth/clientHeight * 已经声明DTD:IE8以下支持 document.documentElement.clientWidth/clientHeight * 火狐/谷歌/ie9+以上支持的 window.innerWidth/innerHeight
//兼容代码
function client() {if (window.innerWidth) {return {"width": window.innerWidth,"height": window.innerHeight};} else if (document.compatMode === "CSS1Compat") {return {"width": document.documentElement.clientWidth,"height": document.documentElement.clientHeight};} else {return {"width": document.body.clientWidth,"height": document.body.clientHeight};}
}//由事件参数对象的兼容性问题导致 1. 谷歌,火狐,IE9+ : 事件参数对象随着事件处理函数的参数传入 2. IE8以下: event对象必须作为window对象的一个属性(window.event)
- 总结
网页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight; 网页真实元素宽: document.body.offsetWidth (包括边线的宽);
网页真实元素高: document.body.offsetHeight (包括边线的宽); 网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight; 网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft; 浏览器窗口的顶部边缘与屏幕的顶部边缘之间的距离: window.screenTop;
浏览器窗口的左边缘与屏幕的左边缘之间的距离: window.screenLeft; 屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width; 屏幕可用工作区高度: window.screen.availHeight;
屏幕可用工作区宽度: window.screen.availWidth;
操作元素
element.innerText 不解析html标签,去除空格、换行
element.innerHTML 不去除//常见属性
src,href
id,alt,title//表单元素
type,value,checked,selected,disabled//样式属性
element.style
element.className//覆盖原先类名 class是关键字不能用
//当js修改样式时为行内样式,优先级高box.style.display = 'none';//自定义属性
element.getAttribute('attr_name')
element.setAttribute('attr_name','value')
element.removeAttribute('属性');
//H5规定自定义属性data-开头做为属性名并且赋值。
H5新增 element.dataset.index 或者 element.dataset[‘index’]
//ie11才开始支持//循环雪碧图 精灵图
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
// 让索引号 乘以 44 就是每个li 的背景y坐标 index就是我们的y坐标var index = i * 44;lis[i].style.backgroundPosition = '0 -' + index + 'px';
}//仿新浪注册页面// 首先判断的事件是表单失去焦点 onblur// 如果输入正确则提示正确的信息颜色为绿色小图标变化// 如果输入不是6到16位,则提示错误信息颜色为红色 小图标变化// 因为里面变化样式较多,我们采取className修改样式// 1.获取元素var ipt = document.querySelector('.ipt');var message = document.querySelector('.message');//2. 注册事件 失去焦点ipt.onblur = function() {// 根据表单里面值的长度 ipt.value.lengthif (this.value.length < 6 || this.value.length > 16) {// console.log('错误');message.className = 'message wrong';message.innerHTML = '您输入的位数不对要求6~16位';} else {message.className = 'message right';message.innerHTML = '您输入的正确';}}
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>dataset 示例</title>
</head>
<body><button id="myButton" data-index="1">点击我</button><script>// 获取按钮元素var button = document.getElementById("myButton");// 读取 datasetconsole.log("初始索引:", button.dataset.index); // 输出: "1"// 修改 datasetbutton.dataset.index = "2";console.log("修改后的索引:", button.dataset.index); // 输出: "2"// 监听点击事件button.addEventListener("click", function() {// 自增 indexthis.dataset.index = parseInt(this.dataset.index) + 1;alert("当前索引: " + this.dataset.index);});</script>
</body>
</html>
//创建节点
document.createElement('name')
//创建由tagName指定的HTML元素。因为这些元素原先不存在,称为动态创建元素节点。//将一个节点添加到指定父节点的子节点列表末尾。
//类似于 CSS 里面的after 伪元素。
node.appendChild(child)//将一个节点添加到父节点的指定子节点前面。
//类似于 CSS 里面的 before 伪元素。
node.insertBefore(child, 指定元素)//从 DOM 中删除一个子节点,返回删除的节点。
node.removeChild(child)//返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点
node.cloneNode()
//括号参数为空或者为false则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
//如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点。
- 三种动态创建元素的区别
document.write()
element.innerHTML
document.createElement()
区别
- document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
- innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
- innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
- createElement() 创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML 效率要比 creatElement 高