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

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

  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是事件对象,作为监听函数的形参,可自定义命名(如event、evt、e等)
  2. 事件对象由系统自动创建,无需手动传入实参
  3. 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 等)。
    • 提供窗口控制(如打开、关闭、调整大小)、定时器、全局变量和函数等功能。
  • 常用方法 / 属性:

    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 // 访问元素
    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>
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
一隅论数智3 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
XiHongShi20163 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
爱吃苹果的日记本3 天前
离散数学第六课
学习·离散数学
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js