本文发表于 842 天前,其中的信息可能已经事过境迁
文章摘要
加载中...|
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结 投诉

Ⅰ、DOM

一、DOM操作

1.根据css选择器来获取DOM元素

选择匹配的第一个元素

html
//document.querySelector('css选择器')
<body>
  <div class="box"></div>
  <script>
    const box = document.querySelector(".box"); //css选择器匹配的第一个元素,返回值为一个HTMLElement对象
    //或const box = document.querySelector('div')
    box.style.color = "blue"; //可以直接做修改
    console.log(box);
  </script>
</body>

选择匹配的多个元素

html
document.querySelectorAll('css选择器')
<body>
  <ul>
    <li>测试1</li>
    <li>测试2</li>
    <li>测试3</li>
  </ul>
  <script>
    const lis = document.querySelectorAll("ul li"); //返回值为NodeList对象集合
    //不能直接做修改,只能通过遍历的方式一次给里面的元素做修改
    console.log(lis);
  </script>
</body>

document.querySelectorAll('css选择器')得到的是一个伪数组

  • 有长度有索引号的数组
  • 但是没有pop() push()等数组方法

想要得到里面的每一个对象,则需要遍历(for)的方式获得

2.其他获取DOM元素的方法

js
//根据id获取一个元素
document.getElementById("nav"); //id选择
//根据类名获取元素 获取页面 所有类名为 w 的元素
document.getElementsByClassName("w"); //类选择
//根据标签获取一类元素 获取页面中所有div
document.getElementsByTagName("div"); //标签选择

3.操作元素内容

对象.innerText 属性

html
<body>
  <div class="box">我是文字内容</div>
  <script>
    const box = document.querySelector(".box");
    box.innerText = "我是一个盒子";
  </script>
</body>
  • 将文本内容添加/更新到任意标签位置
  • 显示纯文本,不解析标签

对象.innerHTML 属性

html
<body>
  <div class="box">我是文字内容</div>
  <script>
    const box = document.querySelector(".box");
    box.innerHTML = "<strong>我是一个盒子</strong>";
  </script>
</body>
  • 将文本内容添加/更新到任意标签位置
  • 会解析标签,多标签建议使用模板字符

4.操作元素属性

html
<body>
  <div class="box"></div>
  <script>
    const box = document.querySelector(".box");
    box.属性 = "新的属性";
  </script>
</body>

5.操作元素样式属性

