假期js学习汇总

三、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
  • 返回值:元素对象

常用属性:

  1. innerHTML:可读写,获取/修改元素内部的 HTML 代码(保留标签、空格和换行)
  2. innerText:可读写,获取/修改元素文本内容(自动去除 HTML 标签、空格和换行)
  3. 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 的事件,比如点击事件。事件由三个部分组成:

  1. 事件源:触发事件的对象
  2. 事件类型:如何触发(如鼠标点击、键盘按下等)
  3. 事件处理程序:通过函数赋值方式实现

执行事件的步骤

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采用函数赋值形式)
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.innerTextelement.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 改变元素其他属性

可操作 srchrefidalttitle 等属性。

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 操作表单元素属性

可操作 typevaluecheckedselecteddisabled 等属性。

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 排他思想

同一组元素中,实现单个元素特殊样式的算法:

  1. 清除所有元素的样式
  2. 给当前元素设置样式
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 操作自定义属性

获取属性值

  1. element.属性:获取元素自带属性
  2. element.getAttribute('属性'):获取自定义属性

设置属性值

  1. element.属性='值'
  2. 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、添加节点
  1. parentNode.appendChild(childNode)

    • 将节点添加到父节点子节点列表末尾
    • 类似数组的push()方法和CSS的::after伪元素
  2. 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、删除节点
  1. parentNode.removeChild(childNode)
  2. 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、其他创建节点方式
  1. element.innerHTML

    • 可解析HTML标签
    • 设置/获取元素内容
  2. element.innerText

    • 纯文本显示,不解析HTML标签
  3. 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>
  1. 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 注意事项
  1. event是事件对象,作为监听函数的形参,可自定义命名(如eventevte等)
  2. 事件对象由系统自动创建,无需手动传入实参
  3. IE低版本存在兼容性问题,可通过event = event || window.event解决(通常无需考虑)
