小小药虫 发表于 2024-4-14 22:41:04

Web APIs

0x01 概述


[*]API 是一些预先定义的函数,提供应用程序与开发人员基于某软件或硬件访问一组例程的能力
[*]Web APIs 是 W3C 组织的标准,是 JS 独有的部分
[*]Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API,即 DOM 与 BOM
0x02 DOM

(1)简介


[*]文档对象模型(Document Object Model)是 W3C 组织推荐的处理可扩展标记语言的标准编程接口

[*]可以改变网页内容、结构和样式

[*]DOM 树:DOM 对象
graph TB文档-->0[根元素
< html >]-->1[元素
< head >] & 2[元素
< body >]1-->11[元素
< title >]-->111[文本
文档标题]2-->21[元素
< a >] & 22[元素
< h1 >]21-->211[属性
href] & 212[文本
链接文本]22-->221[文本
一级标题]

[*]文档:即页面,DOM 中使用 document 表示
[*]元素:页面中的任何标签,DOM 中使用 element 表示
[*]节点:页面中的任何内容,DOM 中使用 node 表示

(2)获取元素

a. 根据 id 属性


[*]getElementById()
[*]返回带有指定 id 的元素对象
<p id="content">This is a paragraph.</p>b. 根据标签名


[*]getElementByTagName()
[*]返回带有指定标签名的元素对象集合
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>

[*]也可以用于获取父元素内所有指定标签名的子元素

[*]父元素必须为单个对象
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
c. 通过 HTML5 新方法


[*]根据类名返回元素对象集合

[*]getElementByClassName()
Item 1
Item 2
Item 3
[*]根据指定选择器返回第一个元素对象

[*]querySelector()
Item 1
Item 2
Item 3
[*]根据指定选择器返回元素对象集合

[*]querySelectorAll()
Item 1
Item 2
Item 3
d. 特殊元素


[*]html 元素
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>
    This is a simple page.
   
</body>
</html>
[*]body 元素
<body>
This is a simple page.

</body>
(3)事件基础


[*]JavaScript 可用于创建动态页面,事件是可以被 JavaScript 侦测到的行为
[*]页面中每个元素都可以产生某些可以触发 JavaScript 的事件
<p id="content">This is a paragraph.</p>
[*]事件三要素包括:

[*]事件源:事件被触发的对象
[*]事件类型:触发事件的方式
[*]事件处理:通过函数处理事件

[*]执行事件的步骤:

[*]获取事件源
[*]注册(或绑定)事件
[*]添加事件处理程序

[*]采用函数赋值形式


[*]常见鼠标事件
事件条件onclick左键<button><button><button><button>点击</button></button></button></button>后触发onmouseover经过时触发onmouseout离开时触发onfocus获得焦点触发onblur失去焦点触发onmousemove移动触发onmouseup弹起触发onmousedown按下触发
(4)操作元素


[*]使用 DOM 操作可以改变网页内容、结构和样式
a. 内容


[*]innerHTML:起始位置到终止位置的全部内容,包括 HTML 标签、空格、换行等
[*]innerText:类似 innerHTML,不包括 HTML 标签、空格、换行等
<p id="content">This is a paragraph.</p>Text in span
b. 属性


[*]如 src、href、id、value 等
[*]举例 1:图片切换至下一张
<button id="next">下一张图片</button>
<img src="https://www.cnblogs.com/./1.png" alt="图片1" />
[*]举例 2:显隐密码
<input type="password" name="password" autofocus />
<label>显示密码</label>
c. 样式


[*]行内样式操作


[*]JavaScript 中,样式采取驼峰命名法,如 backgroundColor 等
[*]JavaScript 修改样式操作产生的是行内样式,CSS 的权重更高

[*]类名样式操作


[*]className 会更改(覆盖)元素的类名

[*]举例 1:密码框格式错误提示信息
<input type="password" />
<p>输入 3~10 个字符</p>
[*]举例 2:(排他思想)
<button>按钮 1</button>
<button>按钮 2</button>
<button>按钮 3</button>
[*]举例 3:表格行在鼠标悬浮时换色
<table border="1">
<thead>
    <tr>


<th>Name</th>


<th>Age</th>


<th>Gender</th>
    </tr>
</thead>
<tbody>
    <tr>