html
对象.style.样式属性 = '值'
<head>
  <style>
    .box {
      width: 200px;
      height: 200px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box"></div>
  <script>
    const box = document.querySelector('.box')
    box.style.width = '300px'
          box.style.backgroundColor = 'hotpink'//属性中多组单词的,采用驼峰命名法可以有效解决
          box.style.border = '2px solid blue'//可以给对象添加属性
          //修改样式较少的情况下有优势   生成的是行内样式表,权重比较高
          document.body.style.backgroundImage = `改变属性${}`
          //body不需要获取,可以直接调用document.body来进行操作
  </script>
</body>

6.通过classList修改样式

html
<head>
  <style>
    .active {
      width: 200px;
      height: 200px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box"></div>
  <script>
    const box = document.querySelector(".box");
    box.classList.add("active"); //追加类 add()  类名不加点,并且是字符串
    box.classList.remove("box"); //移除类 remove() 类名不加点,并且是字符串
    box.classList.toggle("active"); //切换类 toggle() 有就删掉,没有就加上,开关
    //classList是追加和删除  不影响以前的类名
  </script>
</body>

7.操作表单元素属性

html
<body>
  <input type="checkbox" value="电脑" />
  <script>
    const ipt = document.querySelector("input");
    console.log(ipt.checked); // false 布尔值 不选中为false
    ipt.checked = true;
  </script>
</body>

8.自定义属性

html
<div data-id="5">1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<script>
  const one = document.querySelector("div");
  console.log(one.dataset); //DOMStringMap {id: '5'}  id : "5"
  console.log(one.dataset.id); //5
</script>

9.定时器 - 间歇函数

1.开启定时器

js
//setInterval(函数,间隔时间)  间隔时间单位为毫秒
setInterval(function () {
  console.log("一秒执行一次");
}, 1000);

function fn() {
  console.log("一秒执行一次");
}
setInterval(fn, 1000); //有名函数第一个参数写函数名,不需要加小括号

每个定时器都会有自己的编号

2.关闭定时器

js
let 变量名 = setInterval(函数,间隔时间)
clearInterval(变量名)

一般不会刚创建就停止,而是满足一定条件再停止

二、DOM事件

1.事件监听

就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为绑定事件或者注册事件

2.addEventListener与on区别

为某元素设定事件触发函数时,

addEventListener除了可以设置元素触发顺序外,还能多次绑定事件

on 不能多次绑定,否则的话会出现覆盖。即后绑定的on方法覆盖之前绑定的on方法,导致之前绑定的on方法失效

3.事件

鼠标事件焦点事件键盘事件文本事件
鼠标触发表单获得光标键盘触发表单输入触发
click 鼠标点击focus 获得焦点keydown 键盘按下触发input 用户输入事件
mouseenter 鼠标经过blus 失去焦点keyup 键盘抬起触发
mouseleave 鼠标离开
js
//鼠标事件
document.querySelector(".class").addEventListener("click", function () {
  console.log("鼠标点击");
});
document.querySelector(".class").addEventListener("click", function () {
  console.log("鼠标经过");
});
document.querySelector(".class").addEventListener("click", function () {
  console.log("鼠标离开");
});
js
//焦点事件
document.querySelector(".class").addEventListener("focus", function () {
  console.log("获得焦点");
});
document.querySelector(".class").addEventListener("blur", function () {
  console.log("失去焦点");
});

案例:小米搜索框

html
<div class="mi">
  <input type="search" placeholder="小米笔记本" />
  <ul class="result-list">
    <li><a href="#">全部商品</a></li>
    <li><a href="#">小米11</a></li>
    <li><a href="#">小米10S</a></li>
    <li><a href="#">小米笔记本</a></li>
    <li><a href="#">小米手机</a></li>
    <li><a href="#">黑鲨4</a></li>
    <li><a href="#">空调</a></li>
  </ul>
</div>
<script>
  // 1. 获取元素
  const input = document.querySelector("[type*=search]"); //css属性选择器
  const ul = document.querySelector(".result-list");
  // console.log(input)
  // 2. 监听事件 获得焦点
  input.addEventListener("focus", function () {
    // ul显示
    ul.style.display = "block";
    // 添加一个带有颜色边框的类名
    input.classList.add("search");
  });
  // 3. 监听事件 失去焦点
  input.addEventListener("blur", function () {
    ul.style.display = "none";
    input.classList.remove("search");
  });
</script>
js
const input = document.querySelector("input");
//键盘事件
input.addEventListener("keydown", function () {
  console.log("键盘按下了");
});
input.addEventListener("keyup", function () {
  console.log("键盘弹起了");
});
//用户输入文本事件  input
input.addEventListener("input", function () {
  console.log(input.value);
});

4.事件对象及其位置

事件对象也是一个对象,在事件绑定的回调函数的第一个参数就是事件对象

事件对象中有很多属性

js
const input = document.querySelector("input");
input.addEventListener("keyup", function (e) {
  if (e.key === "Enter") {
    //key就是事件对象的一个属性,表示事件的按键输入为回车
    console.log("我按下了回车键");
  }
});

5事件对象中的常用属性

属性描述
type获取当前的事件类型
clientX/clientY获取光标相对于浏览器可见窗口左上角的位置
offsetX/offsetY获取光标相对于当前DOM元素左上角的位置
key用户按下的键盘键的值 现在不提倡使用keyCode

6.trim()去除字符串左右的空格

html
<textarea name="" id="" cols="30" rows="10"></textarea>
<script>
  const str = "          im a teacher  ";
  // console.log(str.trim())  // 去除字符串左右的空格
  const tx = document.querySelector("textarea");
  tx.addEventListener("keyup", function (e) {
    // console.log(tx.value)
    if (e.key === "Enter") {
      // console.log(tx.value)
      console.log(tx.value.trim() === "");
    }
  });
</script>

7.环境对象

环境对象this,谁调用,this就是谁

html
<button>点击</button>
<script>
  // 每个函数里面都有this 环境对象  普通函数里面this指向的是window
  // function fn() {
  //   console.log(this)
  // }
  // window.fn()
  const btn = document.querySelector("button");
  btn.addEventListener("click", function () {
    // console.log(this)  // btn 对象
    // btn.style.color = 'red'
    this.style.color = "red";
  });
</script>

8.回调函数

js
// 调用定时器,匿名函数做为参数
setInterval(function () {
  console.log("我是回调函数...");
}, 1000);

结论:

  1. 回调函数本质还是函数,只不过把它当成参数使用
  2. 使用匿名函数做为回调函数比较常见

9.捕获和冒泡

html
<body>
  <h3>事件流</h3>
  <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
  <div class="outer">
    <div class="inner">
      <div class="child"></div>
    </div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector(".outer");
    const inner = document.querySelector(".inner");
    const child = document.querySelector(".child");

    // html 元素添加事件
    document.documentElement.addEventListener("click", function () {
      console.log("html...");
    });

    // body 元素添加事件
    document.body.addEventListener("click", function () {
      console.log("body...");
    });

    // 外层的盒子添加事件
    outer.addEventListener("click", function () {
      console.log("outer...");
    });

    // 中间的盒子添加事件
    outer.addEventListener("click", function () {
      console.log("inner...");
    });

    // 内层的盒子添加事件
    outer.addEventListener("click", function () {
      console.log("child...");
    });
  </script>
</body>

执行上述代码后发现,当单击事件触发时,其祖先元素的单击事件也【相继触发】,这是为什么呢?

结合事件流的特征,我们知道当某个元素的事件被触发时,事件总是会先经过其祖先才能到达当前元素,然后再由当前元素向祖先传递,事件在流动的过程中遇到相同的事件便会被触发。

再来关注一个细节就是事件相继触发的【执行顺序】,事件的执行顺序是可控制的,即可以在捕获阶段被执行,也可以在冒泡阶段被执行。

如果事件是在冒泡阶段执行的,我们称为冒泡模式,它会先执行子盒子事件再去执行父盒子事件,默认是冒泡模式。

如果事件是在捕获阶段执行的,我们称为捕获模式,它会先执行父盒子事件再去执行子盒子事件。

html
<body>
  <h3>事件流</h3>
  <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
  <div class="outer">
    <div class="inner"></div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector(".outer");
    const inner = document.querySelector(".inner");

    // 外层的盒子
    outer.addEventListener(
      "click",
      function () {
        console.log("outer...");
      },
      true,
    ); // true 表示在捕获阶段执行事件

    // 中间的盒子
    outer.addEventListener(
      "click",
      function () {
        console.log("inner...");
      },
      true,
    );
  </script>
</body>

结论:

  1. addEventListener 第3个参数决定了事件是在捕获阶段触发还是在冒泡阶段触发
  2. addEventListener 第3个参数为 true 表示捕获阶段触发,false 表示冒泡阶段触发,默认值为 false
  3. 事件流只会在父子元素具有相同事件类型时才会产生影响
  4. 绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获)

10.阻止冒泡

阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。

html
<body>
  <h3>阻止冒泡</h3>
  <p>阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。</p>
  <div class="outer">
    <div class="inner">
      <div class="child"></div>
    </div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector(".outer");
    const inner = document.querySelector(".inner");
    const child = document.querySelector(".child");

    // 外层的盒子
    outer.addEventListener("click", function () {
      console.log("outer...");
    });

    // 中间的盒子
    inner.addEventListener("click", function (ev) {
      console.log("inner...");

      // 阻止事件冒泡
      ev.stopPropagation();
    });

    // 内层的盒子
    child.addEventListener("click", function (ev) {
      console.log("child...");

      // 借助事件对象,阻止事件向上冒泡
      ev.stopPropagation();
    });
  </script>
</body>

结论:事件对象中的 ev.stopPropagation 方法,专门用来阻止事件冒泡。

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

mouseenter 和 mouseleave 没有冒泡效果 (推荐)

三、事件委托

事件委托是利用事件流的特征解决一些现实开发需求的知识技巧,主要的作用是提升程序效率。

大量的事件监听是比较耗费性能的,如下代码所示

html
<script>
  // 假设页面中有 10000 个 button 元素
  const buttons = document.querySelectorAll("table button");

  for (let i = 0; i <= buttons.length; i++) {
    // 为 10000 个 button 元素添加了事件
    buttons.addEventListener("click", function () {
      // 省略具体执行逻辑...
    });
  }
</script>

利用事件流的特征,可以对上述的代码进行优化,事件的的冒泡模式总是会将事件流向其父元素的,如果父元素监听了相同的事件类型,那么父元素的事件就会被触发并执行,正是利用这一特征对上述代码进行优化,如下代码所示:

html
<script>
  // 假设页面中有 10000 个 button 元素
  let buttons = document.querySelectorAll("table button");

  // 假设上述的 10000 个 buttom 元素共同的祖先元素是 table
  let parents = document.querySelector("table");
  parents.addEventListener("click", function () {
    console.log("点击任意子元素都会触发事件...");
  });
</script>

我们的最终目的是保证只有点击 button 子元素才去执行事件的回调函数,如何判断用户点击是哪一个子元素呢?

事件对象中的属性 targetsrcElement属性表示真正触发事件的元素,它是一个元素类型的节点。

html
<script>
  // 假设页面中有 10000 个 button 元素
  const buttons = document.querySelectorAll("table button");

  // 假设上述的 10000 个 buttom 元素共同的祖先元素是 table
  const parents = document.querySelector("table");
  parents.addEventListener("click", function (ev) {
    // console.log(ev.target);
    // 只有 button 元素才会真正去执行逻辑
    if (ev.target.tagName === "BUTTON") {
      // 执行的逻辑
    }
  });
</script>

四、其他事件

1.页面加载事件

加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件

有些时候需要等页面资源全部处理完了做一些事情

事件名:load

监听页面所有资源加载完毕:

javascript
window.addEventListener("load", function () {
  // xxxxx
});

2.元素滚动事件

滚动条在滚动的时候持续触发的事件

javascript
window.addEventListener("scroll", function () {
  // xxxxx
});

3.页面尺寸事件

会在窗口尺寸改变的时候触发事件:

javascript
window.addEventListener("resize", function () {
  // xxxxx
});

五、日期对象

掌握 Date 日期对象的使用,动态获取当前计算机的时间。

ECMAScript 中内置了获取系统时间的对象 Date,使用 Date 时与之前学习的内置对象 console 和 Math 不同,它需要借助 new 关键字才能使用。

1.实例化

javascript
// 1. 实例化
// const date = new Date(); // 系统默认时间
const date = new Date("2020-05-01"); // 指定时间
// date 变量即所谓的时间对象

console.log(typeof date);

2.方法

javascript
// 1. 实例化
const date = new Date();
// 2. 调用时间对象方法
// 通过方法分别获取年、月、日,时、分、秒
const year = date.getFullYear(); // 四位年份
const month = date.getMonth(); // 0 ~ 11

getFullYear 获取四位年份

getMonth 获取月份,取值为 0 ~ 11

getDate 获取月份中的每一天,不同月份取值也不相同

getDay 获取星期,取值为 0 ~ 6

getHours 获取小时,取值为 0 ~ 23

getMinutes 获取分钟,取值为 0 ~ 59

getSeconds 获取秒,取值为 0 ~ 59

3.时间戳

时间戳是指1970年01月01日00时00分00秒起至现在的总秒数或毫秒数,它是一种特殊的计量时间的方式。

注:ECMAScript 中时间戳是以毫秒计的。

javascript
// 1. 实例化
const date = new Date();
// 2. 获取时间戳
console.log(date.getTime());
// 还有一种获取时间戳的方法
console.log(+new Date());
// 还有一种获取时间戳的方法
console.log(Date.now());

获取时间戳的方法,分别为 getTime 和 Date.now 和 +new Date()

六、DOM 节点

掌握元素节点创建、复制、插入、删除等操作的方法,能够依据元素节点的结构关系查找节点

回顾之前 DOM 的操作都是针对元素节点的属性或文本的,除此之外也有专门针对元素节点本身的操作,如插入、复制、删除、替换等。

1.插入节点

在已有的 DOM 节点中插入新的 DOM 节点时,需要关注两个关键因素:首先要得到新的 DOM 节点,其次在哪个位置插入这个节点。

如下代码演示:

html
<body>
  <h3>插入节点</h3>
  <p>在现有 dom 结构基础上插入新的元素节点</p>
  <hr />
  <!-- 普通盒子 -->
  <div class="box"></div>
  <!-- 点击按钮向 box 盒子插入节点 -->
  <button class="btn">插入节点</button>
  <script>
    // 点击按钮,在网页中插入节点
    const btn = document.querySelector(".btn");
    btn.addEventListener("click", function () {
      // 1. 获得一个 DOM 元素节点
      const p = document.createElement("p");
      p.innerText = "创建的新的p标签";
      p.className = "info";

      // 复制原有的 DOM 节点
      const p2 = document.querySelector("p").cloneNode(true);
      p2.style.color = "red";

      // 2. 插入盒子 box 盒子
      document.querySelector(".box").appendChild(p);
      document.querySelector(".box").appendChild(p2);
    });
  </script>
</body>

结论:

  • createElement 动态创建任意 DOM 节点

  • cloneNode 复制现有的 DOM 节点,传入参数 true 会复制所有子节点

  • appendChild 在末尾(结束标签前)插入节点

再来看另一种情形的代码演示:

html
<body>
  <h3>插入节点</h3>
  <p>在现有 dom 结构基础上插入新的元素节点</p>
  <hr />
  <button class="btn1">在任意节点前插入</button>
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>JavaScript</li>
  </ul>
  <script>
    // 点击按钮,在已有 DOM 中插入新节点
    const btn1 = document.querySelector(".btn1");
    btn1.addEventListener("click", function () {
      // 第 2 个 li 元素
      const relative = document.querySelector("li:nth-child(2)");

      // 1. 动态创建新的节点
      const li1 = document.createElement("li");
      li1.style.color = "red";
      li1.innerText = "Web APIs";

      // 复制现有的节点
      const li2 = document.querySelector("li:first-child").cloneNode(true);
      li2.style.color = "blue";

      // 2. 在 relative 节点前插入
      document.querySelector("ul").insertBefore(li1, relative);
      document.querySelector("ul").insertBefore(li2, relative);
    });
  </script>
</body>

结论:

  • createElement 动态创建任意 DOM 节点

  • cloneNode 复制现有的 DOM 节点,传入参数 true 会复制所有子节点

  • insertBefore 在父节点中任意子节点之前插入新节点

2.删除节点

删除现有的 DOM 节点,也需要关注两个因素:首先由父节点删除子节点,其次是要删除哪个子节点。

html
<body>
  <!-- 点击按钮删除节点 -->
  <button>删除节点</button>
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>Web APIs</li>
  </ul>

  <script>
    const btn = document.querySelector("button");
    btn.addEventListener("click", function () {
      // 获取 ul 父节点
      let ul = document.querySelector("ul");
      // 待删除的子节点
      let lis = document.querySelectorAll("li");

      // 删除节点
      ul.removeChild(lis[0]);
    });
  </script>
</body>

结论:removeChild 删除节点时一定是由父子关系。

3.查找节点

DOM 树中的任意节点都不是孤立存在的,它们要么是父子关系,要么是兄弟关系,不仅如此,我们可以依据节点之间的关系查找节点。

1.父子关系

html
<body>
  <button class="btn1">所有的子节点</button>
  <!-- 获取 ul 的子节点 -->
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>JavaScript 基础</li>
    <li>Web APIs</li>
  </ul>
  <script>
    const btn1 = document.querySelector(".btn1");
    btn1.addEventListener("click", function () {
      // 父节点
      const ul = document.querySelector("ul");

      // 所有的子节点
      console.log(ul.childNodes);
      // 只包含元素子节点
      console.log(ul.children);
    });
  </script>
</body>

结论:

  • childNodes 获取全部的子节点,回车换行会被认为是空白文本节点
  • children 只获取元素类型节点
html
<body>
  <table>
    <tr>
      <td width="60">序号</td>
      <td>课程名</td>
      <td>难度</td>
      <td width="80">操作</td>
    </tr>
    <tr>
      <td>1</td>
      <td><span>HTML</span></td>
      <td>初级</td>
      <td><button>变色</button></td>
    </tr>
    <tr>
      <td>2</td>
      <td><span>CSS</span></td>
      <td>初级</td>
      <td><button>变色</button></td>
    </tr>
    <tr>
      <td>3</td>
      <td><span>Web APIs</span></td>
      <td>中级</td>
      <td><button>变色</button></td>
    </tr>
  </table>
  <script>
    // 获取所有 button 节点,并添加事件监听
    const buttons = document.querySelectorAll("table button");
    for (let i = 0; i < buttons.length; i++) {
      buttons[i].addEventListener("click", function () {
        // console.log(this.parentNode); // 父节点 td
        // console.log(this.parentNode.parentNode); // 爷爷节点 tr
        this.parentNode.parentNode.style.color = "red";
      });
    }
  </script>
</body>

结论:parentNode 获取父节点,以相对位置查找节点,实际应用中非常灵活。

2.兄弟关系

html
<body>
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>JavaScript 基础</li>
    <li>Web APIs</li>
  </ul>
  <script>
    // 获取所有 li 节点
    const lis = document.querySelectorAll("ul li");

    // 对所有的 li 节点添加事件监听
    for (let i = 0; i < lis.length; i++) {
      lis[i].addEventListener("click", function () {
        // 前一个节点
        console.log(this.previousSibling);
        // 下一下节点
        console.log(this.nextSibling);
      });
    }
  </script>
</body>

结论:

  • previousSibling 获取前一个节点,以相对位置查找节点,实际应用中非常灵活。
  • nextSibling 获取后一个节点,以相对位置查找节点,实际应用中非常灵活。

Ⅱ、BOM

一、window对象

BOM (Browser Object Model ) 是浏览器对象模型

  • window对象是一个全局对象,也可以说是JavaScript中的顶级对象
  • 像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的
  • 所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
  • window对象下的属性和方法调用的时候可以省略window

二、定时器-延迟函数

JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout

语法:

JavaScript
setTimeout(回调函数, 延迟时间)

setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window

间歇函数 setInterval : 每隔一段时间就执行一次, , 平时省略window

清除延时函数:

JavaScript
clearTimeout(timerId)

注意点

  1. 延时函数需要等待,所以后面的代码先执行
  2. 返回值是一个正整数,表示定时器的编号
html
<body>
  <script>
    // 定时器之延迟函数

    // 1. 开启延迟函数
    let timerId = setTimeout(function () {
      console.log("我只执行一次");
    }, 3000);

    // 1.1 延迟函数返回的还是一个正整数数字,表示延迟函数的编号
    console.log(timerId);

    // 1.2 延迟函数需要等待时间,所以下面的代码优先执行

    // 2. 关闭延迟函数
    clearTimeout(timerId);
  </script>
</body>

三、location对象

location (地址) 它拆分并保存了 URL 地址的各个组成部分, 它是一个对象

属性/方法说明
href属性,获取完整的 URL 地址,赋值时用于地址的跳转
search属性,获取地址中携带的参数,符号 ?后面部分
hash属性,获取地址中的啥希值,符号 # 后面部分
reload()方法,用来刷新当前页面,传入参数 true 时表示强制刷新
html
<body>
  <form><input type="text" name="search" /> <button>搜索</button></form>
  <a href="#/music">音乐</a>
  <a href="#/download">下载</a>

  <button class="reload">刷新页面</button>
  <script>
    // location 对象
    // 1. href属性 (重点) 得到完整地址,赋值则是跳转到新地址
    console.log(location.href);
    // location.href = 'http://www.itcast.cn'

    // 2. search属性  得到 ? 后面的地址
    console.log(location.search); // ?search=笔记本

    // 3. hash属性  得到 # 后面的地址
    console.log(location.hash);

    // 4. reload 方法  刷新页面
    const btn = document.querySelector(".reload");
    btn.addEventListener("click", function () {
      // location.reload() // 页面刷新
      location.reload(true); // 强制页面刷新 ctrl+f5
    });
  </script>
</body>

四、navigator对象

navigator是对象,该对象下记录了浏览器自身的相关信息

常用属性和方法:

  • 通过 userAgent 检测浏览器的版本及平台
javascript
// 检测 userAgent(浏览器信息)
(function () {
  const userAgent = navigator.userAgent;
  // 验证是否为Android或iPhone
  const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/);
  const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/);
  // 如果是Android或iPhone,则跳转至移动站点
  if (android || iphone) {
    location.href = "http://m.itcast.cn";
  }
})();