3.6.4.3 常用属性
  • e.target:返回触发事件的对象
  • e.type:返回事件类型(如clickmouseover,不带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 对象(如 documenthistory 等)。
    • 提供窗口控制(如打开、关闭、调整大小)、定时器、全局变量和函数等功能。
  • 常用方法 / 属性

    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窗口加载事件
  1. window.onload=function(){}

    传统注册事件方式(只能注册一次,多次注册会覆盖前一个)

  2. 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、事件循环机制
  1. 主线程顺序执行同步任务
  2. 异步任务进入任务队列等待
  3. 主线程空闲时检查任务队列
  4. 将可执行任务加入主线程
  5. 循环往复
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指向总结

  1. 直接调用:指向window
  2. 对象方法:指向调用对象
  3. 构造函数:指向实例对象
  4. call/apply/bind:指向指定对象
  5. 事件回调:指向事件源
  6. 定时器:指向window

4.2、window对象的常见事件

4.2.1、onload窗口加载事件
  1. window.onload=function(){}

    传统注册事件方式(只能注册一次,多次注册会覆盖前一个)

  2. 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、事件循环机制
  1. 主线程顺序执行同步任务
  2. 异步任务进入任务队列等待
  3. 主线程空闲时检查任务队列
  4. 将可执行任务加入主线程
  5. 循环往复
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指向总结

  1. 直接调用:指向window
  2. 对象方法:指向调用对象
  3. 构造函数:指向实例对象
  4. call/apply/bind:指向指定对象
  5. 事件回调:指向事件源
  6. 定时器:指向window

4.5、location对象

4.5.1、location对象简介

window对象提供了location属性,用于获取或设置窗口的URL,并能解析URL。由于该属性返回一个对象,因此称为location对象。

4.5.2、URL详解

统一资源定位符(URL)是互联网上标准资源的地址,每个文件都有唯一的URL,指明文件位置及浏览器处理方式,俗称"网址"。

URL由三部分组成:

  1. 资源类型
  2. 主机域名
  3. 资源文件名

标准语法格式: protocol://hostname[:port]/path/[;parameters][?query]#fragment

URL组成部分说明:

  1. 协议(Scheme)

    • 定义通信协议类型
    • 常见协议:
      • http://(非加密)
      • https://(加密)
      • ftp://
      • mailto:
    • 示例:https://
  2. 域名/IP地址

    • 标识服务器位置
    • 示例:www.example.com
  3. 端口号(Port)

    • 可选,默认端口可省略
    • HTTP默认:80
    • HTTPS默认:443
    • 示例::8080
  4. 路径(Path)

    • 资源在服务器的具体位置
    • 示例:/blog/article1
  5. 查询参数(Query)

    • ?开头,多个参数用&分隔
    • 示例:?id=123&category=tech
  6. 锚点(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()持续改变元素位置

实现步骤:

  1. 获取元素当前位置
  2. 在当前位置基础上增加移动距离
  3. 使用定时器循环执行
  4. 设置停止条件
  5. 需要元素具有定位属性,通过修改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 优化动画函数 改进点:

  1. 为不同元素绑定独立定时器
  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()持续改变元素位置

实现步骤:

  1. 获取元素当前位置
  2. 在当前位置基础上增加移动距离
  3. 使用定时器循环执行
  4. 设置停止条件
  5. 需要元素具有定位属性,通过修改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 优化动画函数 改进点:

  1. 为不同元素绑定独立定时器
  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)特点
  1. 易于程序员阅读和编写
  2. 易于计算机解析和生成
  3. 本质上是JavaScript的子集,原生JavaScript支持JSON
(3)作用

JSON是一种与语言无关的数据交换格式:

  1. 用于前后端数据交互(Ajax)
  2. 用于移动端与服务端的数据交换
(4)语法规则

JSON语法简洁优雅,主要包含两种结构:

  1. 对象格式:{"key1":value1, "key2":value2, "key3":value3...}
  2. 数组格式:[value1, value2, value3...]

允许的数据类型:字符串、数值、布尔值、null、对象、数组(不包括NaN、undefined和方法)

JSON与JavaScript对象格式相似,区别在于JSON属性名必须使用双引号。

语法规则:

  1. 键值对使用冒号(":")分隔
  2. 多个键值对使用逗号(",")分隔
  3. 对象使用大括号("{}")包裹
  4. 数组使用方括号("[]")包裹
(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)是可扩展标记语言:

  1. 标记型语言:使用标签进行操作(类似HTML)
  2. 可扩展:标签可自定义(如<aa><猫>
  3. 主要功能是存储数据,而非显示数据
5.3.2.2 XML的应用
  1. 系统间数据传输格式
  2. 存储关系型数据
  3. 系统配置文件
  4. Android应用开发中的页面展示
5.3.3 JSON与XML比较

JSON常被拿来与XML比较,因其设计初衷部分是为了替代XML。相比XML,JSON的优势:

  1. 没有结束标签,长度更短,读写更快
  2. 能被JavaScript直接解析
  3. 原生支持数组

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)特点
  1. 易于程序员阅读和编写
  2. 易于计算机解析和生成
  3. 本质上是JavaScript的子集,原生JavaScript支持JSON
(3)作用

JSON是一种与语言无关的数据交换格式:

  1. 用于前后端数据交互(Ajax)
  2. 用于移动端与服务端的数据交换
(4)语法规则

JSON语法简洁优雅,主要包含两种结构:

  1. 对象格式:{"key1":value1, "key2":value2, "key3":value3...}
  2. 数组格式:[value1, value2, value3...]

允许的数据类型:字符串、数值、布尔值、null、对象、数组(不包括NaN、undefined和方法)

JSON与JavaScript对象格式相似,区别在于JSON属性名必须使用双引号。

语法规则:

  1. 键值对使用冒号(":")分隔
  2. 多个键值对使用逗号(",")分隔
  3. 对象使用大括号("{}")包裹
  4. 数组使用方括号("[]")包裹
(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)是可扩展标记语言:

  1. 标记型语言:使用标签进行操作(类似HTML)
  2. 可扩展:标签可自定义(如<aa><猫>
  3. 主要功能是存储数据,而非显示数据
5.3.2.2 XML的应用
  1. 系统间数据传输格式
  2. 存储关系型数据
  3. 系统配置文件
  4. Android应用开发中的页面展示
5.3.3 JSON与XML比较

JSON常被拿来与XML比较,因其设计初衷部分是为了替代XML。相比XML,JSON的优势:

  1. 没有结束标签,长度更短,读写更快
  2. 能被JavaScript直接解析
  3. 原生支持数组

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>
相关推荐
SuperEugene1 小时前
日期与时间处理:不用库和用 dayjs 的两种思路
前端·javascript
寒秋花开曾相惜2 小时前
(学习笔记)2.2 整数表示(2.2.6 扩展一个数字的位表示)
c语言·开发语言·笔记·学习
别退2 小时前
brain
科技·学习
宇木灵2 小时前
C语言基础-八、结构体和共同(用)体
c语言·开发语言·数据结构·笔记·学习·算法
菜鸟小芯2 小时前
【GLM-5 陪练式前端新手入门】第一篇:从 GLM-5 提示到实践,完成前端入门第一步
前端·人工智能
木斯佳2 小时前
前端八股文面经大全:字节跳动交易与广告前端一面(2026-2-10)·面经深度解析
前端
Highcharts.js2 小时前
如何根据派生数据创建钟形曲线图表?highcharts正态分布曲线使用指南:从创建到设置一文搞定
开发语言·javascript·开发文档·正态分布·highcharts·图表类型·钟形图
宇木灵2 小时前
C语言基础-九、动态内存分配
c语言·开发语言·学习·算法
a1117763 小时前
纸张生成器(html开源)
前端·开源·html