<td>John</td>


<td>20</td>


<td>Male</td>
    </tr>
    <tr>


<td>Jane</td>


<td>21</td>


<td>Female</td>
    </tr>
    <tr>


<td>Jim</td>


<td>22</td>


<td>Male</td>
    </tr>
</tbody>
</table>
[*]举例 4:表单全选的选中与取消
<table border="1">
<thead>
    <tr>


<th><input type="checkbox" id="selectAll" /></th>


<th>Name</th>


<th>Age</th>
    </tr>
</thead>
<tbody>
    <tr>


<td><input type="checkbox" /></td>


<td>John</td>


<td>20</td>
    </tr>
    <tr>


<td><input type="checkbox" /></td>


<td>Jane</td>


<td>21</td>
    </tr>
    <tr>


<td><input type="checkbox" /></td>


<td>Jim</td>


<td>22</td>
    </tr>
</tbody>
</table>
d. 自定义属性


[*]element.属性 获取的是内置属性(即元素本身自带的属性)
[*]element.getAttribute('属性') 获取的是自定义和内置的属性


[*]自定义属性的目的:保存并使用数据

[*]对于可以简单且可以明文展示的数据可以保存在页面中,省去使用数据库

[*]HTML5 规定,自定义属性使用 data- 前缀命名并赋值
[*]HTML5 新增以下方法获取属性值:

(5)节点操作

a. 简介


[*]节点操作主要是利用节点层级关系获取元素

[*]利用父子兄节点关系获取元素
[*]逻辑性强
[*]兼容性差

[*]节点是页面中的任何内容,DOM 中使用 node 表示,均可使用 JavaScript 访问
[*]一般地,节点至少拥有以下基本属性:

[*]节点类型:nodeType
节点类型nodeType 值HTML 元素1属性2文本3
[*]节点名称:nodeName
[*]节点值:nodeValue

b. 父节点

c. 子节点


[*]获取子节点集合,包括元素节点、文本节点等



[*]只获取子节点集合中的元素节点
const children = document.getElementById("parent").childNodes;
for (let i = 0; i < children.length; i++) {
if (children.nodeType === 1) {
    console.log(children);
}
}或
const children = document.getElementById("parent").children;
console.log(children);
[*]第一个子节点
const first = document.getElementById("parent").firstChild;
console.log(first);第一个元素子节点

[*]推荐方法
const first = document.getElementById("parent").children;
console.log(first);
[*]存在兼容性问题,需要 IE9+
const first = document.getElementById("parent").firstElementChild;
console.log(first);

[*]最后一个子节点
const last = document.getElementById("parent").lastChild;
console.log(last);最后一个元素子节点

[*]推荐方法
const parent = document.getElementById("parent");
const last = parent.children;
console.log(last);
[*]存在兼容性问题,需要 IE9+
const last = document.getElementById("parent").lastElementChild;
console.log(last);

[*]举例:导航栏及其下拉菜单


[*]    Item 1



[*]Subitem 1


[*]Subitem 2   
   
[*]    Item 2



[*]Subitem 1


[*]Subitem 2   


d. 兄弟节点


[*]获取当前元素的下一个兄弟节点
Title

<p id="content">This is a paragraph.</p>

[*]元素节点
const p = document.querySelector("h1").nextElementSibling;
console.log(p);

[*]获取当前元素的上一个兄弟节点
Title

<p id="content">This is a paragraph.</p>

[*]元素节点
const h1 = document.querySelector("p").previousElementSibling;
console.log(h1);

[*]上述获取兄弟元素节点的方法,均存在兼容性问题,需要 IE9+,为解决此问题,可以封装以下方法:
function getNextElementSibling(element) {
let next = element.nextSibling;
while (next && next.nodeType !== 1) {
    next = next.nextSibling;
}
return next;
}

function getPreviousElementSibling(element) {
let prev = element.previousSibling;
while (prev && prev.nodeType !== 1) {
    prev = prev.previousSibling;
}
return prev;
}
e. 创建与添加节点