五、histroy对象

history (历史)是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退等

使用场景

history对象一般在实际开发中比较少用,但是会在一些OA 办公系统中见到。

![67604783479](D:/web前端/资料/web/web APIs第五天/04-笔记/assets/1676047834796.png)

常见方法:

html
<body>
  <button class="back">←后退</button>
  <button class="forward">前进→</button>
  <script>
    // histroy对象

    // 1.前进
    const forward = document.querySelector(".forward");
    forward.addEventListener("click", function () {
      // history.forward()
      history.go(1);
    });
    // 2.后退
    const back = document.querySelector(".back");
    back.addEventListener("click", function () {
      // history.back()
      history.go(-1);
    });
  </script>
</body>

六、本地存储(重点)

本地存储:将数据存储在本地浏览器中

常见的使用场景:

https://todomvc.com/examples/vanilla-es6/ 页面刷新数据不丢失

好处:

1、页面刷新或者关闭不丢失数据,实现数据持久化

2、容量较大,sessionStorage和 localStorage 约 5M 左右

1.localStorage(重点)

作用: 数据可以长期保留在本地浏览器中,刷新页面和关闭页面,数据也不会丢失

**特性:**以键值对的形式存储,并且存储的是字符串, 省略了window

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>本地存储-localstorage</title>
  </head>

  <body>
    <script>
      // 本地存储 - localstorage 存储的是字符串
      // 1. 存储
      localStorage.setItem("age", 18);

      // 2. 获取
      console.log(typeof localStorage.getItem("age"));

      // 3. 删除
      localStorage.removeItem("age");
    </script>
  </body>
