三、DOM操作
3.1 DOM基础
3.1.1 DOM简介
文档对象模型(Document Object Model,简称DOM)是一组编程接口,通过这些接口可以动态修改页面内容、结构和样式。
DOM树概念:
- 文档:一个页面即为一个文档,DOM中用document表示
- 元素:页面中的所有标签都是元素,DOM中用element表示
- 节点:网页中所有内容(标签、属性、文本、注释等)都是节点,DOM中用node表示
DOM将所有内容都视为对象。
3.1.2 事件处理
事件是用户与浏览器的交互行为,如点击按钮、鼠标移动、关闭窗口等。为方便学习,我们先介绍基本事件处理方式。
方式一:内联事件处理
html
<button id="btn" onclick="alert('哈喽')">我是一个按钮</button>
缺点:结构与行为耦合,不利于维护,不推荐使用。
方式二:绑定事件处理函数
html
<body>
<button id="btn">我是一个按钮</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("你好")
}
</script>
</body>
方式三:addEventListener
html
<button id="btn">按钮</button>
<script>
let btn = document.getElementById('btn');
btn.addEventListener('click', fun);
btn.addEventListener('click', fun1);
function fun() {
alert('fun');
}
function fun1() {
alert('fun1');
}
</script>
3.1.3 文档加载
浏览器加载页面时按自上而下顺序执行。若将script标签置于页面顶部,可能导致DOM对象尚未加载而无法获取。
解决方案一:将JS代码放在页面底部
html
<button id="btn">点我一下</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function() {
alert("hello");
};
</script>
解决方案二:使用window.onload
javascript
window.onload = function() {
var btn = document.getElementById("btn");
btn.onclick = function() {
alert("hello");
};
};
3.2 DOM 元素获取 DOM 在实际开发中主要用于操作页面元素,以下是常用的获取方法:
3.2.1 getElementById() 通过元素的 id 属性获取单个元素节点对象:
- 参数:区分大小写的字符串 id
- 返回值:元素对象
常用属性:
- innerHTML:可读写,获取/修改元素内部的 HTML 代码(保留标签、空格和换行)
- innerText:可读写,获取/修改元素文本内容(自动去除 HTML 标签、空格和换行)
- console.dir:打印元素对象,方便查看其属性和方法
示例:
javascript
var btn01 = document.getElementById("btn01");
btn01.onclick = function() {
var bj = document.getElementById("bj");
alert(bj.innerHTML);
};
3.2.2 getElementsByTagName() 3.2.2.1 通过标签名获取元素集合
- 返回类数组对象
- 即使只有一个匹配元素也会返回数组
- 无匹配时返回空数组
示例:
javascript
var btn02 = document.getElementById("btn02");
btn02.onclick = function() {
var lis = document.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
console.log(lis[i].innerHTML);
}
};
3.2.2.2 获取父元素内的指定标签元素 语法:父元素.getElementsByTagName('标签名') 注意:父元素必须是具体对象,不包含自身
示例:
javascript
var city = document.getElementById("city");
var lis = city.getElementsByTagName("li");
3.2.3 getElementsByName() 通过 name 属性获取元素集合
注意事项:
- innerHTML 对自闭合标签无效
- 读取元素属性:
元素.属性名(如 id、name、src、href) - 表单元素属性:type、value、checked、selected、disabled
- class 属性需使用 className 读取
- 修改 value:
element.value = "新值"
示例:
javascript
var btn03 = document.getElementById("btn03");
btn03.onclick = function() {
var inputs = document.getElementsByName("gender");
for (var i = 0; i < inputs.length; i++) {
alert(inputs[i].className);
}
};
3.2.4 getElementsByClassName() 通过 class 获取元素集合(IE8 及以下不支持)
示例:
javascript
var btn04 = document.getElementById("btn04");
btn04.onclick = function() {
var classes = document.getElementsByClassName("inner");
for (var i = 0; i < classes.length; i++) {
alert(classes[i].className);
}
};
3.2.5 子节点获取
- childNodes:获取所有子节点(含空白文本节点)
- children:仅获取子元素节点
3.2.6 首尾子节点
- firstChild/lastChild:包含空白文本节点
- firstElementChild/lastElementChild:仅元素节点
3.2.7 父节点获取
- parentNode
- parentElement
3.2.8 兄弟节点
- previousSibling/nextSibling:含空白文本
- previousElementSibling/nextElementSibling:仅元素节点(IE8 以下不支持)
3.2.9 body 获取
javascript
// 方法一
var body = document.getElementsByTagName("body")[0];
// 方法二
var body = document.body;
3.2.10 html 根标签
javascript
var html = document.documentElement;
3.2.11 获取所有元素
javascript
// 方法一
var all = document.all;
// 方法二
var all = document.getElementsByTagName("*");
3.2.12 querySelector()
- 参数:CSS 选择器字符串
- 返回第一个匹配元素
- IE8+ 支持
3.2.13 querySelectorAll()
- 返回所有匹配元素的类数组
- 即使单个匹配也返回数组
示例:
javascript
var div = document.querySelector(".box1 div");
var divs = document.querySelectorAll(".box1");
3.3 事件基础
3.3.1 事件概述
JavaScript 使我们能够创建动态页面,事件则是可以被 JavaScript 侦测的行为。简单来说,就是"触发-响应"机制。
网页中的每个元素都能产生可触发 JavaScript 的事件,比如点击事件。事件由三个部分组成:
- 事件源:触发事件的对象
- 事件类型:如何触发(如鼠标点击、键盘按下等)
- 事件处理程序:通过函数赋值方式实现
执行事件的步骤:
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采用函数赋值形式)
javascript
// 获取按钮对象
var btn = document.getElementById("btn");
// 绑定单击事件并添加处理程序
btn.onclick = function() {
alert("你好")
}
3.3.2 常见事件
鼠标事件:
| 事件 | 触发条件 |
|---|---|
| onclick | 单击鼠标时 |
| onmousedown | 按下鼠标按钮时 |
| onmouseup | 松开鼠标按钮时 |
| onmousemove | 鼠标指针移动时 |
| onmouseover | 鼠标移至元素上(会冒泡) |
| onmouseout | 鼠标移出元素(会冒泡) |
| onmouseenter | 鼠标移至元素上(不冒泡) |
| onmouseleave | 鼠标移出元素(不冒泡) |
| onmousewheel | 转动鼠标滚轮时 |
| onscroll | 滚动元素滚动条时 |
键盘事件:
| 事件 | 触发条件 |
|---|---|
| onkeyup | 键盘按键松开时 |
| onkeydown | 键盘按键按下时 |
| onkeypress | 键盘按键按下时(不支持功能键) |
表单事件:
| 事件 | 触发条件 |
|---|---|
| onfocus | 获得焦点时 |
| onblur | 失去焦点时 |
| oninput | 每次输入时 |
| onchange | 内容改变时 |
| onselect | 文本被选取时 |
| onreset | 表单重置时 |
| onsubmit | 表单提交时 |
3.4 操作元素内容及属性
通过 DOM 操作可以改变网页内容、结构和样式。
3.4.1 改变元素内容
element.innerText 和 element.innerHTML 的区别:
- 读取 :
innerText:去除空格、换行和标签,只获取文本innerHTML:获取元素内所有内容,包括标签
- 写入 :
innerText:不识别 HTML 标签innerHTML:识别 HTML 标签
其他属性:
element.nodeValue:根据节点类型返回值element.textContent:返回元素及其后代的文本内容
html
<button>点我切换内容</button>
<div>天气炎热</div>
<script>
var btn = document.querySelector("button");
var div = document.querySelector("div");
btn.onclick = function() {
div.innerHTML = "天气凉爽";
};
</script>
3.4.2 改变元素其他属性
可操作 src、href、id、alt、title 等属性。
html
<button id="dog">小狗</button>
<button id="cat">小猫</button>
<img src="./img/pic_01.jpg" title="小狗" />
<script>
var dog = document.querySelector("#dog");
var cat = document.querySelector("#cat");
var img = document.querySelector("img");
dog.onclick = function() {
img.src = "./img/pic_01.jpg";
img.title = "小狗";
};
cat.onclick = function() {
img.src = "./img/pic_02.jpg";
img.title = "小猫";
};
</script>
3.4.3 操作表单元素属性
可操作 type、value、checked、selected、disabled 等属性。
html
<button>按钮</button>
<input type="text" value="请输入内容" />
<script>
var btn = document.querySelector("button");
var input = document.querySelector("input");
btn.onclick = function() {
input.value = "内容被修改了";
btn.disabled = true;
};
</script>
3.4.4 操作样式属性
方式一 :element.style 行内样式操作
- 采用驼峰命名法(如
fontSize) - 产生行内样式,CSS 权重较高
方式二 :element.className 类名样式操作
- 适用于修改较多样式的情况
- 会覆盖原有类名,需手动保留原类名
html
<div class="box">box</div>
<script>
var box = document.querySelector(".box");
box.onclick = function() {
box.style.backgroundColor = "red";
};
box.onmouseover = function() {
this.className = "box1";
};
</script>
3.4.5 排他思想
同一组元素中,实现单个元素特殊样式的算法:
- 清除所有元素的样式
- 给当前元素设置样式
html
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
var btns = document.querySelectorAll("button");
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
for (var j = 0; j < btns.length; j++) {
btns[j].style.backgroundColor = "";
}
this.style.backgroundColor = "red";
};
}
</script>
3.4.6 操作自定义属性
获取属性值:
element.属性:获取元素自带属性element.getAttribute('属性'):获取自定义属性
设置属性值:
element.属性='值'element.setAttribute('属性','值')
移除某个属性
element.removeAttribute("属性"); 移除某个属性
h5新增自定义属性写法
为了区分自定义属性,还是元素自带属性
H5给我们新增了自定义属性规范:H5规定自定义属性以data-开头,如多个单词,用-连接,读取时,用小驼峰读取
获取自定义属性:
方式一:element.getAttribute('属性')
方式二:element.dataset.去除掉data-的属性名
3.5、节点操作
3.5.1、创建节点
javascript
document.createElement('tagName')
- 参数:标签名字符串
- 说明:动态创建原本不存在的元素节点,返回创建好的元素对象
3.5.2、创建文本节点
javascript
document.createTextNode('textContent')
- 参数:文本内容字符串
- 说明:创建新的文本节点并返回
3.5.3、添加节点
-
parentNode.appendChild(childNode)- 将节点添加到父节点子节点列表末尾
- 类似数组的push()方法和CSS的::after伪元素
-
parentNode.insertBefore(newNode, referenceNode)- 将节点插入到父节点的指定子节点之前
- 类似CSS的::before伪元素
html
<body>
<div id="box">
<p>段落</p>
</div>
<button>添加span</button>
<button>添加h1</button>
<script>
const btns = document.querySelectorAll("button");
const p = document.querySelector("p");
const box = document.getElementById("box");
// 需求1:在p后添加span
btns[0].onclick = function() {
const span = document.createElement("span");
span.appendChild(document.createTextNode("我是一个span"));
box.appendChild(span);
};
// 需求2:在p前添加h1
btns[1].onclick = function() {
const h1 = document.createElement("h1");
h1.appendChild(document.createTextNode("我是一个h1"));
box.insertBefore(h1, p);
};
</script>
</body>
3.5.4、替换节点
javascript
parentNode.replaceChild(newChild, oldChild)
- 功能:用新节点替换已有子节点
3.5.5、删除节点
parentNode.removeChild(childNode)childNode.parentNode.removeChild(childNode)
- 功能:删除DOM中的子节点,返回被删除的节点
3.5.6、克隆节点
javascript
node.cloneNode(deep)
- 参数:布尔值(默认false)
- false:仅克隆节点本身
- true:克隆节点及其所有子节点
- 返回:节点的副本
html
<body>
<div id="box">box盒子</div>
<button>克隆</button>
<script>
const box = document.getElementById("box");
document.querySelector("button").onclick = function() {
const newBox = box.cloneNode(true);
box.parentNode.appendChild(newBox);
};
</script>
</body>
3.5.7、其他创建节点方式
-
element.innerHTML- 可解析HTML标签
- 设置/获取元素内容
-
element.innerText- 纯文本显示,不解析HTML标签
-
document.write()- 直接写入页面内容流
- 文档加载完成后使用会重绘整个页面
html
<body>
<button>获取</button>
<button>添加</button>
<ul>
<li>《红楼梦》</li>
</ul>
<script>
const btns = document.querySelectorAll("button");
const ul = document.querySelector("ul");
btns[0].onclick = function() {
console.log(ul.innerHTML, ul.innerText);
};
btns[1].onclick = function() {
// 方式1:逐个添加
// const li = document.createElement("li");
// li.innerHTML = "《水浒传》";
// ul.appendChild(li);
// 方式2:批量设置
ul.innerHTML = "<li>《红楼梦》</li><li>《水浒传》</li>";
};
</script>
</body>
insertAdjacentHTML()- 将文本解析为节点并插入指定位置
- 不会替换现有节点
语法:
javascript
element.insertAdjacentHTML(position, text)
参数:
- position:
- 'beforebegin':元素自身之前
- 'afterbegin':元素内部第一个子节点前
- 'beforeend':元素内部最后一个子节点后
- 'afterend':元素自身之后
- text:要插入的HTML文本(可配合模板字符串使用)
html
<body>
<button>添加</button>
<ul>
<li>《红楼梦》</li>
</ul>
<script>
const ul = document.querySelector("ul");
document.querySelector("button").onclick = function() {
ul.insertAdjacentHTML('beforeend', `<li>《水浒传》</li>`);
};
</script>
</body>
3.6、事件操作
3.6.1、事件注册方式
3.6.1.1、传统注册方法 使用on开头的事件属性,例如onclick
特点:
- 同一元素同一事件只能绑定一个处理函数
- 后注册的函数会覆盖前注册的函数
示例:
javascript
var btns = document.querySelectorAll("button");
btns[0].onclick = function() {
alert("1"); // 不会执行
};
btns[0].onclick = function() {
alert("2"); // 会执行
};
3.6.1.2、addEventListener方法 语法:
javascript
addEventListener(type, listener[, useCapture])
特点:
- 支持同一元素同一事件绑定多个处理函数
- 按注册顺序依次执行
参数说明:
- type:事件类型字符串(不带on前缀),如"click"、"mouseover"
- listener:事件处理函数
- useCapture:可选布尔值,默认为false(冒泡阶段处理),设为true则在捕获阶段处理
注意:IE8及以下版本不支持
示例:
javascript
btns[1].addEventListener("click", function() {
alert(1);
}, false);
btns[1].addEventListener("click", function() {
alert(2);
}, false);
3.6.1.3、attachEvent方法 语法:
javascript
attachEvent(type, listener)
特点:
- IE8专用方法
- 支持绑定多个处理函数
- 后绑定的函数先执行
参数说明:
- type:带on前缀的事件字符串
- listener:回调函数
示例:
javascript
// 仅适用于IE8
btns[2].attachEvent("onclick", function() {
alert("attachEvent 1");
});
btns[2].attachEvent("onclick", function() {
alert("attachEvent 2");
});
3.6.2、事件解绑
3.6.2.1、传统注册方式解绑 方法:
javascript
eventTarget.onclick = null
示例:
javascript
btns[0].onclick = function() {
alert("1");
btns[0].onclick = null; // 解绑事件
};
3.6.2.2、addEventListener方法解绑 方法:
javascript
eventTarget.removeEventListener(type, listener)
示例:
javascript
btns[1].addEventListener("click", fun);
function fun() {
alert(1);
btns[1].removeEventListener("click", fun); // 解绑事件
}
3.6.2.3、attachEvent方法解绑 方法:
javascript
eventTarget.detachEvent(eventName, callback)
示例:
javascript
btns[2].attachEvent("onclick", fun1);
function fun1() {
alert("attachEvent 1");
btns[2].detachEvent("onclick", fun1); // 解绑事件
}
3.6.3、DOM事件流
3.6.3.1、事件流概述
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播的过程叫事件流
3.6.3.2、事件流3个阶段
(1)、捕获阶段:从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递(从外向内)
(2)、当前目标阶段:触发自己的事件
(3)、冒泡阶段:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发(从内向外)
3.6.3.3、事件流指定阶段
js代码中只能执行捕获或者冒泡其中的一个阶段,其中onclick和attachEvent只能得到冒泡阶段,我们可以通过addEventListener(type,listener[,useCapture])中的第三个参数来分别演示冒泡和捕获
useCapture:可选,是否在捕获阶段触发事件,需要一个布尔值,默认是false,在冒泡阶段处理程序,如果是true,就是在捕获阶段处理程序
<body>
给box、box1绑定点击事件,弹出对应的信息
需求1:弹出box、box1信息
需求2:弹出box1、box信息
-->
<div class="box">
<div class="box1"></div>
</div>
<script>
var boxs = document.querySelectorAll("div");
// 需求1
// boxs[0].addEventListener(
// "click",
// function () {
// alert("我是box");
// },
// true
// );
// boxs[1].addEventListener(
// "click",
// function () {
// alert("我是box1");
// },
// true
// );
//需求2
boxs[0].addEventListener(
"click",
function () {
alert("我是box");
},
false
);
boxs[1].addEventListener(
"click",
function () {
alert("我是box1");
},
false
);
</script>
</body>
注意:
实际开发中我们很少使用事件捕获,我们更关注事件冒泡
有些事件是没有冒泡的,比如onblur、onfoucs、onmuseenter、onmouseleave
事件冒泡有时我们需要,有时需要避免
3.6.4 事件对象
3.6.4.1 概念
事件对象是指事件发生时,与该事件相关的所有信息数据的集合。它包含多种属性和方法,用于获取事件相关信息。
javascript
box1.onmousemove = function(event) {};
3.6.4.2 注意事项
event是事件对象,作为监听函数的形参,可自定义命名(如event、evt、e等)- 事件对象由系统自动创建,无需手动传入实参
- IE低版本存在兼容性问题,可通过
event = event || window.event解决(通常无需考虑)
3.6.4.3 常用属性
e.target:返回触发事件的对象e.type:返回事件类型(如click、mouseover,不带on前缀)e.preventDefault():阻止默认行为(非IE6-8)e.stopPropagation():阻止事件冒泡(非IE6-8)e.offsetX/Y:鼠标相对于当前元素的位置e.clientX/Y:鼠标相对于浏览器窗口的坐标e.pageX/Y:鼠标相对于文档页面的坐标e.screenX/Y:鼠标相对于屏幕的坐标
html
<body>
<div class="box">
<div class="box1"></div>
<a href="https://www.baidu.com/">百度</a>
</div>
<script>
var boxs = document.querySelectorAll("div");
var a = document.querySelector("a");
boxs[0].addEventListener("click", function(e) {
console.log(e.target, "e");
console.log(this, "this");
console.log(e.type, "e.type");
});
a.onclick = function(e) {
e.preventDefault();
e.stopPropagation();
};
</script>
</body>
课堂案例:鼠标坐标显示
html
<body>
<div id="box1"></div>
<div id="box2"></div>
<script>
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
box1.onmousemove = function(event) {
var x = event.clientX;
var y = event.clientY;
box2.innerHTML = "x=" + x + ", y=" + y;
};
</script>
</body>
3.6.5 事件委托
通过将事件绑定到祖先元素,利用冒泡原理影响子节点,减少事件绑定次数,提升性能。新增/删除元素时无需重新绑定。
html
<body>
<button id="btn01">增加链接</button>
<ul id="u1">
<li><a href="#" class="link">链接一</a></li>
<li><a href="#" class="link">链接二</a></li>
<li><a href="#" class="link">链接三</a></li>
</ul>
<script>
var btn01 = document.getElementById("btn01");
var u1 = document.querySelector("#u1");
btn01.onclick = function() {
var li = document.createElement("li");
li.innerHTML = '<a href="#" class="link">新建超链接</a>';
u1.appendChild(li);
};
u1.onclick = function(event) {
if (event.target.className == "link") {
alert("hi");
}
};
</script>
</body>
3.6.6 键盘事件
| 事件类型 | 触发条件 |
|---|---|
onkeyup |
按键松开时触发 |
onkeydown |
按键按下时触发 |
onkeypress |
按键按下时触发 |
e.keyCode:返回按键的ASCII值
html
<body>
<input type="text" />
<script>
document.onkeydown = function(e) {
console.log(e.keyCode);
};
var int = document.querySelector("input");
int.onkeydown = function(e) {
if (e.keyCode >= 48 && e.keyCode <= 57) {
return false; // 阻止数字输入
}
};
</script>
</body>
四、BOM
4.1、BOM概述
4.1.1、BOM简介
BOM(browser Object)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。
BOM由一系列的对象构成,并且每个对象都提供了很多方法与属性
BOM缺乏标准,JS语法的标准化组织是ECMA,DOM的标准化组织是W3C,BOM最初是Netscape浏览器标准的一部分
4.1.2、DOM与BOM的区别
|----|------------------|--------------------------|
| 类别 | DOM | BOM |
| 1 | 文档对象模型 | 浏览器对象模型 |
| 2 | DOM是把文档当做一个对象来看待 | 把浏览器当做一个对象来看待 |
| 3 | 顶级对象是document | 顶级对象是window |
| 4 | 主要学习操作页面元素 | 学习浏览器窗口交互的一些对象 |
| 5 | W3C标准规范 | 各浏览器厂商在各自浏览器上定义的标准,兼容性较差 |
4.1.3、BOM的构成(对象)
所有 BOM 对象都以 window 为顶层,可直接访问(省略 window. 前缀)
BOM比DOM更大,它包含DOM
|----------|----------|------------|--------|---------|
| window |||||
| document | location | navigation | screen | history |
Window
- 地位:BOM 的核心对象,代表浏览器窗口或标签页,是所有 BOM 对象的顶层对象。
- 作用:
-
- 包含其他所有 BOM 对象(如
document、history等)。 - 提供窗口控制(如打开、关闭、调整大小)、定时器、全局变量和函数等功能。
- 包含其他所有 BOM 对象(如
-
常用方法 / 属性:
window.open() // 打开新窗口
window.close() // 关闭当前窗口
window.innerWidth // 窗口内部宽度
window.alert() // 弹出提示框
window.setTimeout() // 定时器
注意:window下的一个特殊属性window.name,所以定义变量时,尽量不用name这个变量名
document 对象
-
地位:属于 BOM,但也常被视为 DOM(文档对象模型)的核心,代表当前加载的 HTML 文档。
-
作用:操作网页内容(如元素、文本、样式等)。
-
常用方法 / 属性:
document.getElementById() // 通过ID获取元素
document.title // 获取/设置网页标题
document.body // 访问<body>元素
document.createElement() // 创建新元素
Navigator(浏览器的意思)
-
作用:提供浏览器自身的信息(如浏览器类型、版本、操作系统等)。
-
常用属性:
navigator.userAgent // 浏览器标识字符串(如包含"Chrome"、"Safari"等信息)
navigator.platform // 运行浏览器的操作系统(如"Win32"、"MacIntel")
navigator.language // 浏览器默认语言(如"zh-CN")
navigator.onLine // 判断浏览器是否联网(true/false)
Location
-
作用:管理当前页面的 URL 信息,可用于获取或修改 URL、跳转页面等。
-
常用属性 / 方法
location.href // 获取完整URL(如"https://example.com/path?query=1")
location.protocol // 获取协议(如"https:")
location.host // 获取域名+端口(如"example.com:8080")
location.search // 获取查询参数(如"?id=123")
location.reload() // 刷新页面
location.assign("url") // 跳转到新URL
History
-
作用:管理浏览器的历史记录(当前标签页的访问历史)。
-
常用方法
history.back() // 后退到上一页(类似浏览器"后退"按钮)
history.forward() // 前进到下一页(类似浏览器"前进"按钮)
history.go(n) // 跳转到历史记录中第n页(n为正数前进,负数后退)
Screen
-
作用:提供用户屏幕的信息(如屏幕尺寸、分辨率等)。
-
常用属性:
screen.width // 屏幕宽度(像素)
screen.height // 屏幕高度(像素)
screen.availWidth // 屏幕可用宽度(扣除任务栏等后的宽度)
screen.colorDepth // 屏幕颜色深度(如24位)
注意:这些BOM对象在浏览器中都是作为window对象的属性来保存的,可以通过window对象来使用,也可以直接使用
4.2、window对象的常见事件
4.2.1、onload窗口加载事件
-
window.onload=function(){}传统注册事件方式(只能注册一次,多次注册会覆盖前一个)
-
window.addEventListener("load",function(){})当文档内容完全加载完成后触发(包括图像、脚本文件、CSS文件等)
4.2.2、DOMContentLoaded窗口加载事件
document.addEventListener("DOMContentLoaded",function(){})
当页面DOM结构加载完毕后立即执行,比onload事件触发更早
html
<body>
<script>
document.addEventListener("DOMContentLoaded", function() {
var box = document.querySelector(".box");
box.addEventListener("click", function() {
this.style.backgroundColor = "pink";
});
});
</script>
<div class="box">box</div>
</body>
4.2.3、调整窗口大小事件
window.onresize=function(){}
或
window.addEventListener("resize",function(){})
窗口大小改变时触发,可用于实现响应式效果
html
<div>box</div>
<script>
var box = document.querySelector("div");
window.addEventListener("resize", function() {
if (window.innerWidth < 800) {
box.style.display = "none";
} else {
box.style.display = "block";
}
});
</script>
4.3、定时器
4.3.1、setInterval()定时调用
语法:setInterval(回调函数, 间隔时间)
参数:
- 回调函数:定时执行的函数
- 间隔时间:毫秒单位
返回值:定时器唯一标识(Number类型)
关闭定时器:clearInterval(标识符)
html
<h1 id="count"></h1>
<script>
var count = document.getElementById("count");
var num = 1;
var timer = setInterval(function() {
count.innerHTML = num++;
if (num == 5) clearInterval(timer);
}, 1000);
</script>
4.3.2、setTimeout()延时调用
语法:window.setTimeout(回调函数, 延迟时间)
特点:仅执行一次
关闭定时器:clearTimeout(标识符)
javascript
var timer = setTimeout(function() {
console.log(num++);
}, 1000);
clearTimeout(timer);
4.4、JS执行机制
4.4.1、JS是单线程
JS设计为单线程以避免操作冲突(如同时修改和删除DOM)。单线程意味着任务需要排队执行,可能导致页面渲染阻塞。
4.4.2、同步和异步
- 同步:顺序执行,前任务完成才能执行后任务
- 异步:任务放入任务队列,主线程空闲时执行
常见异步任务:
- setTimeout/setInterval
- DOM事件
- Promise
- Ajax请求
4.4.3、事件循环机制
- 主线程顺序执行同步任务
- 异步任务进入任务队列等待
- 主线程空闲时检查任务队列
- 将可执行任务加入主线程
- 循环往复
html
<button>点击</button>
<script>
var btn = document.querySelector("button");
btn.onclick = function() {
console.log("点击事件");
};
console.log("同步任务1");
setTimeout(function() {
console.log("定时器回调");
}, 1000);
console.log("同步任务2");
</script>
4.4.3、this指向总结
- 直接调用:指向window
- 对象方法:指向调用对象
- 构造函数:指向实例对象
- call/apply/bind:指向指定对象
- 事件回调:指向事件源
- 定时器:指向window
4.2、window对象的常见事件
4.2.1、onload窗口加载事件
-
window.onload=function(){}传统注册事件方式(只能注册一次,多次注册会覆盖前一个)
-
window.addEventListener("load",function(){})当文档内容完全加载完成后触发(包括图像、脚本文件、CSS文件等)
4.2.2、DOMContentLoaded窗口加载事件
document.addEventListener("DOMContentLoaded",function(){})
当页面DOM结构加载完毕后立即执行,比onload事件触发更早
html
<body>
<script>
document.addEventListener("DOMContentLoaded", function() {
var box = document.querySelector(".box");
box.addEventListener("click", function() {
this.style.backgroundColor = "pink";
});
});
</script>
<div class="box">box</div>
</body>
4.2.3、调整窗口大小事件
window.onresize=function(){}
或
window.addEventListener("resize",function(){})
窗口大小改变时触发,可用于实现响应式效果
html
<div>box</div>
<script>
var box = document.querySelector("div");
window.addEventListener("resize", function() {
if (window.innerWidth < 800) {
box.style.display = "none";
} else {
box.style.display = "block";
}
});
</script>
4.3、定时器
4.3.1、setInterval()定时调用
语法:setInterval(回调函数, 间隔时间)
参数:
- 回调函数:定时执行的函数
- 间隔时间:毫秒单位
返回值:定时器唯一标识(Number类型)
关闭定时器:clearInterval(标识符)
html
<h1 id="count"></h1>
<script>
var count = document.getElementById("count");
var num = 1;
var timer = setInterval(function() {
count.innerHTML = num++;
if (num == 5) clearInterval(timer);
}, 1000);
</script>
4.3.2、setTimeout()延时调用
语法:window.setTimeout(回调函数, 延迟时间)
特点:仅执行一次
关闭定时器:clearTimeout(标识符)
javascript
var timer = setTimeout(function() {
console.log(num++);
}, 1000);
clearTimeout(timer);
4.4、JS执行机制
4.4.1、JS是单线程
JS设计为单线程以避免操作冲突(如同时修改和删除DOM)。单线程意味着任务需要排队执行,可能导致页面渲染阻塞。
4.4.2、同步和异步
- 同步:顺序执行,前任务完成才能执行后任务
- 异步:任务放入任务队列,主线程空闲时执行
常见异步任务:
- setTimeout/setInterval
- DOM事件
- Promise
- Ajax请求
4.4.3、事件循环机制
- 主线程顺序执行同步任务
- 异步任务进入任务队列等待
- 主线程空闲时检查任务队列
- 将可执行任务加入主线程
- 循环往复
html
<button>点击</button>
<script>
var btn = document.querySelector("button");
btn.onclick = function() {
console.log("点击事件");
};
console.log("同步任务1");
setTimeout(function() {
console.log("定时器回调");
}, 1000);
console.log("同步任务2");
</script>
4.4.3、this指向总结
- 直接调用:指向window
- 对象方法:指向调用对象
- 构造函数:指向实例对象
- call/apply/bind:指向指定对象
- 事件回调:指向事件源
- 定时器:指向window
4.5、location对象
4.5.1、location对象简介
window对象提供了location属性,用于获取或设置窗口的URL,并能解析URL。由于该属性返回一个对象,因此称为location对象。
4.5.2、URL详解
统一资源定位符(URL)是互联网上标准资源的地址,每个文件都有唯一的URL,指明文件位置及浏览器处理方式,俗称"网址"。
URL由三部分组成:
- 资源类型
- 主机域名
- 资源文件名
标准语法格式: protocol://hostname[:port]/path/[;parameters][?query]#fragment
URL组成部分说明:
-
协议(Scheme)
- 定义通信协议类型
- 常见协议:
- http://(非加密)
- https://(加密)
- ftp://
- mailto:
- 示例:
https://
-
域名/IP地址
- 标识服务器位置
- 示例:
www.example.com
-
端口号(Port)
- 可选,默认端口可省略
- HTTP默认:80
- HTTPS默认:443
- 示例:
:8080
-
路径(Path)
- 资源在服务器的具体位置
- 示例:
/blog/article1
-
查询参数(Query)
?开头,多个参数用&分隔- 示例:
?id=123&category=tech
-
锚点(Fragment)
#开头,定位页面特定位置- 示例:
#section2
完整示例: https://www.example.com:443/blog/post?articleId=567#comments
注意事项:
- 部分组件可选
- 需编码特殊字符(如空格为%20)
- 各组件功能明确区分
4.5.3、location对象属性和方法
属性:
| 属性 | 说明 |
|---|---|
| href | 返回完整URL |
| hash | 返回#后的内容 |
| host | 返回服务器名和端口 |
| hostname | 返回服务器名(无端口) |
| pathname | 返回路径和文件名 |
| port | 返回端口号 |
| protocol | 返回使用协议 |
| search | 返回查询字符串 |
方法:
| 方法 | 功能 |
|---|---|
| assign() | 跳转页面(保留历史记录) |
| replace() | 跳转页面(不保留历史记录) |
| reload() | 重新加载页面(参数true强制刷新) |
4.6、navigator对象
navigator对象包含浏览器信息。由于历史原因,大部分属性已不再适用,通常仅使用userAgent属性识别浏览器。userAgent是包含浏览器信息的字符串,不同浏览器具有不同的userAgent。
4.7、history对象
history对象用于与浏览器历史记录交互,包含用户访问过的URL。
属性:
| 属性 | 说明 |
|---|---|
| length | 返回访问过的页面数量 |
方法:
| 方法 | 功能 |
|---|---|
| back() | 后退到上一页 |
| forward() | 前进到下一页 |
| go(n) | 跳转指定页面(正数前进,负数后退) |
五、JavaScript补充
5.1 元素的三大系列
5.1.1 offset系列
5.1.1.1 offset基础
offset系列属性用于动态获取元素的位置偏移和尺寸信息:
- 获取元素相对于定位祖先元素的偏移位置
- 获取元素自身的尺寸(宽度和高度)
- 注意:所有返回值均为无单位数值
常用offset属性:
| 属性 | 说明 |
|---|---|
element.offsetParent |
返回最近的有定位的父元素,若无则返回body |
element.offsetTop |
返回元素顶部相对于定位父元素上边的偏移量 |
element.offsetLeft |
返回元素左侧相对于定位父元素左边的偏移量 |
element.offsetWidth |
返回元素总宽度(包含内容、padding和边框) |
element.offsetHeight |
返回元素总高度(包含内容、padding和边框) |
5.1.1.2 offset与style的区别
| 特性 | offset | style |
|---|---|---|
| 样式来源 | 可获取任意样式表(行内/内部) | 仅能获取行内样式 |
| 返回值 | 无单位数值 | 带单位的字符串 |
| 尺寸计算 | 包含padding+border+内容 | 仅内容宽度 |
| 读写性 | 只读属性 | 可读写属性 |
| 适用场景 | 获取元素尺寸和位置 | 修改元素样式值 |
html
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 200px;
height: 200px;
border: 1px solid red;
margin: 50px auto;
position: relative;
}
.box1 {
width: 100px;
height: 100px;
background-color: orange;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
</style>
<body>
<div class="box">
<div class="box1"></div>
</div>
<div class="box2" style="width: 50px; height: 50px; background-color: red; border: 10px solid green"></div>
<script>
var box = document.querySelector(".box");
var box1 = document.querySelector(".box1");
var box2 = document.querySelector(".box2");
// offset获取示例
// console.log(box1.offsetParent, "offsetParent");
// console.log(box1.offsetTop, "offsetTop");
// console.log(box1.offsetLeft, "offsetLeft");
// console.log(box.offsetWidth, "offsetWidth");
// console.log(box.offsetHeight, "offsetHeight");
// style获取示例
// console.log(box2.style.width); // "50px"
// box2.style.width = "200px";
</script>
</body>
5.1.2 Client 系列
5.1.2.1 Client 基础
通过 client 系列属性可动态获取元素可视区域信息,包括边框尺寸和元素大小等。
Client 系列属性:
| 属性 | 说明 |
|---|---|
element.clientTop |
返回元素上边框宽度 |
element.clientLeft |
返回元素左边框宽度 |
element.clientWidth |
返回包含 padding 的内容区宽度(不含边框,无单位) |
element.clientHeight |
返回包含 padding 的内容区高度(不含边框,无单位) |
html
<head>
<meta charset="UTF-8">
<title>Client Demo</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
border: 10px solid orange;
padding: 20px;
margin: 100px auto;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var box = document.querySelector(".box");
// console.log(box.clientTop); // 10
// console.log(box.clientLeft); // 10
// console.log(box.clientWidth); // 140
// console.log(box.clientHeight); // 140
</script>
</body>
5.1.2.2 Client 应用 - flexible.js 解析
javascript
(function flexible(window, document) {
var docEl = document.documentElement;
var dpr = window.devicePixelRatio || 1;
// 设置 body 字体大小
function setBodyFontSize() {
if (document.body) {
document.body.style.fontSize = 12 * dpr + "px";
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// 设置 rem 单位
function setRemUnit() {
var rem = docEl.clientWidth / 10;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// 响应式调整
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", function(e) {
if (e.persisted) setRemUnit();
});
// 0.5px 兼容处理
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
})(window, document);
5.1.3 Scroll 系列
5.1.3.1 Scroll 基础
通过 scroll 系列属性可动态获取元素尺寸和滚动距离等信息。
Scroll 系列属性:
| 属性 | 说明 |
|---|---|
element.scrollTop |
返回上侧滚动距离(无单位) |
element.scrollLeft |
返回左侧滚动距离(无单位) |
element.scrollWidth |
返回实际宽度(内容+padding,不含边框,无单位) |
element.scrollHeight |
返回实际高度(内容+padding,不含边框,无单位) |
html
<head>
<meta charset="UTF-8">
<title>Scroll Demo</title>
<style>
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
border: 10px solid red;
padding: 20px;
overflow: auto;
}
p {
width: 400px;
height: 400px;
background-color: orange;
}
</style>
</head>
<body>
<div class="box1">
<p>示例文本</p>
</div>
<script>
var box = document.querySelector(".box1");
// console.log("scrollWidth", box.scrollWidth);
// console.log("clientWidth", box.clientWidth);
// console.log("scrollHeight", box.scrollHeight);
// console.log("clientHeight", box.clientHeight);
// console.log("scrollTop", box.scrollTop);
// console.log("scrollLeft", box.scrollLeft);
// box.addEventListener("scroll", function() {
// console.log("scrollTop", box.scrollTop);
// console.log("scrollLeft", box.scrollLeft);
// });
</script>
</body>
5.1.2 Client 系列
5.1.2.1 Client 基础
通过 client 系列属性可动态获取元素可视区域信息,包括边框尺寸和元素大小等。
Client 系列属性:
| 属性 | 说明 |
|---|---|
element.clientTop |
返回元素上边框宽度 |
element.clientLeft |
返回元素左边框宽度 |
element.clientWidth |
返回包含 padding 的内容区宽度(不含边框,无单位) |
element.clientHeight |
返回包含 padding 的内容区高度(不含边框,无单位) |
html
<head>
<meta charset="UTF-8">
<title>Client Demo</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
border: 10px solid orange;
padding: 20px;
margin: 100px auto;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var box = document.querySelector(".box");
// console.log(box.clientTop); // 10
// console.log(box.clientLeft); // 10
// console.log(box.clientWidth); // 140
// console.log(box.clientHeight); // 140
</script>
</body>
5.1.2.2 Client 应用 - flexible.js 解析
javascript
(function flexible(window, document) {
var docEl = document.documentElement;
var dpr = window.devicePixelRatio || 1;
// 设置 body 字体大小
function setBodyFontSize() {
if (document.body) {
document.body.style.fontSize = 12 * dpr + "px";
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// 设置 rem 单位
function setRemUnit() {
var rem = docEl.clientWidth / 10;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// 响应式调整
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", function(e) {
if (e.persisted) setRemUnit();
});
// 0.5px 兼容处理
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
})(window, document);
5.1.3 Scroll 系列
5.1.3.1 Scroll 基础
通过 scroll 系列属性可动态获取元素尺寸和滚动距离等信息。
Scroll 系列属性:
| 属性 | 说明 |
|---|---|
element.scrollTop |
返回上侧滚动距离(无单位) |
element.scrollLeft |
返回左侧滚动距离(无单位) |
element.scrollWidth |
返回实际宽度(内容+padding,不含边框,无单位) |
element.scrollHeight |
返回实际高度(内容+padding,不含边框,无单位) |
html
<head>
<meta charset="UTF-8">
<title>Scroll Demo</title>
<style>
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
border: 10px solid red;
padding: 20px;
overflow: auto;
}
p {
width: 400px;
height: 400px;
background-color: orange;
}
</style>
</head>
<body>
<div class="box1">
<p>示例文本</p>
</div>
<script>
var box = document.querySelector(".box1");
// console.log("scrollWidth", box.scrollWidth);
// console.log("clientWidth", box.clientWidth);
// console.log("scrollHeight", box.scrollHeight);
// console.log("clientHeight", box.clientHeight);
// console.log("scrollTop", box.scrollTop);
// console.log("scrollLeft", box.scrollLeft);
// box.addEventListener("scroll", function() {
// console.log("scrollTop", box.scrollTop);
// console.log("scrollLeft", box.scrollLeft);
// });
</script>
</body>
5.1.4 小结:三大系列对比
| 属性 | 作用描述 | 返回值说明 |
|---|---|---|
| offsetWidth | 返回元素宽度(包含padding、边框和内容区) | 无单位数值 |
| clientWidth | 返回元素宽度(包含padding和内容区,不含边框) | 无单位数值 |
| scrollWidth | 返回元素实际宽度(包含padding,不含边框) | 无单位数值 |
应用场景:
- offset系列:获取元素位置(offsetLeft/offsetTop/offsetWidth/offsetHeight)
- client系列:获取元素大小(clientWidth/clientHeight)
- scroll系列:获取滚动距离(scrollTop)
5.2 动画函数封装
5.2.1 简单动画实现 核心原理:通过setInterval()持续改变元素位置
实现步骤:
- 获取元素当前位置
- 在当前位置基础上增加移动距离
- 使用定时器循环执行
- 设置停止条件
- 需要元素具有定位属性,通过修改left值实现移动
html
<script>
var box = document.querySelector("div");
var timer = setInterval(function() {
if(box.offsetLeft >= 500) {
clearInterval(timer);
return;
}
box.style.left = box.offsetLeft + 10 + "px";
}, 30);
</script>
5.2.2 动画函数封装
html
<script>
function animate(obj, target) {
var timer = setInterval(function() {
if(obj.offsetLeft >= target) {
clearInterval(timer);
return;
}
obj.style.left = obj.offsetLeft + 10 + "px";
}, 30);
}
var box = document.querySelector("div");
var span = document.querySelector("span");
animate(box, 500);
animate(span, 300);
</script>
5.2.3 优化动画函数 改进点:
- 为不同元素绑定独立定时器
- 确保只有一个定时器运行
- 到达目标位置后不再响应
html
<script>
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if(obj.offsetLeft >= target) {
clearInterval(obj.timer);
return;
}
obj.style.left = obj.offsetLeft + 10 + "px";
}, 30);
}
var btn = document.querySelector("button");
btn.addEventListener("click", function() {
animate(document.querySelector("span"), 300);
});
animate(document.querySelector("div"), 500);
</script>
5.2.4 缓动效果实现 原理:通过动态调整移动步长实现速度变化
核心算法: 步长 = (目标位置 - 当前位置) / 10 停止条件:当前位置等于目标位置
html
<script>
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;
if(obj.offsetLeft == target) {
clearInterval(obj.timer);
return;
}
obj.style.left = obj.offsetLeft + step + "px";
}, 30);
}
</script>
5.2.5 动画函数优化
html
<script>
function animate(obj, target, callback) {
// 函数实现...
}
</script>
5.1.4 小结:三大系列对比
| 属性 | 作用描述 | 返回值说明 |
|---|---|---|
| offsetWidth | 返回元素宽度(包含padding、边框和内容区) | 无单位数值 |
| clientWidth | 返回元素宽度(包含padding和内容区,不含边框) | 无单位数值 |
| scrollWidth | 返回元素实际宽度(包含padding,不含边框) | 无单位数值 |
应用场景:
- offset系列:获取元素位置(offsetLeft/offsetTop/offsetWidth/offsetHeight)
- client系列:获取元素大小(clientWidth/clientHeight)
- scroll系列:获取滚动距离(scrollTop)
5.2 动画函数封装
5.2.1 简单动画实现 核心原理:通过setInterval()持续改变元素位置
实现步骤:
- 获取元素当前位置
- 在当前位置基础上增加移动距离
- 使用定时器循环执行
- 设置停止条件
- 需要元素具有定位属性,通过修改left值实现移动
html
<script>
var box = document.querySelector("div");
var timer = setInterval(function() {
if(box.offsetLeft >= 500) {
clearInterval(timer);
return;
}
box.style.left = box.offsetLeft + 10 + "px";
}, 30);
</script>
5.2.2 动画函数封装
html
<script>
function animate(obj, target) {
var timer = setInterval(function() {
if(obj.offsetLeft >= target) {
clearInterval(timer);
return;
}
obj.style.left = obj.offsetLeft + 10 + "px";
}, 30);
}
var box = document.querySelector("div");
var span = document.querySelector("span");
animate(box, 500);
animate(span, 300);
</script>
5.2.3 优化动画函数 改进点:
- 为不同元素绑定独立定时器
- 确保只有一个定时器运行
- 到达目标位置后不再响应
html
<script>
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if(obj.offsetLeft >= target) {
clearInterval(obj.timer);
return;
}
obj.style.left = obj.offsetLeft + 10 + "px";
}, 30);
}
var btn = document.querySelector("button");
btn.addEventListener("click", function() {
animate(document.querySelector("span"), 300);
});
animate(document.querySelector("div"), 500);
</script>
5.2.4 缓动效果实现 原理:通过动态调整移动步长实现速度变化
核心算法: 步长 = (目标位置 - 当前位置) / 10 停止条件:当前位置等于目标位置
html
<script>
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;
if(obj.offsetLeft == target) {
clearInterval(obj.timer);
return;
}
obj.style.left = obj.offsetLeft + step + "px";
}, 30);
}
</script>
5.2.5、动画函数优化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>05.优化缓动动画动画函数</title>
<style>
* {
padding: 0;
margin: 0;
}
div {
width: 100px;
height: 100px;
background-color: pink;
position: absolute;
left: 0;
}
</style>
</head>
<body>
<button id="btn01">点击按钮,执行动画函数 500</button><br />
<button id="btn02">点击按钮,执行动画函数 800</button><br />
<div>丹洋其</div>
<script>
//优化三 加回调函数,可以在执行动画后,再执行其他内容
function animation(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 定义step,来代表每次移动的距离值
// 优化一:对于step会涉及到小数,将小数向上取整
// var step = Math.ceil((target - obj.offsetLeft) / 10);
// 优化二:动画还是会涉及到往回走,如果往回走,则step会是负值,要向小取整
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
// 如果传入了回调,则执行回调,否则,就不执行
if (callback) {
callback();
}
} else {
// console.log(222);
obj.style.left = obj.offsetLeft + step + "px";
}
}, 15);
}
var s1 = document.querySelector("div");
var btn01 = document.querySelector("#btn01");
var btn02 = document.querySelector("#btn02");
btn01.addEventListener("click", function () {
animation(s1, 500);
});
btn02.addEventListener("click", function () {
animation(s1, 800, function () {
alert("111");
});
});
</script>
</body>
</html>
5.2.6、animation.js文件并使用
animation.js
function animation(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
if (callback) {
callback();
}
} else {
console.log(222);
obj.style.left = obj.offsetLeft + step + "px";
}
}, 15);
}
5.3 JSON数据
5.3.1 JSON
(1)定义
JSON(JavaScript Object Notation)是JavaScript对象表示法的缩写。由于JavaScript对象只能被JS识别,而其他编程语言无法直接理解,因此引入了JSON这种特殊格式的字符串。JSON可以被任何编程语言识别,并能转换为各种语言中的对象。它是一种轻量级的数据交换格式,广泛应用于开发中的数据交互。
(2)特点
- 易于程序员阅读和编写
- 易于计算机解析和生成
- 本质上是JavaScript的子集,原生JavaScript支持JSON
(3)作用
JSON是一种与语言无关的数据交换格式:
- 用于前后端数据交互(Ajax)
- 用于移动端与服务端的数据交换
(4)语法规则
JSON语法简洁优雅,主要包含两种结构:
- 对象格式:
{"key1":value1, "key2":value2, "key3":value3...} - 数组格式:
[value1, value2, value3...]
允许的数据类型:字符串、数值、布尔值、null、对象、数组(不包括NaN、undefined和方法)
JSON与JavaScript对象格式相似,区别在于JSON属性名必须使用双引号。
语法规则:
- 键值对使用冒号(":")分隔
- 多个键值对使用逗号(",")分隔
- 对象使用大括号("{}")包裹
- 数组使用方括号("[]")包裹
(5)JSON方法
JavaScript提供了JSON工具类,用于JSON字符串和JS对象之间的转换。
JSON.parse(): 将JSON字符串转换为JS对象
javascript
var json = '{"name":"孙悟空","age":18,"gender":"男"}';
var o = JSON.parse(json);
console.log(o); // {name: '孙悟空', age: 18, gender: '男'}
console.log(o.gender); // 男
JSON.stringify(): 将JS对象转换为JSON字符串
javascript
var obj3 = {name: "猪八戒", age: 28, gender: "男"};
obj3 = JSON.stringify(obj3);
console.log(obj3); // {"name":"猪八戒","age":28,"gender":"男"}
5.3.2 XML
5.3.2.1 什么是XML
XML(eXtensible Markup Language)是可扩展标记语言:
- 标记型语言:使用标签进行操作(类似HTML)
- 可扩展:标签可自定义(如
<aa>、<猫>) - 主要功能是存储数据,而非显示数据
5.3.2.2 XML的应用
- 系统间数据传输格式
- 存储关系型数据
- 系统配置文件
- Android应用开发中的页面展示
5.3.3 JSON与XML比较
JSON常被拿来与XML比较,因其设计初衷部分是为了替代XML。相比XML,JSON的优势:
- 没有结束标签,长度更短,读写更快
- 能被JavaScript直接解析
- 原生支持数组
JSON示例:
json
{
"id": 12,
"name": "gao",
"age": 30,
"gender": "男",
"interests": ["篮球", "爬山", "旅游"]
}
XML示例:
XML
<root>
<id>12</id>
<name>gao</name>
<age>30</age>
<gender>男</gender>
<interest>篮球</interest>
<interest>爬山</interest>
<interest>旅游</interest>
</root>
JSON可直接使用数组,而XML需要重复标签,会增加无意义的标签数量,不利于网络传输。XML主要应用于配置文件。
5.4 本地存储
5.3 JSON数据
5.3.1 JSON
(1)定义
JSON(JavaScript Object Notation)是JavaScript对象表示法的缩写。由于JavaScript对象只能被JS识别,而其他编程语言无法直接理解,因此引入了JSON这种特殊格式的字符串。JSON可以被任何编程语言识别,并能转换为各种语言中的对象。它是一种轻量级的数据交换格式,广泛应用于开发中的数据交互。
(2)特点
- 易于程序员阅读和编写
- 易于计算机解析和生成
- 本质上是JavaScript的子集,原生JavaScript支持JSON
(3)作用
JSON是一种与语言无关的数据交换格式:
- 用于前后端数据交互(Ajax)
- 用于移动端与服务端的数据交换
(4)语法规则
JSON语法简洁优雅,主要包含两种结构:
- 对象格式:
{"key1":value1, "key2":value2, "key3":value3...} - 数组格式:
[value1, value2, value3...]
允许的数据类型:字符串、数值、布尔值、null、对象、数组(不包括NaN、undefined和方法)
JSON与JavaScript对象格式相似,区别在于JSON属性名必须使用双引号。
语法规则:
- 键值对使用冒号(":")分隔
- 多个键值对使用逗号(",")分隔
- 对象使用大括号("{}")包裹
- 数组使用方括号("[]")包裹
(5)JSON方法
JavaScript提供了JSON工具类,用于JSON字符串和JS对象之间的转换。
JSON.parse(): 将JSON字符串转换为JS对象
javascript
var json = '{"name":"孙悟空","age":18,"gender":"男"}';
var o = JSON.parse(json);
console.log(o); // {name: '孙悟空', age: 18, gender: '男'}
console.log(o.gender); // 男
JSON.stringify(): 将JS对象转换为JSON字符串
javascript
var obj3 = {name: "猪八戒", age: 28, gender: "男"};
obj3 = JSON.stringify(obj3);
console.log(obj3); // {"name":"猪八戒","age":28,"gender":"男"}
5.3.2 XML
5.3.2.1 什么是XML
XML(eXtensible Markup Language)是可扩展标记语言:
- 标记型语言:使用标签进行操作(类似HTML)
- 可扩展:标签可自定义(如
<aa>、<猫>) - 主要功能是存储数据,而非显示数据
5.3.2.2 XML的应用
- 系统间数据传输格式
- 存储关系型数据
- 系统配置文件
- Android应用开发中的页面展示
5.3.3 JSON与XML比较
JSON常被拿来与XML比较,因其设计初衷部分是为了替代XML。相比XML,JSON的优势:
- 没有结束标签,长度更短,读写更快
- 能被JavaScript直接解析
- 原生支持数组
JSON示例:
json
{
"id": 12,
"name": "gao",
"age": 30,
"gender": "男",
"interests": ["篮球", "爬山", "旅游"]
}
XML示例:
XML
<root>
<id>12</id>
<name>gao</name>
<age>30</age>
<gender>男</gender>
<interest>篮球</interest>
<interest>爬山</interest>
<interest>旅游</interest>
</root>
JSON可直接使用数组,而XML需要重复标签,会增加无意义的标签数量,不利于网络传输。XML主要应用于配置文件。
5.4 本地存储
localStorage和sessionStorage是HTML5提供的Web Storage本地存储机制,采用键值对形式存储数据,通常以JSON字符串格式保存在客户端。
作为对HTML4中Cookie存储机制的改进,Web Storage解决了Cookie的诸多缺点,成为HTML5推荐使用的存储方案。
5.4.1 Cookie机制
(1) Cookie简介
Cookie是服务器发送到用户浏览器并保存在本地的小段文本数据。当客户端请求服务器时,若需要记录用户状态,服务器会通过response颁发Cookie。浏览器保存该Cookie后,在后续请求中会自动将其发送回服务器,用于识别用户状态。
(2) Cookie的应用场景
- 保持用户登录状态
- 追踪用户行为
- 个性化页面定制
- 实现购物车功能(如淘宝记录用户浏览历史)
5.4.2 window.sessionStorage
特性:
- 生命周期随浏览器窗口关闭而结束
- 仅在同一窗口(页面)内共享数据
- 存储容量较小
- 采用键值对JSON格式存储
常用方法:
javascript
sessionStorage.setItem(key,value); // 存储数据
sessionStorage.getItem(key); // 获取数据
sessionStorage.removeItem(key); // 删除数据
sessionStorage.clear(); // 清空数据
5.4.3 window.localStorage
特性:
- 永久存储,需手动删除
- 支持同浏览器多窗口(页面)共享
- 存储容量较大
- 采用键值对JSON格式存储
常用方法:
javascript
localStorage.setItem(key,value); // 存储数据
localStorage.getItem(key); // 获取数据
localStorage.removeItem(key); // 删除数据
localStorage.clear(); // 清空数据
5.4.4 记住用户名案例
实现功能:勾选"记住用户名"后,下次打开浏览器自动显示上次登录的用户名。
html
<body>
<input type="text" id="username" />
<input type="checkbox" id="checkbox" />记住用户名
<script>
var userInt = document.getElementById("username");
var checkbox = document.getElementById("checkbox");
// 检查本地存储并初始化界面
if (localStorage.getItem("username")) {
userInt.value = localStorage.getItem("username");
checkbox.checked = true;
}
// 监听复选框变化
checkbox.addEventListener("change", function() {
if (this.checked) {
localStorage.setItem("username", userInt.value);
} else {
localStorage.removeItem("username");
}
});
</script>
</body>
5.4 本地存储
localStorage和sessionStorage是HTML5提供的Web Storage本地存储机制,采用键值对形式存储数据,通常以JSON字符串格式保存在客户端。
作为对HTML4中Cookie存储机制的改进,Web Storage解决了Cookie的诸多缺点,成为HTML5推荐使用的存储方案。
5.4.1 Cookie机制
(1) Cookie简介
Cookie是服务器发送到用户浏览器并保存在本地的小段文本数据。当客户端请求服务器时,若需要记录用户状态,服务器会通过response颁发Cookie。浏览器保存该Cookie后,在后续请求中会自动将其发送回服务器,用于识别用户状态。
(2) Cookie的应用场景
- 保持用户登录状态
- 追踪用户行为
- 个性化页面定制
- 实现购物车功能(如淘宝记录用户浏览历史)
5.4.2 window.sessionStorage
特性:
- 生命周期随浏览器窗口关闭而结束
- 仅在同一窗口(页面)内共享数据
- 存储容量较小
- 采用键值对JSON格式存储
常用方法:
javascript
sessionStorage.setItem(key,value); // 存储数据
sessionStorage.getItem(key); // 获取数据
sessionStorage.removeItem(key); // 删除数据
sessionStorage.clear(); // 清空数据
5.4.3 window.localStorage
特性:
- 永久存储,需手动删除
- 支持同浏览器多窗口(页面)共享
- 存储容量较大
- 采用键值对JSON格式存储
常用方法:
javascript
localStorage.setItem(key,value); // 存储数据
localStorage.getItem(key); // 获取数据
localStorage.removeItem(key); // 删除数据
localStorage.clear(); // 清空数据
5.4.4 记住用户名案例
实现功能:勾选"记住用户名"后,下次打开浏览器自动显示上次登录的用户名。
html
<body>
<input type="text" id="username" />
<input type="checkbox" id="checkbox" />记住用户名
<script>
var userInt = document.getElementById("username");
var checkbox = document.getElementById("checkbox");
// 检查本地存储并初始化界面
if (localStorage.getItem("username")) {
userInt.value = localStorage.getItem("username");
checkbox.checked = true;
}
// 监听复选框变化
checkbox.addEventListener("change", function() {
if (this.checked) {
localStorage.setItem("username", userInt.value);
} else {
localStorage.removeItem("username");
}
});
</script>
</body>