[*]动态创建元素节点:createElement()
const p = document.createElement("p");
[*]添加节点至指定父节点的子节点的末尾:appendChild()
p.innerText = "This is a paragraph"; // 设置标签内容
document.body.appendChild(p);               // 添加节点
[*]在指定元素前面插入元素:insertBefore()
const h1 = document.createElement("h1");
h1.innerText = "Title";
document.body.insertBefore(h1, p);
[*]举例:<textarea></textarea>
<button>发布</button>
<ul></ul>留言
<textarea></textarea>
<button>发布</button>
<ul></ul>
[*]直接将内容写入页面的文档流:write()

[*]write()、innerHTML()、createElement() 三种方法区别:

[*]write() 在当文档流执行完成后,会导致页面重绘
[*]innerHTML() 是将内容写入某个 DOM 节点,适合创建多个元素,结构稍复杂
[*]createElement() 结构清晰,效率较低

f. 删除节点


[*]删除一个节点:removeChild()
<p id="content">This is a paragraph.</p>删除节点
[*]举例 1:删除留言(在“<textarea></textarea>
<button>发布</button>
<ul></ul>留言”案例的基础上修改)
const btn = document.querySelector("button");btn.onclick = function () {const text = document.querySelector("textarea");if (text) {    const ul = document.querySelector("ul");    const li = document.createElement("li");    li.innerHTML = text.value + "删除";    ul.insertBefore(li, ul.firstChild);    const as = document.querySelectorAll("a");    for (let i = 0; i < as.length; i++) {

as.onclick = function () {

    // this.parentNode.remove();

    ul.removeChild(this.parentNode);

};    }} else {    alert("<textarea></textarea>
<button>发布</button>
<ul></ul>内容不能为空");}};
[*]举例 2:动态表格




姓名

年龄

操作       
g. 复制节点


[*]克隆一个节点:cloneNode()
<p id="content">This is a paragraph.</p>
[*]其中,cloneNode() 的参数默认为 false,即浅拷贝,不会拷贝子节点
0x03 事件高级

(1)注册事件

a. 简介


[*]注册事件又称绑定事件,给元素添加事件
[*]注册事件方式包括:

[*]传统方式

[*]以 on 为前缀的事件,如 onclick、onchange 等
[*]注册事件的唯一性,即同一元素同一事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的

[*]方法监听注册方式

[*]采用 W3C 标准
[*]使用 addEventListener() 监听
[*]IE9 之前可以使用 attachEvent() 代替
[*]同一元素同一事件可以注册多个监听器,并按注册顺序执行


b. addEventListener


[*]将指定的监视器注册到目标对象上,当该对象触发指定事件时,就会执行事件处理函数
[*]语法:addEventListener(type, listener[, useCapture])

[*]type:事件类型字符串,如 click、change 等
[*]listener:事件处理函数,即监听函数
[*]useCapture:(可选)是否在捕获阶段触发,是布尔值,默认 false
“事件捕获”在本章节第(3)节说明

<button><button><button><button>点击</button></button></button></button>
c. attachEvent


[*]将指定的监视器注册到目标对象上,当该对象触发指定事件时,就会执行指定的回调函数
[*]语法:attachEvent(eventNameWiteOn, callback)

[*]eventNameWithOn:事件类型字符串,如 onclick、onchange
[*]callback:回调函数,用于事件处理

d. 兼容性解决方案

兼容性处理原则:首先照顾大多数浏览器,再处理特殊浏览器
function addEventListener(element, eventName, callback) {
if (element.addEventListener) {
    element.addEventListener(eventName, eventName);
} else if (element.attachEvent) {
    element.attachEvent(eventName, callback);
} else {
    element["on" + eventName] = callback;
}
}(2)删除事件


[*]删除事件又称解绑事件
[*]删除事件方式包括:

[*]传统方式
<button><button><button><button>点击</button></button></button></button>
[*]方法监听删除方式

[*]使用 removeEventListener() 删除
<button><button><button><button>点击</button></button></button></button>
[*]IE9 之前可以使用 detachEvent() 代替


[*]兼容性解决方案
function removeEventListener(element, eventName, callback) {
if (element.removeEventListener) {
    element.removeEventListener(eventName, callback);
} else if (element.attachEvent) {
    element.detachEvent("on" + eventName, callback);
} else {
    element["on" + eventName] = null;
}
}
(3)DOM 事件流


[*]事件流描述的是从页面中接收事件的顺序
[*]DOM 事件流:事件发生时会在元素节点之间按照特定顺序的传播过程
[*]DOM 事件流分三个阶段:

[*]捕获阶段

[*]事件捕获:由 DOM 最顶层节点<button>开始</button>,逐级向下传播到最具体的元素接收的过程

[*]当前目标阶段
[*]冒泡阶段

[*]事件冒泡:事件<button>开始</button>时,由最具体的元素接收,之后逐级向上传播到 DOM 最顶层节点的过程


[*]举例:注册事件采取捕获阶段触发,先父元素节点,后子元素节点

[*]部分事件没有冒泡,如 onblur 等
(4)事件对象


[*]事件对象代表事件的状态,是事件一系列相关数据的集合,包括鼠标坐标等数据
[*]在以下代码中,形参 event 就是事件对象
<button><button><button><button>点击</button></button></button></button>
[*]IE6~8 使用 window.event 写法,兼容性写法为:
e = event || window.event;
[*]常见属性和方法
属性方法说明target返回触发事件的对象srcElement返回触发事件的对象(在 IE6~8 中使用)type返回事件类型,如 click 等stopPropagation()阻止冒泡cancelBubble阻止冒泡(在 IE6~8 中使用)preventDefault()阻止默认事件returnValue阻止默认事件(在 IE6~8 中使用)
[*]阻止事件冒泡的兼容性写法
if (e & e.stopPropagation) {
e.stopPropagation();
} else {
window.event.cancelBubble = true;
}
(5)事件委托


[*]事件委托又称事件代理,在 jQuery 中称为事件委派
[*]原理:将每个子节点的事件监听器统一设置在其父节点上,利用冒泡原理影响每个子节点
[*]作用:提高性能
[*]举例:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
(6)常用鼠标事件


[*]禁用右键菜单
document.addEventListener("contextmenu", function (e) {
e.preventDefault();
});
[*]禁止鼠标选中
document.addEventListener("selectstart", function (e) {
e.preventDefault();
});
[*]举例:跟随鼠标移动的方框

[*]mouseenter 与 mouseover 的区别在于:mouseenter 不会冒泡

[*]mouseenter 只在鼠标经过盒子自身时触发,而 mouseover 经过其子盒子也会触发

(7)常用键盘事件


[*]常用键盘事件
事件说明keyup按键松开时触发keydown按键按下时触发keypress按键按下时触发(区别大小写,不识别功能键,如 Ctrl 等)keyCode返回按键的 ASCII 值(区分大小写)
[*]按键执行顺序:
graph LRkeydown-->keypress-->keyup
[*]举例:按 / 键选中输入框

0x04 BOM

(1)简介


[*]浏览器对象模型(Browser Object Model)提供了独立于内容而与浏览器窗口进行交互的对象
[*]BOM 由一系列相关对象构成
[*]BOM 缺乏标准,最初是 Netscape 浏览器标准的一部分
[*]与 DOM 对比:
DOMBOM名称文档对象模型浏览器对象模型对象文档浏览器顶级对象documentwindow功能操作页面元素浏览器窗口交互标准W3C根据浏览器厂商
[*]BOM 构成:
graph TBwindow-->document & location & navigation & screen & history

[*]document:BOM 中包含 DOM
[*]window:是浏览器的顶级对象,既是 JS 访问浏览器窗口的接口,也是全局对象

[*]调用 window 对象方法时可以省略,如 alert(),除了 window.name


(2)window 对象常见事件


[*]窗口加载完成事件
window.onload = function () {};
// 或
window.addEventListener("load", function () {});

[*]DOM 加载完成事件(需要 IE9+)
window.addEventListener("DOMContentLoaded", function () {});

[*]窗口大小调整事件
window.onresize = function () {};
// 或
window.addEventListener("resize", function () {});
(3)定时器

a. timeout


[*]设置计时器

[*]语法:setTimeout(callback[, timeMS])
[*]作用:经过指定毫秒后执行回调函数

[*]清除定时器

[*]语法:clearTimeout(timer)
[*]作用:清除 setTimeout() 设置的定时器

[*]举例:
let timer = setTimeout(function() {}, 1000);
clearTimeout(timer);
b. interval


[*]设置计时器

[*]语法:setInterval(callback[, timeMS])
[*]作用:间隔指定毫秒后重复执行回调函数
[*]举例:倒计时器
00
00
00

[*]清除定时器

[*]语法:clearInterval(timer)
[*]作用:清除 setInterval() 设置的定时器

[*]举例:发送短信间隔
手机号: <input type="number" /><button>获取验证码</button>
(4)执行队列

a. 执行过程


[*]JavaScript 的特点是单线程,即同一时间只做一件事

[*]缺点:当 JS 执行时间过长,会导致页面渲染不连贯,产生阻塞的感受

[*]HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,即同步与异步

[*]同步:顺序依次执行
[*]异步:多任务同时执行

[*]同步任务都在主线程上执行,形成执行栈
[*]异步任务通过回调函数实现,分为以下类型:

[*]普通事件:如 click 等
[*]资源加载:如 load 等
[*]定时器
异步任务相关回调函数会被添加到任务队列(又称消息队列)中

b. 执行机制


[*]JavaScript 执行机制如下:
[*]先执行执行栈中的同步任务
[*]将异步任务放入任务队列
[*]完成执行栈后,按次序读取任务队列,将异步任务放入执行栈并执行

[*]由于主线程不断地重复获取任务、执行任务,因此该机制称为事件循环
(5)location 对象


[*]用于获取或设置窗体的 URL,并且可以用于解析 URL
[*]属性:
属性说明href获取或设置 URLhost返回主机(域名)port返回端口号pathname返回路径search返回参数hash返回片段

[*]举例:获取 URL 中携带的参数


[*]常用方法:
方法说明assign()重定向页面,与属性 href 类似,可以跳转页面replace()替换当前页面,替换后不能后退reload()重新加载页面,相当于刷新或 F5
参数为 true 表示强制刷新或 Ctrl+F5
(6)navigator 对象


[*]包含有关浏览器的信息
[*]举例:根据终端(浏览器)的不同跳转相应的页面
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|iPad|ios|Android|BlackBerry|IEMobile|Opera Mini|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
window.location.href = "https://m.example.com/";   // Mobile
} else {
window.location.href = "https://www.example.com/"; // PC
}
(7)history 对象


[*]用于与浏览器历史记录进行交互,包含用户(在浏览器窗口中)访问过的 URL
[*]方法:
方法说明back()后退forward()前进go(arg)参数为正数:前进 arg 个页面
参数为负数:后退 arg 个页面
[*]常见于 OA 办公系统
0x05 PC 端网页特效

(1)元素偏移量 offset

a. 简介


[*]动态获取元素的位置(偏移)、大小等

[*]获取元素距离带有定位父元素的位置
[*]获取元素自身的大小(宽高)
[*]获取的数值不携带单位

[*]常用属性:
属性说明offsetParent返回作为该元素带有定位的父级元素offsetTop返回元素相对带有定位父元素上方的偏移offsetLeft返回元素相对带有定位父元素左边框的偏移offsetWidth返回自身包括内边距、边框、内容的宽度offsetHeight返回自身包括内边距、边框、内容的高度
[*]相比之下,offset 更适合获取元素的大小与位置,而 style 更适合修改元素
b. 获取鼠标在盒子中的坐标

c. 拖动模态框


[*]HTML
<button><button><button><button>点击</button></button></button></button>登录登录框标题

关闭
[*]CSS
#mask {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.3);
display: none;
}
#card {
width: 400px;
height: 300px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
background-color: white;
border-radius: 30px;
box-shadow: 0 0 10px rgb(0, 0, 0);
text-align: center;
line-height: 40px;
display: none;
}
#header {
width: 100%;
margin-top: 0;
border-bottom: 2px solid rgba(0, 0, 0, 0.3);
cursor: move;
}
[*]JavaScript
const mask = document.querySelector("#mask");
const card = document.querySelector("#card");
const header = document.querySelector("#header");
document.querySelector("#open").addEventListener("click", () => {
mask.style.display = "block";
card.style.display = "block";
});
document.querySelector("#close").addEventListener("click", () => {
mask.style.display = "none";
card.style.display = "none";
});
header.addEventListener("mousedown", function (e) {
e.preventDefault();
let x = e.clientX - card.offsetLeft;
let y = e.clientY - card.offsetTop;
function move(e) {
    card.style.left = e.pageX - x + "px";
    card.style.top = e.pageY - y + "px";
}
document.addEventListener("mousemove", move);
document.addEventListener("mouseup", function (e) {
    document.removeEventListener("mousemove", move);
});
});
d. 图片放大镜