</html>

2.sessionStorage(了解)

特性:

  • 用法跟localStorage基本相同
  • 区别是:当页面浏览器被关闭时,存储在 sessionStorage 的数据会被清除

存储:sessionStorage.setItem(key,value)

获取:sessionStorage.getItem(key)

删除:sessionStorage.removeItem(key)

3.localStorage 存储复杂数据类型

**问题:**本地只能存储字符串,无法存储复杂数据类型.

**解决:**需要将复杂数据类型转换成 JSON字符串,在存储到本地

**语法:**JSON.stringify(复杂数据类型)

JSON字符串:

  • 首先是1个字符串
  • 属性名使用双引号引起来,不能单引号
  • 属性值如果是字符串型也必须双引号
html
<body>
  <script>
    // 本地存储复杂数据类型
    const goods = {
      name: "小米",
      price: 1999,
    };
    // localStorage.setItem('goods', goods)
    // console.log(localStorage.getItem('goods'))

    // 1. 把对象转换为JSON字符串  JSON.stringify
    localStorage.setItem("goods", JSON.stringify(goods));
    // console.log(typeof localStorage.getItem('goods'))
  </script>
</body>

**问题:**因为本地存储里面取出来的是字符串,不是对象,无法直接使用

**解决:**把取出来的字符串转换为对象

