两天更新完毕,建议关注收藏点赞
友情链接:
HTML&CSS&LESS&Bootstrap&Emmet
Axios & AJAX & Fetch
BOM DOM
待整理 js2
- Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API ( BOM 和 DOM)。官方文档点击跳转
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. 鼠标经过事件 onmouseover
trs[i].onmouseover = function() {
// console.log(11);
this.className = 'bg';
}
// 4. 鼠标离开事件 onmouseout
trs[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 不可以
//scroll
1. 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.length
if (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");
// 读取 dataset
console.log("初始索引:", button.dataset.index); // 输出: "1"
// 修改 dataset
button.dataset.index = "2";
console.log("修改后的索引:", button.dataset.index); // 输出: "2"
// 监听点击事件
button.addEventListener("click", function() {
// 自增 index
this.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 高