[*]HTML


    https://www.cnblogs.com/./image.jpg
[*]CSS
#image {
position: relative;
width: 200px;
height: 200px;
background-image: url("https://www.cnblogs.com/./image.jpg");
background-size: cover;
border: 1px solid black;
}
#mask {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background-color: red;
opacity: 0.5;
cursor: move;
display: none;
}
#preview {
position: absolute;
top: 0;
left: 210px;
width: 300px;
height: 300px;
overflow: hidden;
z-index: 10;
border: 1px solid black;
display: none;
}
#previewImg {
position: absolute;
top: 0;
left: 0;
}
[*]JavaScript
const image = document.querySelector("#image");
const mask = document.querySelector("#mask");
image.addEventListener("mouseover", () => {
mask.style.display = "block";
preview.style.display = "block";
});
image.addEventListener("mouseout", () => {
mask.style.display = "none";
preview.style.display = "none";
});
image.addEventListener("mousemove", function (e) {
let x = e.pageX - this.offsetLeft;
let y = e.pageY - this.offsetTop;
let maskX = x - mask.offsetWidth / 2;
let maskY = y - mask.offsetHeight / 2;
let maskMaxX = this.offsetWidth - mask.offsetWidth;
let maskMaxY = this.offsetHeight - mask.offsetHeight;
if (maskX < 0) {
    maskX = 0;
} else if (maskX > maskMaxX) {
    maskX = this.offsetWidth - mask.offsetWidth;
}
if (maskY < 0) {
    maskY = 0;
} else if (maskY > maskMaxY) {
    maskY = this.offsetHeight - mask.offsetHeight;
}
mask.style.left = maskX + "px";
mask.style.top = maskY + "px";

const preview = document.querySelector("#preview");
const previewImg = document.querySelector("#previewImg");
let previewMaxX = previewImg.offsetWidth - preview.offsetWidth;
let previewMaxY = previewImg.offsetHeight - preview.offsetHeight;
previewImg.style.left = -((maskX * previewMaxX) / maskMaxX) + "px";
previewImg.style.top = -((maskY * previewMaxY) / maskMaxY) + "px";
});
(2)元素可视区 client