**语法:**JSON.parse(JSON字符串)

html
<body>
  <script>
    // 本地存储复杂数据类型
    const goods = {
      name: "小米",
      price: 1999,
    };
    // localStorage.setItem('goods', goods)
    // console.log(localStorage.getItem('goods'))

    // 1. 把对象转换为JSON字符串  JSON.stringify
    localStorage.setItem("goods", JSON.stringify(goods));
    // console.log(typeof localStorage.getItem('goods'))

    // 2. 把JSON字符串转换为对象  JSON.parse
    console.log(JSON.parse(localStorage.getItem("goods")));
  </script>
</body>

七、综合案例

1.数组map 方法

使用场景:

map 可以遍历数组处理数据,并且返回新的数组

语法:

javascript
<body>
  <script>
  const arr = ['red', 'blue', 'pink']
  // 1. 数组 map方法 处理数据并且 返回一个数组
   const newArr = arr.map(function (ele, index) {
    // console.log(ele)  // 数组元素
    // console.log(index) // 索引号
    return ele + '颜色'
 })
console.log(newArr)
</script>
</body>

map 也称为映射。映射是个术语,指两个元素的集之间元素相互“对应”的关系。

map重点在于有返回值,forEach没有返回值(undefined)

2.数组join方法

**作用:**join() 方法用于把数组中的所有元素转换一个字符串

