Web APIs

Web APIs

1. Web APIs 和 JS 基础关联性

  • Web APIs 是 JS 的应用,大量使用 JS 基础语法做交互效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0F2D2Ceo-1668609195843)(https://gitee.com/colohh/image_bed/raw/master/img/JS%E7%9A%84%E7%BB%84%E6%88%90.png)]

2. API 和Web API

  • API (应用程序编程接口)一般是一些预定义的函数,是给程序员提供的一种工具,以便更轻松实现功能
  • Web API 是浏览器提供的一套操作浏览器功能页面元素API(BOM 和 BOM),主要针对浏览器做交互效果
  • Web API 一般都有输入和输出(函数的传参和返回值),Web API 很对都是方法(函数)

3. DOM

3.1 DOM 简介

  • 文档对象模型(DOM),处理可标记语言(HTML , XML)的编程接口

  • 可以改变网页的内容、结构和样式

  • DOM 树

    DOM 把以下内容都看作是对象

    • 文档:一个页面就是一个文档,DOM 中用 document 表示

    • 元素:页面中的所有标签都是元素,DOM 中用 element 表示

    • 节点:网页中所有内容都是节点(标签、属性、文本、注释等)DOM 中用 node 表示

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AyFu8AfF-1668609195844)(https://gitee.com/colohh/image_bed/raw/master/img/DOM%E6%A0%91.png)]

3.2 获取元素

3.2.1 根据 ID 获取
  • getElementById(id)

    let element = document.getElementById(id);
    
    • 返回的是一个元素对象

    • get:获得 ;element:元素 ;by:通过 – 驼峰命名法

    • 参数 id 是大小写敏感的字符串

    • 因为我们文档页面从上往下加载,所以先得有标签 所以我们script写到标签的下面

    • console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法

      <div id="time">2019-9-9</div>
      
      <script>
      	let timer = document.getElementById('time');
      	console.log(timer);// <div id="time">2019-9-9</div>
      	console.log(typeof timer);// Object
      	console.dir(timer);// time 的属性和方法
      </script>
      
3.2.2 根据标签名获取
  • getElementsByTagName(标签名)

    let lis = document.getElementsByTagName('标签名');
    
    • 返回的是带有指定标签名的对象的集合,以伪数组的形式存储

              console.log(lis);
              console.log(lis[0]);
      
    • 得到的元素是动态的

    • 我们想要依次打印里面的元素对象我们可以采取遍历的方式

      for (let i = 0; i < lis.length; i++) {
          console.log(lis[i]);
      }
      
    • 如果页面中只有一个li 返回的还是伪数组的形式

    • 如果页面中没有这个元素 返回的是空的伪数组的形式

    • element.getElementsByTagName(‘标签名’);父元素必须是指定的单个元素,获取的时候不包括父元素自己

      let ol = document.getElementById('ol');     
      console.log(ol.getElementsByTagName('li'));
      
3.2.3 通过 HTML5 新增的方法获取
(1)getElementsByClassName(类名)
  • 根据类名获得某些元素集合

    let boxs = document.getElementsByClassName('box');
    console.log(boxs);
    
(2)querySelector()
  • 返回指定选择器的第一个元素对象

    • 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号

      • querySelector(‘.类名’)
      • querySelector(‘#ID名’)
      • querySelector(‘标签名’)
      let firstBox = document.querySelector('.box');
      console.log(firstBox);
      let nav = document.querySelector('#nav');
      console.log(nav);
      var li = document.querySelector('li');
      console.log(li);
      
(3)querySelectorAll()
  • 返回指定选择器的所有元素对象集合
3.2.4 获取特殊元素
(1)获取 body 标签
let bodyEle = document.body;
console.log(bodyEle);// 元素
console.dir(bodyEle);// 属性方法
(2)获取 head 标签
let htmlEle = document.documentElement;
console.log(htmlEle);

3.3 事件基础

3.3.1 事件概述
  • JS 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为,触发相应的一种机制
3.3.2 事件三要素(执行时间的步骤)
  • 事件源(事件被触发的对象)

    • 获得事件对象
    let btn = document.getElementById('btn');
    
  • 事件类型(如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下)

  • 事件处理程序

    • 通过一个函数赋值的方式完成

      btn.onclick = function() {
          alert('点秋香');
      }
      
3.3.3 常见的鼠标事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BWh3aesJ-1668609195845)(https://gitee.com/colohh/image_bed/raw/master/img/%E5%B8%B8%E8%A7%81%E7%9A%84%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6.png)]

3.4 操作元素

3.4.1 改变元素内容
(1)innerText

替换从开始到终止位置的内容,但他去除 html 标签,同时空格和换行也会去掉

  • 获取元素

    let btn = document.querySelector('button');
    let div = document.querySelector('div');
    let p = document.querySelector('p');
    
  • 注册事件(元素可以不添加事件)

    btn.onclick = function(){
    	// div.innerText = '2019-6-6';
    	div.innerText = getDate();// JS 基础中封装的函数
    }
    // 元素可以不添加事件
    p.innerText = getDate();
    
(2)innerHTML

替换从开始到终止位置的内容,保留 html 标签,同时也保留空格和换行

(3)innerText 和 innerHTML 的区别
  • innerText 不识别html标签,同时空格和换行也会去掉

    div.innerText = '<strong>今天是:</strong> 2019';//
    

  • innerHTML 识别html标签,同时也保留空格和换行

    div.innerText = '<strong>今天是:</strong> 2019';//
    

3.4.2 操作常见元素属性

格式:元素.属性= ’ ’

常用的元素属性

  • src、href
  • id、alt、title
  • 获取元素

    let ldh = document.getElementById('ldh');
    let zxy = document.getElementById('zxy');
    let img = document.querySelector('img');
    
  • 注册事件 处理程序

    zxy.onclick = function() {
        img.src = 'images/zxy.jpg';
        img.title = '张学友思密达';
    }
    ldh.onclick = function() {
        img.src = 'images/ldh.jpg';
        img.title = '刘德华';
    }
    
3.4.3 操作表单元素属性

常用的表单元素属性:

  • type、value、checked、selected、disabled
  • 获取元素

    let btn = document.querySelector('button');
    let input = document.querySelector('input');
    
  • 注册事件 处理程序

    • 表单里面的值 文字内容是通过 value 来修改的

      btn.onclick = function() {
      	input.value = '被点击了';
      }
      
    • 如果想要某个表单被禁用 不能再点击用 disabled

      this.disabled = true;// this 指向的是事件函数的调用者 btn
      
3.4.4 操作元素样式属性

我们可以通过 JS 修改元素的大小、颜色、位置等样式

  • element==.style==

    • 行内样式:适合于样式较少的情况,CSS权重比较高

    • 获取元素

      let div = document.querySelector('div')
      
    • 注册事件 处理程序

      div.onclick = function() {
      	//div.style
      	this.style.backgroundColor = 'purple';//点击修改颜色
      	this.style.width = '250px';//修改宽度
      	this.style.display = 'none';//点击隐藏
      }
      
  • element.className

    • 类名样式:className更改元素的样式 适合于样式较多或者功能复杂的情况

    • className 会直接更改、覆盖原来的类名

      如果想要保留原先的类名,可以在原来的类名后面加上空格和新的类名(多类名选择器)

    • 在 CSS 中 写一个 .change 样式

      .change {
          background-color: purple;
          color: #fff;
          font-size: 25px;
          margin-top: 100px;
      }
      
    • 获取元素 注册事件 处理程序

      <div class="first">文本</div>
      <script>
      var test = document.querySelector('div');
      test.onclick = function() {
      	this.className = 'first change';// 多类名选择器
      }
      </script>
      
3.4.6 排他思想

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9gFfZhPh-1668609195846)(https://gitee.com/colohh/image_bed/raw/master/img/%E6%8E%92%E4%BB%96%E6%80%9D%E6%83%B3.png)]

如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想算法:

  • 所有元素全部清除样式
  • 给当前元素设置样式
  • 注意顺序不能颠倒,先干掉其他人,再设置自己
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
    //1.获取所有元素
    let btns = document.querySelectorAll('button');
    // btns 得到的是伪数组 里面的每一个元素 btns[i]
    for(let i = 0; i < btns.length; i++) {
        btns[i].onclick = function() {
            // (1)我们先把所有的按钮背景颜色全部去掉
            for(let j = 0; j < btns.length; j++) {
                    btns[j].style.backgroundColor = '';
            }
            // (2)然后再把选中的按钮背景颜色改为粉色
            this.style.backgroundColor = 'pink';
        }
    }

</script>
3.4.7 自定义属性的操作

自定义属性的目的:为了保存并使用一些不用保存在数据库中直接保存在页面中的数据。

(1)获取属性值
  • element.属性

    • 获取内置属性值(元素本身自带的)
    <div id="box" index="1"></div>
    <script>
        let box = document.querySelector('div');
        // 打印box属性值 id
        console.log(div.id);
    </script>
    
  • 获取自定义属性

    • 兼容性获取 element.getAttribute(‘data-index’)

      • 主要获取我们自己添加自定义的属性值(index)
      // 打印box属性值 index
      console.log(div.getAttribute('data-index'));
      
    • H5 新增方法 element.dataset.indexelement.dataset[‘index’]

      • 它只能获取 data- 开头的

      • dataset 是一个集合 里面存放了所有以 data 开头的自定义属性

      • 如果自定义属性里面有多个 - 连接的单词,我们获取的时候采取 驼峰命名法

      <div id="box" data-index="1" data-list-name="andy"></div>
      <script>
      	console.log(div.dataset.index);
      	console.log(div.dataset['index']);
          console.log(div.dataset.listName);
          console.log(div.dataset['listName']);
      </script>
      
(2)设置属性值
  • element.属性 = ‘值’

    • 设置内置属性值
    div.id = 'text';
    div.className = 'navs';// 修改类名 class
    
  • element.setAttribute(‘属性’,‘值’)

    • 主要设置自定义属性
    • H5 规定自定义属性要以 data-开头 作为属性名并赋值
    <div></div>
    <script>
    	div.setAttribute('data-index',0);
    	div.setAttribute('class','footer');// 修改类名 class
    </script>
    
(3)移除属性
  • element.removeAttribute(‘属性’)

    div.removeAttribute('index')
    

3.5 节点操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKHWL1qz-1668609195846)(https://gitee.com/colohh/image_bed/raw/master/img/%E8%8E%B7%E5%8F%96%E5%85%83%E7%B4%A0.png)]

3.5.1 节点概述
  • 网页中所有内容都是节点(标签、属性、文本、注释等

  • HTML DOM 书中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zxYW3m5v-1668609195847)(https://gitee.com/colohh/image_bed/raw/master/img/DOM%E6%A0%91.png)]

  • 一般地,节点至少拥有 nodeType(节点类型)nodeName(节点名称)、==nodeValue(节点值)==这三个基本属性。

    • nodeType 的值
      • 元素节点为 1
      • 属性节点为 2
      • 文本节点为 3(文本节点包括文字、空格、换行等)
3.5.2 节点层级
(1)父级节点
  • element.parentNode

    • 得到的是离 element 最近的父节点

      <div class="box">
          <span class="erweima">×</span>
      </div>
      <script>
          let erweima = document.querySelector('.erweima');
          // 如果找不到父节点就返回 null
          console.log('erweima.parentNode');// 获取box
      </script>
      
(2)子节点
① 获取子节点
  • parentNode.childNodes(不提倡)

    • childNodes 得到的所有子节点包括:元素节点、文本节点等等。如果我们只想要获得元素节点,则需要专门处理:

      <ul>
          <li></li>
          <li></li>
          <li></li>
      </ul>
      <script>
          // 获取元素
          let ul = document.querySelector('ul');
          console.log(ul.childNode);
          // 只保留元素节点
          for(let i = 0; i < ul.childNodes.length; i++){
              if(ul.childNodes[i].nodeType == 1) {
                  console.log(ul.childNodes[i]);
              }
          }
      </script>
      
  • parentNode.children

    • 它是一个只读属性,返回所有的子元素节点。也是我们实际开发常用的。

      console.log(ul.children);
      
② 获取第一个和最后一个子节点
  • 第一个子节点

    • parentNode.firstChild:包括 文本节点 和 元素节点

      let ul = document.querySelector('ul');
      console.log(ul.firstChild);
      
    • parentNode.firstElementChild 只返回元素节点

      console.log(ul.firstElementChild;
      
    • parentNode.children[]

      console.log(ul.children[0]);
      
  • 最后一个子节点

    • parentNode.lastChild:包括 文本节点 和 元素节点

      let ul = document.querySelector('ul');
      console.log(ul.lastChild);
      
    • parentNode.lastElementChild 只返回元素节点

      console.log(ul.firstElementChild;
      
    • parentNode.children[]

      console.log(ul.children[ul.children.length - 1]);
      
(3)兄弟节点
  • 下一个兄弟节点

    • node.nextSibling:包含元素节点 或者 文本节点等等

      <div>我是div</div>
      <span>我是span</span>
      <script>
          var div = document.querySelector('div');
          console.log(div.nextSibling);
      </script>
      
    • node.nextElementSibling:得到下一个兄弟元素节点

      console.log(div.nextElementSibling);
      
  • 上一个兄弟节点

    • node.previousSibling:包含元素节点 或者 文本节点等等

      console.log(div.previousSibling);
      
    • node.previousElementSibling:得到上一个兄弟元素节点

      console.log(div.previousElementSibling);
      
3.5.3 创建节点

先创建 再添加位置

  • 动态创建元素节点

  • document.createElement(‘tagName’);

    • 创建多个元素效率稍微低一些,但是结构更清晰
    let li = document.createElement('li');
    
  • document.innerHTML(‘tagName’);

    • 创建多个元素效率更高(前提是不要拼接字符串,采取数组形式拼接),结构稍微复杂
    let inner = document.querySelector('.inner');
    inner.innerHTML = '<a href='#'>百度</a>'
    
  • document.write(‘tagName’);

    • 如果页面文档流加载完毕,再调用这句话会导致页面重绘
  • 添加节点

    • node.appendChild(child) :将 一个节点(child)追加到指定父节点(node)列表末尾

    • appendChild 不支持追加字符串的子元素,insertAdjacentHTML 支持追加字符串的元素

      let ul = document.querySelector('ul');
      ul.appendChild(li);
      
    • node.insertBefore(child, 指定元素):将 一个节点(child)追加到指定节点前面

      let lili = document.createElement('li');
      ul.insertBefore(lili, ul.children[0]);
      
3.5.4 删除节点
  • node.removeChild(child)

    • 从 DOM 中删除一个子结点,返回删除的节点

      let ul = document.querySelector('ul');
      ul.removeChild(ul.children[0]);
      
3.5.5 复制节点(克隆节点)

先克隆,再添加位置

  • 克隆指定节点

    • node.cloneNode()

    • 括号参数空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点;

    • 若想要克隆标签及内容,只需在括号里写 true :node.cloneNode(true)

      let ul = document.querySelector('ul');
      let lili = ul.children[0].cloneNode()
  • 添加节点位置

    • 同 3.5.3 添加节点(有两种方法)

      ul.appendChild(lili)
      
3.5.6 创建并插入节点 insertAdjacentHTML()
  • insertAdjacentHTML() 方法将指定的文本解析为 HTML 或 XML,并将结果节点插入到DOM树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接使用innerHTML操作更快。

  • 利用 insertAdjacentHTML() 可以直接把字符串格式添加到父元素中

  • 语法:

    • position 是插入的位置

    • text 是要被解析为 HTML 和 XML,并插入到 DOM 树中的字符串

      element.insertAdjacentHTML(position,text);
      
  • 参数

    • ‘beforebegin’
      • 元素自身的前面
    • ‘afterbegin’
      • 插入元素内部的第一个子节点之前
    • ‘beforeend’
      • 插入元素内部的最后一个子节点之后
    • ‘afterend’
      • 元素自身的后面
  • 代码实例:

    let html = '<div id="two">two</div>';
    div.insertAdjacentHTML('beforeend',html);
    

3.6 事件高级

3.6.1 注册事件(绑定事件)

给元素添加事件,称为注册事件。

注册事件有两种方式:传统方式和方法监听注册方式

(1)传统注册方式
  • 利用 on 开头的事件

  • 特点:注册事件的唯一性:同一个元素同一个事件只能执行一次

    <button onclick="alert('hi~')"></button>
    <script>
        btn.onclick = function(){
    	alert('hi~')
    	}
    </script>
    
(2)方法监听注册方式
  • w3c 标准 推荐方式

  • 特点:同一个元素同一个事件可以注册多个监听器,按照注册顺序依次执行

  • ==addEventListener()==它是一种方法

    eventTarget.addEventListenner(type,listener[,useCapture])

    • type:事件类型字符串,比如 click、mouseover,注意这里没有on哦

    • listener:事件处理函数,事件发生时,会调用该监听函数

    • useCapture:可选参数,是一个布尔值,默认为 false

      btn.addEventListener('click',function(){
      	alert('hi~')
      })
      
3.6.2 删除事件(解绑事件)
(1)传统方式删除事件
  • eventTarget.onclick = null;

    let div = document.querySelector('div');
    div.onclick = function() {
    	alert('hi~');
    	// 删除事件
    	div.onclick = null;
    }
    
(2)方法监听注册方式删除事件
  • eventTarget.removeEventListener(type,listener[,useCapture]);

    btn.addEventListener('click',fn);// 里面的 fn 不需要调用 所以不加小括号
    function fn() {
        alert('hi~');
        // 删除事件
        btn.removeEventListener('click',fn);
    }
    
3.6.3 DOM事件流
  • 事件流描述的是从页面中接收事件的顺序

  • 事件发生时会在元素节点中按照特定的顺序传播,这个传播过程即DOM事件流

  • DOM事件流分为三个阶段:

    • 捕获阶段
    • 当前目标阶段
    • 冒泡阶段
      • 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-duGFu7Aw-1668609195848)(https://gitee.com/colohh/image_bed/raw/master/img/DOM%E4%BA%8B%E4%BB%B6%E6%B5%81.png)]
  • 代码验证

    • JS 代码中只能执行捕获或者冒泡其中的一个阶段。

    • onclick 和 attachEvent(ie) 只能得到冒泡阶段。

    • 捕获阶段

      • 如果addEventListener 第三个参数是 true 那么则处于捕获阶段

      • document -> html -> body -> father -> son

        // 先输出 father 再输出 son
        let son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, true);
        let father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, true);
        
    • 冒泡阶段

      • 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段

      • son -> father ->body -> html -> document

        // 先输出 son 再输出 father 最后是 document
        let son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        let father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        document.addEventListener('click', function() {
            alert('document');
        })
        
3.6.4 事件对象

div.onclick = function(event) {}

  • event 就是一个事件对象 写到我们侦听函数的小括号里面 当形参来看

  • 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数

  • 事件对象是跟事件相关的一系列相关数据的集合(属性和方法):比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标等;如果是键盘事件里面就包含的键盘事件的信息,比如判断用户按下了那个键

  • 事件对象可以自己命名 比如 event 、 evt、 e

  • 事件对象的常见属性和方法:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iVBsl4mB-1668609195848)(https://gitee.com/colohh/image_bed/raw/master/img/%E4%BA%8B%E4%BB%B6%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%B8%B8%E8%A7%81%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95.png)]

3.6.5 阻止事件冒泡

事件对象阻止默认行为

让链接不跳转或让提交按钮不提交

<a href="http://www.baidu.com">百度</a>
<script>
	let a = document.querySelector('a');
	a.addEventListener('click',function(e){
		e.preventDefault;// 阻止链接跳转
	})
</script>
阻止事件冒泡的方式
  • 利用事件对象里面的 stopPropagation() 方法

    e.stopPropagation()

    // 先输出 son 再输出 father 最后是 document
    let son = document.querySelector('.son');
    son.addEventListener('click', function(e) {
        alert('son');
        e.stopPropagation();// 阻止冒泡 后面的 father 和 document 都不会再响应了
    }, false);
    let father = document.querySelector('.father');
    father.addEventListener('click', function() {
        alert('father');
    }, false);
    document.addEventListener('click', function() {
        alert('document');
    })
    
3.6.6 事件委托(代理、委派)
(1)事件委托的原理

不是给每个子结点单独设置事件监听器,而是将事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子结点。

(2)事件委托的作用

只操作了一次DOM,提高了程序的性能。

(3)代码实现

当我们点击 li 的时候,因为事件冒泡 所以也会 click 到父节点 ul ,从而触发 alert 事件,而不用给每个 li 单独绑定事件

<ul>
    <li>hello</li>
    <li>hello</li>
    <li>hello</li>
    <li>hello</li>
</ul>
<script>
    //获取父节点
    let ul = document.querySelector('ul');
    //给父节点绑定事件
    ul.addEventListener('click',function() {
        alert('hello')
    })
</script>

点击 li 改变 li 的背景颜色:

<ul>
    <li>hello</li>
    <li>hello</li>
    <li>hello</li>
    <li>hello</li>
</ul>
<script>
    //获取父节点
    let ul = document.querySelector('ul');
    //给父节点绑定事件
    ul.addEventListener('click',function(e) {
        // e.target 这个可以得到我们点击的对象
        e.target.style.backgroundColor = 'pink';
    })
</script>
3.6.7 常用的鼠标事件
(1)鼠标事件
1. 常用的鼠标事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5DHQbcz3-1668609195849)(https://gitee.com/colohh/image_bed/raw/master/img/%E5%B8%B8%E8%A7%81%E7%9A%84%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6.png)]

  • mouseenter 和 mouseover(mouseleave 和 mouseout) 的区别
    • mouseenter / mouseleave 鼠标事件
      • mouseenter /mouseleave 只会经过自身盒子触发(mouseenter / mouseleave 不会冒泡
    • mouseover / mouseout 鼠标事件
      • mouseover / mouseout 鼠标经过自身盒子会触发,经过子盒子还会触发。
2. 禁止鼠标右键菜单(了解)

contextmenu 主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单(禁用右键菜单)

document.addEventListener('contextmenu',function(e) {
	e.preventDefault();
})
3. 禁止选中文字(了解)
document.addEventListener('selectstart',function(e) {
	e.preventDefault();
})
(2)鼠标事件对象

event 对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jSkXsCB1-1668609195850)(https://gitee.com/colohh/image_bed/raw/master/img/%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6%E5%AF%B9%E8%B1%A1.png)]

  • 案例 - 跟随鼠标的天使

    <head>
    <style>
            img {
                position: absolute;
                top: 2px;
            }
        </style>
    </head>
    
    <body>
        <img src="images/angel.gif" alt="">
        <script>
            var pic = document.querySelector('img');
            document.addEventListener('mousemove', function(e) {
                // 1. mousemove只要我们鼠标移动1px 就会触发这个事件
                // console.log(1);
                // 2.核心原理: 每次鼠标移动,我们都会获得最新的鼠标坐标, 把这个x和y坐标做为图片的top和left 值就可以移动图片
                var x = e.pageX;
                var y = e.pageY;
                console.log('x坐标是' + x, 'y坐标是' + y);
                //3 . 千万不要忘记给left 和top 添加px 单位
                pic.style.left = x - 50 + 'px';
                pic.style.top = y - 40 + 'px';
            });
        </script>
    </body>
    
3.6.8 常用的键盘事件
(1)常用键盘事件

三个事件同时存在时的顺序: keydown – keypress – keyup

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bsfwu6WO-1668609195851)(https://gitee.com/colohh/image_bed/raw/master/img/%E5%B8%B8%E7%94%A8%E9%94%AE%E7%9B%98%E4%BA%8B%E4%BB%B6.png)]

(2)键盘事件对象

键盘事件对象(keyboardEvent)中的 keyCode 属性可以得到相应键的 ASCII 码值

  • 利用 keyCode 判断用户按了哪个键

    • keyup 和 keydown 事件不区分字母大小写:按下 a 和 A 得到的都是65

      document.addEventListener('keyup',function(e){
      	console.log(e.keyCode);
      })
      
    • keypress 事件区分字母大小写:按下 A 得到65;按 a 得到97

4. BOM

4.1 BOM 概述

4.1.1 BOM 简介
  • BOM(浏览器对象模型),它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window
  • BOM 学习的是浏览器窗口交互的一些对象
  • BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差
  • BOM 由一系列相关的对象组成,并且每个对象都提供了很多方法和属性。
4.1.2 BOM 构成

BOM 比 DOM 更大,它包含 DOM

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J4ijpbSJ-1668609195852)(https://gitee.com/colohh/image_bed/raw/master/img/BOM%E7%9A%84%E6%9E%84%E6%88%90.png)]

4.2 window 对象的常见事件

  • window 对象是浏览器的顶级对象,它具有双重角色
    • 它是 JS 访问浏览器窗口的一个接口。
    • 他是一个全局对象,定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法
4.2.1 窗口加载事件

当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等)

以前 js 部分只能放到 css布局的下面,用这个方法 js 部分就可以放在文件的任意位置

  • window.onload

  • 但这种传统的注册事件方式只能写一次,若写了多个,以最后一个为准

    window.onload = function(){
    	...
    }
    
  • window.addEventListener(‘load’, function() {})

    • 可以写任意个事件,没有限制

      window.addEventListener('load', function() {
      	...
      })
      
  • document.addEventlistener(‘DOMContentLoaded’,function() {})

    • 仅当 DOM 加载完成(不包含样式表、图片、flash等)时,即触发事件。
    • 好处:页面图片过多时,用户访问到onload触发可能需要较长时间,交互效果就不能实现,影响用户体验。此时用 DOMContentLoaded 即可解决。
4.2.2 调整窗口大小事件

只要窗口大小发生像素变化,就会触发这个事件

  • resize

    • 使用方式

      window.onresize = function() {}
      window.addEventListener('resize',function() {})
      
    • 常用场景

      响应式布局:当我们把浏览器窗口缩小到一定大小时,隐藏某些节点

      let div = document.querySelector('div');
      windows.addEventLisener('resize',function() {
      	// window.innerWidth 为浏览器窗口宽度
          if (window.innerWidth <= 800) {
              div.style.display = 'none';
          }
      })
      

4.3 定时器

4.3.1 setTimeout() 定时器

setTimeout() 这个调用函数我们也称为回调函数 callback

  • 语法规范(window可以省略)

    • 定时器到期后调用函数

    • 延时时间单位是毫秒,可以省略

    • 这个调用函数可以直接写函数,还可以写函数名

      window.setTimeout(调用函数,[延迟的毫秒数]);
      
  • 停止定时器 clearTimeout()

    • 语法规范

      window.clearTimeout(timeoutID)
      
    • 实际运用

      <button>点击停止计时器</button>
      <script>
          let btn = document.querySelector('button');
          let timer = setTimeout(function() {
              console.log('boom!')
          },5000);
          btn.addEventListener('click',function() {
              clearTimeout(timer);// 停止计时器
          })
      </script>
      
4.3.2 setInterval() 定时器
  • 语法规范(window可以省略)

    • 反复调用这个函数:每隔这个时间,就去调用一次这个函数

    • 间隔的毫秒数默认是 0

    • 第一次执行时也有间隔毫秒数,因此刷新页面会有空白

      • 解决方式:可以先调用一次这个函数(setInterval()之前),防止刷新后空白
    • 这个调用函数可以直接写函数,还可以写函数名

      window.setInterval(回调函数,[间隔的毫秒数]);
      
  • 停止定时器 clearInterval()

    • 语法规范

      window.clearInterval(timeoutID)
      
    • 实际运用

      <button class="begin">点击开启计时器</button>
      <button class="stop">点击停止计时器</button>
      <script>
          let begin = document.querySelector('.begin');
          let stop = document.querySelector('.stop');
          let timer = null;// 全局变量 null是一个空对象
          begin.addEventListener('click',function() {
              timer = setInterval(function() {
                  console.log('boom')
              },1000);
          })
          stop.addEventListener('click',function() {
              clearInterval(timer);// 停止计时器
          })
      </script>
      
4.3.3 this指向问题

一般情况下this的最终指向的是那个调用它的对象

  • 全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window)

    console.log(this);
    
    function fn() {
        console.log(this);
    }
    
    window.setTimeout(function() {
        console.log(this);
    
    }, 1000);
    
  • 方法调用中谁调用this指向谁

    let o = {
        sayHi: function() {
            console.log(this); // this指向的是 o 这个对象
        }
    }
    o.sayHi(); 
    
  • 构造函数中this指向构造函数的实例

    function Fun() {
        console.log(this); // this 指向的是fun 实例对象
    }
    var fun = new Fun();
    

4.4 JS 执行机制

JS 是单线程同一个时间只做一件事

4.4.1 同步和异步

为了解决这个问题,利用多核 CPU 的能力,H5 提出 Web Worker 标准,允许 JS脚本创建多个线程。于是,JS中出现了同步异步

(1)同步
  • 前一个任务结束后再执行下一个任务,程序的执行顺序和任务的排列顺序是一样的。
  • 同步任务都在主线程上执行,形成一个执行栈
(2)异步
  • 在做这件事的同时,还可以处理其他事情。
  • JS 的异步是通过回调函数实现的。异步任务相关回调函数添加到任务队列(消息队列)中
  • 一般而言,异步任务有以下三种类型:
    • 普通事件:如 click、resize 等
    • 资源加载:如 load、error 等
    • 定时器:如 setInterval、setTimeout 等
4.4.2 执行机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uaw7QT4f-1668609195852)(https://gitee.com/colohh/image_bed/raw/master/img/JS%E6%89%A7%E8%A1%8C%E6%9C%BA%E5%88%B6.png)]

  • 先执行执行栈中的同步任务
  • 异步任务(回调函数)放入任务队列中。
  • 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

4.5 location 对象

window 对象给我们提供了一个 location 属性用于获取或设置窗体的 URL(网址),并且可以用来解析 URL 。因为这个属性返回的是一个对象,所以我们将这个属性也称为 location 对象

4.5.1 location 对象的属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-48w6EhFi-1668609195853)(https://gitee.com/colohh/image_bed/raw/master/img/location%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%B1%9E%E6%80%A7.png)]

(1)location.href
  • 可以获取网址或实现跳转

    <button>点击</button>
    <script>
            let btn = document.querySelector('button');
            let div = document.querySelector('div');
            btn.addEventListener('click', function() {
                console.log(location.href);// 获取网址
                location.href = 'http://www.itcast.cn'; // 实现跳转
            })
    </script>
    
(2)location.search
  • 可以返回参数 (详见 Web APIs-第三天-10-获取URL参数)

    • 登陆页面 login.html

      <body>
          登陆页面
          <!-- form实现跳转  -->
          <form action="index.html" method="
          get"> 
              用户名:
              <input type="text" name="uname">
              <input type="submit" value="登录">
          </form>
      </body>
      
    • 主页 index.html

      <body>
          首页
          <div>
              <i>andy</i> 欢迎光临
          </div>
          <script>
              let i = document.querySelector('i');
              // 通过 location.search 把参数 uname 拿过来
              console.log(location.search);// ?uname=andy
              // 1.先去掉? substr('起始的位置',截取几个字符)
              let params = location.search.substr(1);
              // 2.利用 = 把字符串分割为数组 split('=');
              let arr = params.split('=');
              // 3.把数据写入div中
              i.innerHTML = arr[1];
              // console.log(location.href)
          </script>
      </body>
      
4.5.2 location 对象的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-heTu4x3V-1668609195853)(https://gitee.com/colohh/image_bed/raw/master/img/location%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E6%B3%95.png)]

(1)location.assign()
  • 跳转页面

    • location.assign() 是记录浏览历史的,所以可以实现后退功能
    <button>按钮</button>
    <script>
        let btn = document.querySelector('button');
        btn.addEventListener('click',function() {
            location.assign('https://www.bilibili.com');
        })
    </script>
    
(2)location.replace()
  • 跳转页面,用法同 assign
  • location.replace() 不记录浏览历史,所以不能后退
(3)location.reload()
  • 刷新页面

    <button>按钮</button>
    <script>
        let btn = document.querySelector('button');
        btn.addEventListener('click',function() {
            location.reload();
            location.reload(ture);// 强制刷新
        })
    </script>
    

4.6 navigator 对象

navigator 对象包含有关浏览器的信息,他有很多属性,我们最常用的是 userAgent,该属性可以返回由客户机发送服务器的 user-agent 头部的值。

  • 下面一段代码可以判断用户从哪个终端打开页面,实现跳转

    
    if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
    	window.location.href = "../H5/index.html"; //手机
    }
    

4.7 history 对象

window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的 URL。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V1iM3Ivs-1668609195853)(https://gitee.com/colohh/image_bed/raw/master/img/history%E5%AF%B9%E8%B1%A1%E6%96%B9%E6%B3%95.png)]

代码示例:

<body>
    <a href="list.html">点击我去往列表页</a>
    <button>前进</button>
    <script>
        let btn = document.querySelector('button');
        btn.addEventListener('click',function() {
            // history.forward()
            // 前进
            history.go(1)
        })
    </script>
</body>
let btn = document.querySelector('button');
  btn.addEventListener('click',function() {
      location.assign('https://www.bilibili.com');
  })
```
(2)location.replace()
  • 跳转页面,用法同 assign
  • location.replace() 不记录浏览历史,所以不能后退
(3)location.reload()
  • 刷新页面

    <button>按钮</button>
    <script>
        let btn = document.querySelector('button');
        btn.addEventListener('click',function() {
            location.reload();
            location.reload(ture);// 强制刷新
        })
    </script>
    

4.6 navigator 对象

navigator 对象包含有关浏览器的信息,他有很多属性,我们最常用的是 userAgent,该属性可以返回由客户机发送服务器的 user-agent 头部的值。

  • 下面一段代码可以判断用户从哪个终端打开页面,实现跳转

    
    if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
    	window.location.href = "../H5/index.html"; //手机
    }
    

4.7 history 对象

window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的 URL。

[外链图片转存中…(img-V1iM3Ivs-1668609195853)]

代码示例:

<body>
    <a href="list.html">点击我去往列表页</a>
    <button>前进</button>
    <script>
        let btn = document.querySelector('button');
        btn.addEventListener('click',function() {
            // history.forward()
            // 前进
            history.go(1)
        })
    </script>
</body>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值