[*]获取元素可视区相关信息,如边框大小、元素大小等
[*]常见属性:
属性说明clientTop返回元素上边框的大小clientLeft返回元素左边框的大小clientWidth返回自身包括内边距、内容的宽度clientHeight返回自身包括内边距、内容的高度
立即执行函数:(function() {})()
主要作用:创建一个独立的作用域
(3)元素滚动 scroll


[*]获取元素的大小、滚动距离等
[*]如果浏览器的高度(宽度)不足以显示全部内容,则会自动出现滚动条

[*]当滚动条向下(向右)滚动后,未显示在当前窗口的页面称为被卷去的页面
[*]滚动条在滚动时会触发 onscroll 事件

[*]常见属性:
属性说明scrollTop返回被卷去的上侧距离scrollLeft返回被卷去的左侧距离scrollWidth返回自身内容的宽度scrollHeight返回自身内容的高度
[*]被卷去的头部兼容性写法
function getScroll() {return {    left:

window.pageXOffset ||

document.documentElement.scrollLeft ||

document.body.scrollLeft ||

0,    top:

window.pageYOffset ||

document.documentElement.scrollTop ||

document.body.scrollTop ||

0,};}
[*]举例:侧边栏

[*]HTML
<header></header>


<button>回到顶部</button>
[*]CSS
header {
width: 90%;
height: 200px;
background-color: #ccc;
margin: 10px auto;
}
#content {
width: 90%;
height: 1000px;
background-color: #eee;
margin: 10px auto;
}
#bar {
position: absolute;
top: 300px;
right: 0;
width: 30px;
height: 150px;
background-color: #ddd;
}
button {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
[*]JavaScript
const bar = document.querySelector("#bar");
const btn = document.querySelector("button");
let ctnTop = document.querySelector("#content").offsetTop;
let barTop = bar.offsetTop - ctnTop;
document.addEventListener("scroll", () => {
if (window.scrollY > ctnTop) {
    bar.style.position = "fixed";
    bar.style.top = barTop + "px";
    btn.style.display = "block";
} else {
    bar.style.position = "absolute";
    bar.style.top = "300px";
    btn.style.display = "none";
}
});
btn.addEventListener("click", () => {
window.scrollTo({
    top: 0,
    behavior: "smooth",
});
});

(4)动画函数封装


[*]原理:通过定时器 setInterval() 不断移动盒子的位置

[*]盒子需要定位才能使用动画
<button>开始</button>
[*]动画函数的简单封装需要传递两个参数:动画对象、移动距离
function animate(obj, target) {clearInterval(obj.timer);obj.timer = setInterval(() => {    if (obj.offsetLeft >= target) {

clearInterval(obj.timer);    }    obj.style.left = obj.offsetLeft + 1 + "px";}, 25);}document.querySelector("button").addEventListener("click", () => {animate(document.querySelector("div"), 500);});
[*]缓动动画是让元素的运动速度发生变化(即,将移动距离递减)

[*]步长需要取整
[*]正步长向上取整,负步长向下取整
function animate(obj, target) {clearInterval(obj.timer);obj.timer = setInterval(() => {    if (obj.offsetLeft === target) {

clearInterval(obj.timer);    }    let step = (target - obj.offsetLeft) / 50;    step = step > 0 ? Math.ceil(step) : Math.floor(step);    obj.style.left = obj.offsetLeft + step + "px";}, 25);}
[*]在动画函数中引入回调函数
function animate(obj, target, callback) {clearInterval(obj.timer);obj.timer = setInterval(() => {    if (obj.offsetLeft === target) {

clearInterval(obj.timer);

if (callback) callback();    }    let step = (target - obj.offsetLeft) / 50;    step = step > 0 ? Math.ceil(step) : Math.floor(step);    obj.style.left = obj.offsetLeft + step + "px";}, 25);}document.querySelector("button").addEventListener("click", () => {animate(document.querySelector("div"), 500, () => {    alert("移动结束");});});
[*]将动画函数封装到单独的 JavaScript 文件中

[*]创建 animate.js
/** * 实现元素的平滑移动动画。 * @param {Object} obj - 需要进行动画的DOM对象。 * @param {number} target - 目标位置,即元素移动到的左偏移量。 * @param {Function} callback - 动画完成后的回调函数。 */function animate(obj, target, callback) {// 停止当前正在进行的动画clearInterval(obj.timer);// 设置定时器,每25毫秒执行一次动画逻辑obj.timer = setInterval(() => {    // 当元素移动到目标位置时,停止动画    if (obj.offsetLeft === target) {

clearInterval(obj.timer);

// 如果设置了回调函数,则动画完成后执行回调

if (callback) callback();    }    // 计算每次移动的距离,平滑移动    let step = (target - obj.offsetLeft) / 50;    // 确保移动方向正确,且移动步长为整数    step = step > 0 ? Math.ceil(step) : Math.floor(step);    // 更新元素的左偏移量    obj.style.left = obj.offsetLeft + step + "px";}, 25);}
[*]在页面中使用


0x06 本地存储


[*]本地存储特性:

[*]数据存储在用户浏览器中
[*]存储与读写方便
[*]容量大(sessionStorage - 5M,localStorage - 20M)
[*]只能存储字符串,可以将对象使用 JSON.stringify() 编码后存储

(1)sessionStorage


[*]当浏览器窗口关闭后,sessionStorage 生命周期终止
[*]在同一窗口(页面)下,数据可以共享
[*]以键值对的形式存储和使用
[*]举例:
<input type="text" />
<button id="save">存储</button>
<button id="read">读取</button>
<button id="delete">删除</button>
<button id="clear">清空</button>
(2)localStorage


[*]生命周期永久有效,只能手动删除
[*]在同一浏览器下,数据可以共享
[*]以键值对的形式存储和使用
[*]举例:
<input type="text" />
<button id="save">存储</button>
<button id="read">读取</button>
<button id="delete">删除</button>
<button id="clear">清空</button>
(3)记住用户名

<input type="text" id="username" />
<input type="checkbox" id="rememberMe" />
<label for="rememberMe">记住我</label>
来源:https://www.cnblogs.com/SRIGT/p/18134525
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Web APIs