语法:

html
<body>
  <script>
    const arr = ["red", "blue", "pink"];

    // 1. 数组 map方法 处理数据并且 返回一个数组
    const newArr = arr.map(function (ele, index) {
      // console.log(ele)  // 数组元素
      // console.log(index) // 索引号
      return ele + "颜色";
    });
    console.log(newArr);

    // 2. 数组join方法  把数组转换为字符串
    // 小括号为空则逗号分割
    console.log(newArr.join()); // red颜色,blue颜色,pink颜色
    // 小括号是空字符串,则元素之间没有分隔符
    console.log(newArr.join("")); //red颜色blue颜色pink颜色
    console.log(newArr.join("|")); //red颜色|blue颜色|pink颜色
  </script>
</body>

Ⅲ、正则表达式

正则表达式(Regular Expression)是一种字符串匹配的模式(规则)

使用场景:

  • 例如验证表单:手机号表单要求用户只能输入11位的数字 (匹配)
  • 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等

一、正则基本使用

  1. 定义规则

    JavaScript
    const reg =  /表达式/
    • 其中/ /是正则表达式字面量
    • 正则表达式也是对象
  2. 使用正则

    • test()方法 用来查看正则表达式与指定的字符串是否匹配
    • 如果正则表达式与指定的字符串匹配 ,返回true,否则false
html
<body>
  <script>
    // 正则表达式的基本使用
    const str = "web前端开发";
    // 1. 定义规则
    const reg = /web/;

    // 2. 使用正则  test()
    console.log(reg.test(str)); // true  如果符合规则匹配上则返回true
    console.log(reg.test("java开发")); // false  如果不符合规则匹配上则返回 false
  </script>
</body>

二、元字符

  1. 普通字符:
  • 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。
  • 普通字符只能够匹配字符串中与它们相同的字符。
  • 比如,规定用户只能输入英文26个英文字母,普通字符的话 /[abcdefghijklmnopqrstuvwxyz]/
  1. 元字符(特殊字符)
  • 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
  • 比如,规定用户只能输入英文26个英文字母,换成元字符写法: /[a-z]/

1.边界符

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

如果 ^ 和 $ 在一起,表示必须是精确匹配

html
<body>
  <script>
    // 元字符之边界符
    // 1. 匹配开头的位置 ^
    const reg = /^web/;
    console.log(reg.test("web前端")); // true
    console.log(reg.test("前端web")); // false
    console.log(reg.test("前端web学习")); // false
    console.log(reg.test("we")); // false

    // 2. 匹配结束的位置 $
    const reg1 = /web$/;
    console.log(reg1.test("web前端")); //  false
    console.log(reg1.test("前端web")); // true
    console.log(reg1.test("前端web学习")); // false
    console.log(reg1.test("we")); // false

    // 3. 精确匹配 ^ $
    const reg2 = /^web$/;
    console.log(reg2.test("web前端")); //  false
    console.log(reg2.test("前端web")); // false
    console.log(reg2.test("前端web学习")); // false
    console.log(reg2.test("we")); // false
    console.log(reg2.test("web")); // true
    console.log(reg2.test("webweb")); // flase
  </script>
</body>

2.量词

量词用来设定某个模式重复次数

注意: 逗号左右两侧千万不要出现空格

html
<body>
  <script>
    // 元字符之量词
    // 1. * 重复次数 >= 0 次
    const reg1 = /^w*$/;
    console.log(reg1.test("")); // true
    console.log(reg1.test("w")); // true
    console.log(reg1.test("ww")); // true
    console.log("-----------------------");

    // 2. + 重复次数 >= 1 次
    const reg2 = /^w+$/;
    console.log(reg2.test("")); // false
    console.log(reg2.test("w")); // true
    console.log(reg2.test("ww")); // true
    console.log("-----------------------");

    // 3. ? 重复次数  0 || 1
    const reg3 = /^w?$/;
    console.log(reg3.test("")); // true
    console.log(reg3.test("w")); // true
    console.log(reg3.test("ww")); // false
    console.log("-----------------------");

    // 4. {n} 重复 n 次
    const reg4 = /^w{3}$/;
    console.log(reg4.test("")); // false
    console.log(reg4.test("w")); // flase
    console.log(reg4.test("ww")); // false
    console.log(reg4.test("www")); // true
    console.log(reg4.test("wwww")); // false
    console.log("-----------------------");

    // 5. {n,} 重复次数 >= n
    const reg5 = /^w{2,}$/;
    console.log(reg5.test("")); // false
    console.log(reg5.test("w")); // false
    console.log(reg5.test("ww")); // true
    console.log(reg5.test("www")); // true
    console.log("-----------------------");

    // 6. {n,m}   n =< 重复次数 <= m
    const reg6 = /^w{2,4}$/;
    console.log(reg6.test("w")); // false
    console.log(reg6.test("ww")); // true
    console.log(reg6.test("www")); // true
    console.log(reg6.test("wwww")); // true
    console.log(reg6.test("wwwww")); // false

    // 7. 注意事项: 逗号两侧千万不要加空格否则会匹配失败
  </script>
</body>

3.范围

表示字符的范围,定义的规则限定在某个范围,比如只能是英文字母,或者数字等等,用表示范围

html
<body>
  <script>
    // 元字符之范围  []
    // 1. [abc] 匹配包含的单个字符, 多选1
    const reg1 = /^[abc]$/;
    console.log(reg1.test("a")); // true
    console.log(reg1.test("b")); // true
    console.log(reg1.test("c")); // true
    console.log(reg1.test("d")); // false
    console.log(reg1.test("ab")); // false

    // 2. [a-z] 连字符 单个
    const reg2 = /^[a-z]$/;
    console.log(reg2.test("a")); // true
    console.log(reg2.test("p")); // true
    console.log(reg2.test("0")); // false
    console.log(reg2.test("A")); // false
    // 想要包含小写字母,大写字母 ,数字
    const reg3 = /^[a-zA-Z0-9]$/;
    console.log(reg3.test("B")); // true
    console.log(reg3.test("b")); // true
    console.log(reg3.test(9)); // true
    console.log(reg3.test(",")); // flase

    // 用户名可以输入英文字母,数字,可以加下划线,要求 6~16位
    const reg4 = /^[a-zA-Z0-9_]{6,16}$/;
    console.log(reg4.test("abcd1")); // false
    console.log(reg4.test("abcd12")); // true
    console.log(reg4.test("ABcd12")); // true
    console.log(reg4.test("ABcd12_")); // true

    // 3. [^a-z] 取反符
    const reg5 = /^[^a-z]$/;
    console.log(reg5.test("a")); // false
    console.log(reg5.test("A")); // true
    console.log(reg5.test(8)); // true
  </script>
</body>

4.字符类

某些常见模式的简写方式,区分字母和数字

三、替换和修饰符

replace 替换方法,可以完成字符的替换

html
<body>
  <script>
    // 替换和修饰符
    const str = "欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神";
    // 1. 替换  replace  需求:把前端替换为 web
    // 1.1 replace 返回值是替换完毕的字符串
    // const strEnd = str.replace(/前端/, 'web') 只能替换一个
  </script>
</body>

修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等

  • i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
  • g 是单词 global 的缩写,匹配所有满足正则表达式的结果
html
<body>
  <script>
    // 替换和修饰符
    const str = "欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神";
    // 1. 替换  replace  需求:把前端替换为 web
    // 1.1 replace 返回值是替换完毕的字符串
    // const strEnd = str.replace(/前端/, 'web') 只能替换一个

    // 2. 修饰符 g 全部替换
    const strEnd = str.replace(/前端/g, "web");
    console.log(strEnd);
  </script>
</body>

1.change 事件

给input注册 change 事件,值被修改并且失去焦点后触发

2.判断是否有类

元素.classList.contains() 看看有没有包含某个类,如果有则返回true,么有则返回false

赞赏博主
评论 隐私政策