Web APIs 笔记

Web APIs 简介:

1、Web APIs 阶段与JS语法基础阶段的关联性?

2、什么是API ?

3、什么是 Web API ?

JS的组成:ECMAScript (JS语法)、 DOM、BOM(Web API)

目标:

  • 什么是DOM,

  • DOM树

    DOM HTML 树

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

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

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

    节点的属性

    nodeNamenodeTypenodeValue
    文档节点#document9null
    元素节点标签名1null
    属性节点属性名2属性值
    文本节点#text3文本内容

    DOM把以上内容看做是对象

    文档对象模型,是W3C组织推荐的处理可扩展的标记语言(HTML或者XML)的标准编程接口。

一、获取页面元素:

window.onload() 方法用于在网页加载完毕后立刻执行的操作,即当 HTML 文档加载完毕后,立刻执行某个方法。

window.onload() 通常用于 元素,在页面完全载入后(包括图片、css文件等等)执行脚本代码。

1、根据ID进行获取

document.getElementById(“time”)

    //1,由于文档页面是从上往下面加载,所以script写在下面
    //2,get 获得 element 元素 by 通过驼峰命名法
    //3,参数 id 是大小写敏感的字符串
    //4,返回的是一个元素对象
    var timer = document.getElementById("time");
    console.log(timer);
    console.log(typeof timer);
    //5,console.dir打印我们返回的元素对象,更好地查看里面的属性和方法
    console.dir(timer);

getElementsByName() 通过name属性获取一组元素节点对象

2、根据标签名进行获取

getElementsByTagName()方法可以返回带有指定标签名的对象的集合。

还可以获取某个元素(父元素)内部所有指定标签名的子元素。

element.getElementByTagName(‘标签名’);

注意:父元素必须是单个对象(必须指明是哪一个元素的对象)。获取的时候不包括父元素自己。

<body>
  <ul>
    <li>把加班餐,不打扮的1</li>
    <li>把加班餐,不打扮的2</li>
    <li>把加班餐,不打扮的3</li>
  </ul>
  <ol id="ol">
    <li>努努N年你1</li>
    <li>努努N年你2</li>
    <li>努努N年你3</li>
  </ol>
  <script>
    //返回的是,获取过来元素对象的集合 以伪数组的形式存储的
    var lis = document.getElementsByTagName("li");
    console.log(lis);
    console.log(lis[0]);
    //2、想要依次打印里面的元素对象我们可以采用遍历的方式
    for (var i = 0; i < lis.length; i++) {
      console.log(lis[i]);
    }
    //3,如果页面中只有一个li ,返回的还是伪数组的形式。
    //4、如果页面中没有这个元素返回的还是空的伪数组的形式
    //5、element.getElementByTagName('标签名');父元素必须是指定的单个元素

    var arrol = document.getElementsByTagName("ol"); // [ol] 获得是一个数组
    console.log(arrol[0].getElementsByTagName("li"));
    /*  var ol = document.getElementById("ol"); //获得的是一个对象
    console.log(ol.getElementsByTagName("li")); */
  </script>
</body>

3、通过HTML5新增的方法获取
<body>
  <div class="box">盒子1</div>
  <div class="box">盒子2</div>
  <div id="nav">
    <ul>
      <li>首页</li>
      <li>产品</li>
    </ul>
  </div>
  <script>
    // 1、 document.getElementsByClassName('类名'); 根据类名返回元素对象的集合
    
    var boxs = document.getElementsByClassName("box"); //以伪数组的形式存储
    console.log(boxs);
    
    var firstBox = document.querySelector(".box");
    console.log(firstBox);
    
    //2、 document.querySelector('选择器');  根据指定选择器返回第一个元素的对象
    //   注意:里面的选择器需要加符号  .box  #nav
    
    var nav = document.querySelector("#nav");
    console.log(nav);
    var li = document.querySelector("li");
    console.log(li);
   
   //3、document.querySelectorAll('选择器');根据指定选择器返回所有元素对象的集合
    
    var allBox = document.querySelectorAll(".box");
    console.log(allBox);
    var lis = document.querySelectorAll("li");
    console.log(lis);
  </script>
</body>

4、特殊元素获取
  • 能够给元素注册事件,

  • 能够操作DOM元素的属性,

  • 能够创建元素,

  • 能够操作DOM的节点

获取body元素和获取html元素:

 <body>
    <script>
      //1、获取 body元素
      var bodyEle = document.body;
      console.log(bodyEle);
      // 2、 获取html元素
      var htmlEle = document.documentElement;
      console.log(htmlEle);
      // 3、获取页面中的所有元素
      var all = document.all;
      // all = document.getElementsByTagName('*');同上
      console.log(all);
    </script>
  </body>

在这里插入图片描述

二、事件基础

JS使我们有能力创建动态页面,而事件是可以被JS侦测到的行为。 简单理解:触发---->响应机制

1、事件有三部分组成:

(1)事件源(2) 事件类型 (3)事件处理程序

<body>
    <button id="btn">唐伯虎</button>
    <script>
      //点击一个按钮弹出对话框
      //(1)事件源 事件被触发的对象
      var btn = document.getElementById("btn");
      //(2)事件类型: 如何触发  什么事件? 例如:鼠标点击(onclick) 鼠标经过 还是键盘按下触发 或者 滚轮
      //(3)事件处理程序 : 通过一个函数赋值的方式完成
      btn.onclick = function () {
        alert("点秋香");
      };
    </script>

执行事件的步骤:1,获取事件源 2,注册事件(绑定事件) 3,添加事件处理程序(采用函数赋值的方法)

 //执行事件的步骤
      //获取事件源
      var div = document.querySelector("div");
      //绑定事件 div.document
      //添加事件处理程序
      div.onclick = function () {
        console.log("我被选中了");
      };
鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
onmouseout鼠标离开触发
onfocus获得鼠标焦点触发
onblur失去鼠标焦点触发
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发

三、操作元素

JS的DOM操作可以改变网页的内容,结构和样式,可以利用DOM操作元素来改变元素里面的内容、属性等。注意以下都是属性

1、改变元素的内容

element.innerText

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

element.innerHTML

起始位置到终止位置的全部内容,包括HTML标签,同时保留空格和换行

<body>
    <div></div>
    <p>
      我是蚊子
      <span>1123</span>
    </p>
    <script>
      // innerText 和 innerHTML 的区别
      //1、innerText的使用方法 不识别html标签 非标准  去除空格和换行
      var div = document.querySelector("div");
      div.innerText = " <strong> 今天是:</strong> 2022";
      //2、innerHTML的使用方法 识别html标签 W3C标准  保留空格和换行
      // div.innerHTML = " <strong> 今天是:</strong> 2022";
      // 这两个属性是可以读写的  可以获取元素里面的内容
      var p = document.querySelector("p");
      console.log(p.innerText);
      console.log(p.innerHTML);
    </script>
  </body>

在这里插入图片描述

 <style>
      img {
        width: 200px;
      }
      #panda {
        margin-right: 80px;
      }
    </style>
  </head>
  <body>
    <button id="panda">大熊猫</button>
    <button id="yyy">小绵羊</button>
    <br />
    <img src="images/panda.webp" alt="" title="大熊猫" />
    <script>
      // 获取元素
      var yyy = document.getElementById("yyy");
      var panda = document.getElementById("panda");
      var img = document.querySelector("img");
      // 注册事件,处理程序
      yyy.onclick = function () {
        img.src = "images/yyy.webp";
        img.title = "小绵羊";
      };
      panda.onclick = function () {
        img.src = "images/panda.webp";
        img.title = "大熊猫";
      };
    </script>
  </body>

在这里插入图片描述

<!-- 根据不同时间,页面显示不同的图片,同时显示不同的问候语

如果上午时间打开页面,显示上午好,显示上午的图片

如果是下午时间打开页面,显示下午好,显示下午的图片

如果是晚上时间打开页面,显示晚上好,显示晚上的图片 -->

案列分析:

  1. 根据系统不同时间来判断,所以需要用日期的对象
  2. 利用多分支语句来设置不同的图片
  3. 需要一个图片,并且要根据时间修改图片,就需要用到操作元素src的属性
  4. 需要一个div元素,显示问候语,修改元素内容即可
<style>
      img {
        width: 300px;
      }
    </style>
  </head>
  <body>
    <img src="images/skay.webp" alt="" />
    <div>上午好</div>
    <script>
      //获取元素
      var img = document.querySelector("img");
      var div = document.querySelector("div");
      //得到当前的小时数
      var date = new Date();
      var h = date.getHours();
      //判断小时数来来改变图片和文字信息
      if (h < 12) {
        img.src = "images/skay.webp";
        div.innerHTML = "亲,上午好";
      } else if (h < 18) {
        img.src = "images/dog.webp";
        div.innerHTML = "亲,下午好";
      } else {
        img.src = "images/cat2.webp";
        div.innerHTML = "亲,啊晚上好呀";
      }
    </script>
  </body>

在这里插入图片描述

2、表单元素属性操作

利用DOM可以操作如下表单元素的属性:

type、value、checked、selected、disabled(禁用)

<body>
    <button id="btn">按钮</button>
    <input type="text" value="输入内容" name="" id="" />
    <script>
      var btn = document.getElementById("btn");
      var input = document.querySelector("input");
      btn.onclick = function () {
        input.value = "大傻逼";
        // btn.disabled = true;
        this.disabled = true; //this  指向的是时间函数的调用者
      };
    </script>
  </body>
 仿京东显示密码:
 <style>
      * {
        margin: 0;
        padding: 0;
      }
      .box {
        position: relative;
        width: 400px;
        border: 1px solid #ccc;
        margin: 50px auto;
      }
      .box input {
        width: 370px;
        height: 30px;
        outline: none;
        border: 0;
      }
      .box img {
        position: absolute;
        width: 24px;
        top: 4px;
        right: 4px;
      }
    </style>
  </head>
 <body>
    <!--1、核心思路:点击眼睛按钮,把密码框类型改为文本框就可以看见里面的密码 -->
    <!--2、一个按钮可以分为两种状态,点击一次,切换为文本框,再点击一次,切换为密码框 -->
    <!--3、利用一个flag变量,来判断flag的值,如果是1就切换为文本框,flag设置为0,
        如果是0,就切换为密码框,flag设置为1-->
    <div class="box">
      <label for="">
        <img src="images/close.png" alt="" id="eye" />
      </label>
      <input type="password" name="" id="pwd" />
    </div>
    <script>
      //获取元素
      var eye = document.getElementById("eye");
      var pwd = document.getElementById("pwd");
      //注册事件 处理程序
      var flag = 0;
      eye.onclick = function () {
        if (flag == 0) {
          pwd.type = "text";
          eye.src = "images/open.png";
          flag = 1;
        } else {
          pwd.type = "password";
          eye.src = "images/close.png";
          flag = 0;
        }
      };
    </script>
  </body>

在这里插入图片描述

3、样式属性操作

通过JS修改元素的大小,颜色,位置等样式 。

1,element.style 行内样式操作

2、element.className 类名样式操作

注意:

JS里面的样式采取驼峰命名法,比如 fontSize、backgroundColor

JS修改style样式操作,产生的是行内样式,CSS权重比较高。

如果样式较多,可以采取操作类名的方式更改元素的样式

class因为是个保留字,因此使用className来操作元素类名属性

className 会直接更改元素的类名,会覆盖原先的类名。(如果要保留原来的类名需要在原来的基础上再添加新的类名)。

<style>
      div {
        width: 600px;
        margin: 100px auto;
      }
      .message {
        display: inline-block;
        font-size: 12px;
        color: #999;
        background: url(images/mess.png) no-repeat left center;
        padding-left: 20px;
      }
      .wrong {
        color: red;
        background-image: url(images/wrong.png);
      }
      .right {
        color: green;
        background-image: url(images/right.png);
      }
    </style>
  </head>
  <body>
    <div class="register">
      <input type="password" class="ipt" />
      <p class="message">请输入6~16位密码</p>
    </div>
    <script>
      //1、首先判断的事件是表单失去焦点 onblur
      //2、如果输入正确则提示正确的提示信息颜色为绿色小图标的变化
      //3、如果输入的不是6-16 位,则提示错误信息颜色为红色 小图标的变化
      // 4、因为里面变化样式较多,我们采取className修改样式
      // 获取元素
      var ipt = document.querySelector('.ipt');
      var message = document.querySelector('.message');
      //注册事件
      ipt.onblur = function () {
        if (ipt.value.length < 6 || ipt.value.length > 16) {
          //  console.log('错误');
          message.className = 'message wrong';
          message.innerHTML = '输入的位数错误';
        } else {
          message.className = 'message right';
          message.innerHTML = '输入格式正确';
        }
      };
    </script>
  </body>

在这里插入图片描述

在这里插入图片描述

4、操作元素

操作元素总结:

操作元素:1、操作元素内容(innerText,innerHTML)2、操作常见的元素属性(src,href,title,alt)3、操作表单元素属性(type,value,disabled)4、操作元素样式属性(element.style , className)

自定义属性操作:

获取属性值:

element.属性 获取内置的属性(元素本身自带的属性)

element.getAttribute(‘属性’); 主要获得自定义的属性(标准) 程序员自定义的属性

设置属性值:

(1)element.属性 = ‘值’ 设置内置属性

(2) element.setAttribute(‘属性’,‘值’);主要针对自定义属性

(3)移出属性 removeAttribute(‘属性’);

   <div id="demo" index="12" class="nav"></div>
  <script>
  var div = document.querySelector('div');
   div.className = 'navs';

   div.setAttribute('index', '90');

   div.setAttribute('class', 'navs'); *//class 特殊  这里写的是class 不是className*
   <script/>

在这里插入图片描述

H5自定义属性:

自定义属性的目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。

自定义属性获取是通过getAttribute(‘属性’) 获取。

但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。

H5给我们新增了自定义属性:

设置H5自定义属性:

H5规定自定义属性data-开头做为属性名并且赋值。

比如<div data-index= '1'></div>或者使用JS设置element.setAttribute(‘data-index’,2);

获取H5自定义属性:

1,兼容性获取 element.getAttribute(‘data-index’);

2、H5新增element.dataset.index 或者 element.dataset[‘index’] ie 11才开始支持。

// H5新增的获取自定义属性的方法 它只能获取data-开头的

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

四、节点操作

获取元素通常使用两种方式:

1、利用DOM提供的方法获取元素

  • document.getElementByid()

  • document.getElementByTagName()

  • document.querySelector 等

    逻辑性不强,比较繁琐

2、利用节点层级关系获取元素

  • 利用父子兄弟节点关系获取元素
  • 逻辑性强,但是兼容性稍微差

这两种方式都可以获取元素节点,我们后面都会使用,但是节点操作更简单

节点概述 :

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node来表示。

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

**一般的,**节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性

元素节点 nodeType 为 1

属性节点 nodeType 为 2

文本节点 nodeType 为 3(文本节点包含文字、空格、换行等)

实际开发中,节点操作主要操作的是元素节点。

节点层级:

利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄弟层级关系

1、父级节点:

node.parentNode

  • parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
  • 如果指定的节点没有父节点则返回null
2、子节点:

parentNode.childNodes(标准)子节点

parentNode.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合。

注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等。 在IE8及以下的浏览器中,不会将空白文本当成子节点。

如果只想获得里面的元素节点,则需要专门的处理,所以我们一般不提倡使用childNodes

  //1,parentNode.childNodes(标准)子节点
      //   childNodes 所有有的子节点  包含 元素节点 文本节点等等
      console.log(ul.childNodes);
      var ul = document.querySelector('ul');
      for (var i = 0; i < ul.childNodes.length; i++) {
        if (ul.childNodes[i].nodeType == 1) {
          console.log(ul.childNodes[i]);
        }
      }

parentNode.children(非标准)(重点使用)

是一个只读的属性,返回所有的子元素节点。它只返回了元素节点,其余节点不返回(重点掌握)

虽然children是一个非标准, 但是得到了各个浏览器的支持,因此我们可以放心使用。

parentNode.firstChild :返回的是第一个子节点,找不到则返回null * ( 同样,也是包含所有的节点)*

parentNode.firstElementChild 返回最后一个子元素节点,找不到则返回null

**注意:**这两个方法有兼容性问题,IE9 以上才支持。

// 3.实际开发中的写法 既没有兼容性问题又返回第一个子元素

console.log(ol.children[ol.children.length - 1]); //得到最后一个元素

3、兄弟节点:

1、node.nextSibling 返回的是当前元素的下一个兄弟节点,找不到返回null。同样,也包含所有的节点

2、node.previousSibling 返回当前元素的上一个兄弟节点,找不到 返回null。 同样,也包含所有的节点

3、node.nextELementSibling 返回的是当前元素的下一个兄弟节点,找不到返回null(IE9 以上)

//处理兼容性问题: 封装一个兼容性的函数
 function getNextElementSibling(element) {
        var el = element;
        while ((el = el.nextSibling)) {
          if (el.nodeType === 1) {
            return el;
          }
        }
        return null;
      }
4、创建节点

核心:先创建再添加

document,createElement(‘tagName’)

此方法创建是由tagName指定的HTML元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以也称动态创建元素节点。

添加节点:

1、node.appendChild(child);

此方法将一个节点添加到指定父节点的子节点列表末尾。类似于CSS里面的after伪元素。

2、node.insertBefore(child,指定元素)

此方法将一个节点添加到父节点的指定节点前面。类似于CSS里面的before伪元素。

<body>
    <ul>
      <li>666</li>
    </ul>
    <script>
      // 1,创建节点: 元素节点
      var li = document.createElement('li');
      //  2、 添加节点  node.appendCholed(child)  node 父级 child 子级  后面追加元素
      var ul = document.querySelector('ul');
      ul.appendChild(li);
      //   3、添加节点 node.insertBefore(child,指定元素)
      var lili = document.createElement('li');
      ul.insertBefore(lili, ul.children[0]);
    //   4、添加一个元素: 先创建再添加
    </script>
  </body>
5、删除节点

node.removeChild(child);

此方法从DOM中删除一个子节点,返回删除的节点。

6、复制节点

node.cloneNode();

此方法返回调用该方法的节点的一个副本,也称为克隆节点。

注意:如果括号参数为空或者为false,则是浅拷贝,即只有克隆复制节点本身,不克隆里面的子节点。

​ 如果括号里面为true,则为深拷贝。复制里面的内容。

节点操作:

三种动态节点创建元素的区别:

document.write()

是直接将内容写入到页面的内容流,但是文档流执行完毕之后,它会导致页面全部重绘

 // 整个页面加载完之后才会执行JS
      window.onload = function () {
        document.write('<div>123</div>');
      };
 // 1、document.write() 创建元素 如果页面文档流加载完毕,再调用这句话会导致页面重绘

      /*      var btn = document.querySelector('button');
      btn.onclick = function () {
        document.write('<div>123</div>');
      }; */

element.innerHTML:

innerHTML 是将内容写入某个DOM的节点,不会导致页面全部重绘

innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接 ,需要把数组转换为字符串),结构稍微复杂

document.createElement():

createElement() 创建多个元素效率稍微低一点点,但是结构更加清晰。

7、替换节点

replaceChild(); 可以使用指定的子节点替换已有的子节点

语法:父节点.replaceChild(新节点,旧节点);

8、DOM的重点核心:

主要针对于元素的操作:

  • 创建 (document.write(),element.innerHTML,document.createElement())

  • (appendChild,insertBefore)、

  • (removeChild)、

  • (1、修改属性:src、href、title等,2、 修改普通元素内容:innerHTML、innerText 3、修改表单元素:value、type,disabled等 4、修改元素样式:style,className)

  • (主要获取查询DOM元素:1、DOM提供的API方法:getElementById,getElementByTagName,古老方法不太推荐。

    2、H5提供的新增的方法:ququerySelector,ququerySelectorAll 提倡使用 3、利用节点操作来获取元素:父(parentNode),子(children),兄(previousElementSibling ,nextElementSibling)提倡使用)

  • 属性操作 (主要针对自定义属性: 1、setAttribute:设置dom的属性值 2、getAttribute:得到dom的属性值 3、removeAttribute:移出属性)

  • 事件操作

给元素注册事件,采取 事件源.事件类型 = 事件处理程序

鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
onmouseout鼠标离开触发
onfocus获得鼠标焦点触发
onblur失去鼠标焦点触发
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发

五、事件高级

  • 能够写出元素注册事件的两种方式
  • 能够说出删除事件的两种方式
  • 能够说出DOM事件流的三个阶段
  • 能够利用事件对象完成跟随鼠标案例
  • 能够封装组织冒泡的兼容性函数
  • 能够说出事件委托的原理
  • 能够说出常用的鼠标和键盘事件

学习流程:

1、注册事件(绑定事件)2、删除事件(解绑事件)3、DOM事件流 4、事件对象 5、阻止事件冒泡 6、事件委托(代理 、委派)7、 常用的鼠标事件 8、常用的键盘事件

1、注册事件

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

传统注册方式:

  • 利用on开头的事件 onclick
  • <button onclick= "alert('hi~')"></button>
  • btn.onclick = function(){}
  • 特点:注册事件的唯一性
  • 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数

方法监听注册方式:

  • W3C标准 推荐方式
  • addEventListener() 是一个方法
  • IE9 之前不支持,可使用 attachEvent() 代替(该特性非标准的,请尽量不要在生产环境中使用它!)
  • 特点:同一个元素同一个事件可以注册多个监听器
  • 按注册顺序依次执行

eventTarget.addEventListener('type',listener[,useCapture])

eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。

该方法接收三个参数:

type:事件类型字符串(必须添加引号),比如click、mouseover,注意这里不带on

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

‘useCapture’:可选参数,是一个布尔值,默认是false。学完DOM事件流后,再进行下一步学习。

attachEvent 事件监听方式

eventTarget.attachEvent(eventNameWithOn,callback)

eventTarget.attachEvent() 方法是将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行。

该方法接收两个参数:

eventNameWithOn :事件类型字符串,比如onclick、onmouseover,这里要带on

callback : 事件处理函数,当目标触发事件时回调函数被调用。

 // 3,attachEvent()  ie9 以前的版本才支持
      attachEvent('onclick', function () {
        alert('123');
      });

注册事件兼容性解决方案:

 function addEventListener(element, eventName, fn) {
        // 判断当前浏览器是否支持 addEventListener 方法
        if (element.addEventListener) {
          element.addEventListener(element, fn); //第三个参数  默认的是false
        } else if (element.attachEvent) {
          element.attachEvent('on' + eventName, fn);
        } else {
          // 相当于 element.onclick = fn;
          element['on' + eventName] = fn;
        }
      }

兼容性处理原则;首先照顾大多数浏览器,再处理特殊浏览器。

2、删除事件

删除事件的方式:

(1)传统注册方式

eventTarget.onclick = null;

(2)方法监听注册方式

eventTarget.removeEventListener(type, listener[, useCapture]);

eventTarget.detachEvent (eventNameWithOn, callback);

<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        // 点击一次之后再点击就不会提示
      var div = document.querySelectorAll('div');
      for (var i = 0; i < div.length; i++) {
        // 1、传统的方式解绑
        /* div[i].onclick = function () {
          alert('haha');
          this.onclick = null; //解绑事件
        }; */
        // 2、添加监听器的方式解绑
        /*    div[i].addEventListener('click', fn);
        function fn() {
          alert('haha');
          this.removeEventListener('click', fn);
        } */
        // 3、
        div[i].attachEvent('onclick', fn1);
        function fn1() {
          alert('666');
          this.detachEvent('onclick', fn1);
        }
      }
    </script>
  </body>
3、DOM事件流

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

DOM事件流分为三个阶段,分别为:

捕获阶段:事件从Document节点自上而下向目标节点传播的阶段;

目标阶段:真正的目标节点正在处理事件的阶段;

冒泡阶段:事件从目标节点自上而下向Document节点传播的阶段。

img

注意:

1、JS代码只能执行捕获或者冒泡其中一个阶段(要么是捕获要么是冒泡)

2、onclick和attachEvent(ie)只能得到冒泡阶段

3、addEventListener(type, listener[, useCapture]) 第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认是false),表示在事件冒泡阶段调用事件处理程序

4、实际开发中,我们很少使用事件捕获,我们更关注事件冒泡

5、有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave

6、事件的冒泡有时会带来麻烦,不过是可以被阻止的,方法是:stopPropagation()

stopPropagation() 方法:终止事件在传播过程的捕获、目标处理或冒泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。

4、事件对象

官方解释:event对象代表事件的状态,比如键盘按键的状态,鼠标的位置,鼠标按钮的状态。

简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,它有很多属性和方法:

比如:

1.谁绑定了这个事件

2.鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。

2.键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。

<style>
      div {
        width: 100px;
        height: 100px;
        background-color: pink;
      }
    </style>
  </head>
  <body>
    <div>123</div>
    <script>
      var div = document.querySelector('div');
      //   传统方式:
      /*  div.onclick = function (event) {
        console.log(event);
      }; */
      //   处理IE678,兼容性写法
      div.onclick = function (e) {
        console.log(e);
        e = e || window.event;
      };
      //   使用监听器
      div.addEventListener('click', function (event) {
        console.log(event);
      });
      /* 
      1、event 就是一个事件对象,写在侦听函数的  小括号里面 当形参来看
      2、事件对象只有有了事件才会存在,它是系统为我们自动创建的,不需要我们来传递参数
      3、事件对象  是 我们事件的一系列相关数据的集合,跟事件相关的  
         比如,鼠标点击里面就包含了鼠标的相关信息 ,鼠标坐标,如果是键盘事件里面就包含了键盘事件的信息
      4、事件对象 可以自己命名  比如:event,evt,e
      5、事件对象也有兼容性问题   IE678 通过 window.event 兼容性的写法  e = e || window.event;  */
    </script>
  </body>

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

事件对象属性方法说明
e.target返回触发事件的对象 标准
e.srcElement返回触发事件的对象 非标准 IE678使用
e.type返回事件类型 比如click mouseover 不带on
e.canceIBubble该属性阻止冒泡 非标准 IE678使用
e.returnValue该属性 阻止默认事件(默认行为)非标准 IE678使用 比如不让链接跳转
e.preventDefault()该方法 阻止默认事件(默认行为)标准 比如不让链接跳转
e.stopPropagation阻止冒泡 标准
 <body>
    <div>123</div>
    <ul>
      <li>abc</li>
      <li>abc</li>
      <li>abc</li>
    </ul>
    <script>
      //常见的事件属性和方法
      //   1、e.target返回的是触发事件的对象(元素) this返回的是绑定事件的对象(元素)
      // 区别:e.target 点击了哪个元素,就返回哪个元素。this 谁绑定了这个点击事件,就返回谁。
      var div = document.querySelector('div');
      div.addEventListener('click', function (e) {
        console.log(e.target);
        console.log(this);
      });
      var ul = document.querySelector('ul');
      ul.addEventListener('click', function (e) {
        // 给ul绑定了是事件,那么 this 就指向ul
        console.log(this);
        console.log(e.currentTarget);
        // e.traget  指向的点击的那个对象  谁触发了这个事件 当前点击的是  li  e.traget  指向的就是li
        console.log(e.target);
      });
      //   处理IE678 兼容性  了解
      /*  div.onclick = function (e) {
        e = e || window.event;
        var traget = e.traget || e.srcElement;
        console.log(traget);
      }; */
      //   了解,跟this 有个非常相似的属性  currentTarget ie678不认识
    </script>
  </body>

在这里插入图片描述

<body>
    <div>123</div>
    <a href="http://www.baidu.com">百度</a>
    <form action="http://www.baidu.com">
      <input type="submit" value="提交" name="sub" />
    </form>
    <script>
      // 返回事件类型
      var div = document.querySelector('div');
      div.addEventListener('click', fn);
      div.addEventListener('mouseover', fn);
      div.addEventListener('mouseout', fn);
      function fn(e) {
        console.log(e.type);
      }
      //   2、阻止默认事件
      var a = document.querySelector('a');
      a.addEventListener('click', fn1);
      function fn1(e) {
        e.preventDefault(e); //dom推荐的写法
      }
      //   3、传统的注册方式
      a.onclick = function (e) {
        // 普通浏览器  e.preventDefault();
        // e.preventDefault(e);
        // 低版本浏览器  IE678
        // e.returnValue;
        // 可以利用return false 也能阻止默认行为 没有兼容性问题
        return false; //return  后面的代码不执行了而且只限于传统的注册方式
      };
    </script>
  </body>
5、阻止事件冒泡

组织事件冒泡的两种方式:

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点。

实现代码:

$("#three").click(function(event) {
      event.stopPropagation();
  });

a.写入event.stopPropagation(); 停止传播

事件处理过程中,阻止了事件冒泡,但不会阻止默认行为

e.cancelBubble = true; //取消冒泡 支持IE678

阻止事件冒泡的兼容性解决方案:

if (e && e.stopPropagation){
    e.stopPropagation();
}else {
    window.event.cancelBubble = true;
}

b.写入return false;

事件处理过程中,阻止了事件冒泡,也阻止了默认行为

c.写入event.preventDefault();

事件处理过程中,不阻止事件冒泡,但阻止默认行为

6、事件委托(代理 、委派)

事件冒泡本身的特性,会带来坏处,也会带来害处,需要我们灵活掌握。

事件委托的原理:

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

事件委托的作用:

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

<body>
    <ul>
      <li>地狱魔爵人</li>
      <li>地狱魔爵人</li>
      <li>地狱魔爵人</li>
    </ul>
    <!-- 点击每个li都会弹出对话框,以前,需要给每一个li注册事件,
        而且访问DOM的次数越多,就会延长整个页面的交互就绪时间 

    给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,
    因为点击li,事件会冒泡到ul上, ul有注册事件就会触发事件监听器-->
    <script>
      var ul = document.querySelector('ul');
      ul.addEventListener('click', function (e) {
        alert(e.target.innerHTML);
        // e.target 可以得到点击的对象
        console.log(e.target);
        e.target.style.background = 'pink';
      });
    </script>
  </body>
7、 常用的鼠标事件

1、禁止鼠标右键菜单

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

禁止鼠标选中

(selectstart 开始选中)

 <body>
    一行不愿意分享的文字;
    <script>
      // 禁止鼠标右键
      document.addEventListener('contextmenu', function (e) {
        e.preventDefault();
      });
      //   禁止选中文字 selectstart
      document.addEventListener('selectstart', function (e) {
        e.preventDefault();
      });
    </script>
  </body>

2、鼠标事件对象

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

鼠标事件对象说明
e.clientX返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX返回鼠标相对于文档页面的X坐标 IE9+ 支持
e.pageY返回鼠标相对于文档页面的Y坐标 IE9+ 支持
e.screenX返回鼠标相对于电脑屏幕的X坐标
e.screenY返回鼠标相对于电脑屏幕的Y坐标
 <style>
      img {
        position: absolute;
      }
    </style>
  </head>
  <body>
    <img src="images/angel.gif" alt="" />
    <script>
      /* 1、鼠标不断移动,使用鼠标移动事件
        2、在页面中移动,给document注册事件
        3、图片要移动距离,而且不占用位置,要使用绝对定位
        4、核心原理:每次鼠标移动,我们会获得最新的鼠标坐标,把这个X和Y坐标做为图片的top和left值就可以移动图片 */
      var pic = document.querySelector('img');
      document.addEventListener('mousemove', function (e) {
        var x = e.clientX;
        var y = e.clientY;
        // 千万不要给left top 添加 px 单位
        pic.style.left = x - 30 + 'px';
        pic.style.top = y - 40 + 'px';
      });
    </script>
  </body>

在这里插入图片描述

8、常用的键盘事件
键盘事件触发条件
onkeyup某个键盘按键被松开时触发
onkeydown某个键盘按键被按下时触发
onkeypress某个键盘按键 被按下时触发 但是它不识别功能按键 比如 ctrl shift 箭头等
   <script>
      // 1、keyup 按键弹起时触发
      document.addEventListener('keyup', function () {
        console.log('弹起up');
      });
      // 3、onkeypress某个键盘按键 被按下时触发  但是它不识别功能按键  比如 ctrl shift 箭头等
      document.addEventListener('keypress', function () {
        console.log('按下press');
      });
      // 2、onkeydown某个键盘按键被按下时触发 能够识别功能键
      document.addEventListener('keydown', function () {
        console.log('按下down');
      });
      // 4、三个事件的执行顺序  keydown  keypress  keyup
    </script>

键盘事件对象:

 <script>
      // 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
      document.addEventListener('keyup', function (e) {
        console.log('up' + e.keyCode);
        // 判断用户按下了哪个键
        if (e.keyCode === 65) {
          alert('您按下的a键');
        }
      });
      //   1、keyup 和 keydown 事件不区分字母的大小写  a和A得到的都是65
      //   2、keypress  事件区分大小写  a 97  A 65
      document.addEventListener('keypress', function (e) {
        console.log('press' + e.keyCode);
      });
    </script>

大小规则

常见ASCII码的大小规则:数字< 大写字母 < 小写字母。

1.数字比字母要小。如 “7”<“F”;

2.数字0比数字9要小,并按0到9顺序递增。如 “3”<“8” ;

3.字母A比字母Z要小,并按A到Z顺序递增。如“A”<“Z” ;

4.同个字母的大写字母比小写字母要小32。如“A”<“a” 。

几个常见字母的ASCII码大小: “A”为65;“a”为97;“0”为 48 [4] 。

六、BOM浏览器对象模型

能够说出什么是DOM

能够知道浏览器的顶级对象

能够写出页面加载事件以及注意事项

能够写出两种定时器函数并说出区别

能够说出JS执行机制

能够使用location对象完成页面之间的跳转

能够知晓navigator对象涉及的属性

能够使用history提供的方法实现页面的刷新

1、BOM概述:

BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。

BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。

BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C,BOM最初是Netscape浏览器标准的一部分。

window包括:document,location,navigation,screen,history

1.1、BOM的构成

window对象 是浏览器的顶级对象,它具有双重角色。

它是JS访问浏览器的一个接口。

它是一个全局对象定义一个全局作用域的变量、函数都会变成window对象的属性和方法。在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如alert()、prompt()等。

**注意:**window下的一个特殊属性window.name

2、window对象的常见事件
window.onload = function(){}
或者
window.addEventListener("load",function(){});

1、window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等)就调用的处理函数。

2、window.onload 传统注册事件只能写一次,如果有多个,会以最后一个window.onload为准。

3、如果使用addEventListener则没有限制。

2.1窗口加载事件:
document.addEventListener('DOMContentLoaded',function(){})

DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。(IE9以上支持)

如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoaded事件比较适合。

2.2调整窗口大小事件
window.onresize = function(){}
wondow.addEventListener('resize',function(){})

window.onresize 是调整窗口大小的加载事件,当触发时就调用的处理函数。

注意:

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

我们经常利用这个事件完成响应式布局。window.innerWidth 当前屏幕宽度

3、定时器

window对象给我们提供2个非常好用的方法-定时器。

3.1 setTimeout()
window.setTimeout(调用函数,[延迟的毫秒数]);

<script>
      window.addEventListener('load', function () {
        // setTimeout语法规范:  window.setTimeout('调用函数',延迟时间);
        // 1、window在调用时可以省略
        // 2、这个延迟时间单位是毫秒数,但是可以省略,如果不省略默认的是0

        /* setTimeout(function () {
          console.log('时间到了');
        }, 2000); */
        // 3、这个调用函数可以直接写函数 还可以写 函数名  还有一个写法  '函数名()'
        // 4、页面中可能有很多的定时器,我们经常给定时器添加标识符用于区别不同的定时器 (名字)
        function callback() {
          console.log('爆炸了');
        }
        var timer1 = setTimeout(callback, 2000);
        var timer2 = setTimeout(callback, 5000);
        // setTimeout('callback()', 2000);//不提倡此写法
      });
    </script>

setTimeout() 方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。

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

普通函数是按照代码顺序直接调用

而这个函数,需要等待时间,时间到了才会去调用这个函数,因此称为回调函数。

之前讲的 element.onclick = function(){} 或者 element.addEventListener(“click”,fn); 里面的 函数也是回调函数。

清除定时器:

window.clearTimeout(timeout ID)

clearTimeout()方法取消了先前的调用 setTimeout() 建立的定时器。

<script>
      window.addEventListener('load', function () {
        var btn = document.querySelector('button');
        function callback() {
          console.log('爆炸');
        }
        var timer = setTimeout(callback, 4000);
        btn.addEventListener('click', function () {
          // window可以省略  里面的参数就是定时器的标识符
          window.clearTimeout(timer);
        });
      });
    </script>
3.2 setInterval()

setInterval()方法重复调用一个函数,每隔这个时间,就去调用一次回调函数。

window.setInterval(回调函数,[间隔的毫秒数]);

 <script>
      window.addEventListener('load', function () {
        /* 语法规范:setInterval(调用函数,延时时间) */
        var timer = setInterval(function () {
          console.log('傻逼');
        }, 1000);
        // setTimeout  延时时间到了就去调用这个函数,只调用一次就结束了这个定时器
        // setInterval  每隔这个延时时间就会去调用一次函数,重复性的调用此函数
      });
 </script>

停止setInterval()定时器

clearInterval()方法取消了先前通过setInterval()建立的定时器。

window.clearInterval(intervalID);

<body>
    <script>
      window.addEventListener('load', function () {
        var begin = document.querySelector('.begin');
        var stop = document.querySelector('.stop');
        // 全局变量  null是一个空对象
        var Timer = null;
        begin.addEventListener('click', function () {
          Timer = setInterval(function () {
            console.log('大大的');
          }, 1000);
        });
        stop.addEventListener('click', function () {
          clearInterval(Timer);
        });
      });
    </script>
    <button class="begin">开启定时器</button>
    <button class="stop">停止定时器</button>
  </body>
3.3 this

​ this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象。

4、JS执行机制
4.1 JS 是单线程

​ JS语言的一大特点就是单线程,也就是说,同一时间只能做一件事。这是因为JS这门脚本语言诞生的使命所致------JS是为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。应该先进行添加,之后再删除。

​ 单线程就意味着,所有的任务需要排队,前一个任务结束,才会执行后一个任务,这样导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

4.2 同步和异步
  // 第一个问题
      console.log(1);
      setTimeout(function () {
        console.log(3); //执行时间比较长
      }, 1000);
      console.log(2);
      // 结果:1 2 3

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

**同步:**前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的,同步的。

**异步:**做一件事情的同时还可以做其他事情。

本质区别:在一条流水线上各个流程执行的顺序是不同的。

同步任务:同步任务都在主线程上执行,形成一条执行线。

**异步任务:**JS的异步是通过回调函数实现的。 一般而言,异步任务有以下三种类型:

  1. 普通事件,如click、resize等

  2. 资源加载,如load、error等

  3. 定时器,包括setInterval、setTimeout等

    异步任务相关回调函数添加到任务队列中(任务队列也称消息队列)。

4.3 执行机制

先执行执行栈中的同步任务。

异步任务(回调函数)放入到任务队列中。

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

在这里插入图片描述

在这里插入图片描述

5、location对象

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

​ URL: 统一资源定位符(Uniform Resource Location,URL)是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

URL的一般语法格式为:

protocol://host[:port]/path/[?query]#fragment
http://www.itcast,cn/index.html?name=andy&age=18#link

组成说明
protocol通信协议 常用的http,ftp,maito等
host主机( 域名)www.itheima.com
port端口号 可选,省略时使用方案的默认端口 如http的默认端口为80
path路径 由 零或者多个’/'符号隔开的字符串,一般用来表示主机上一个目录或者文件地址
query参数 以键值对的形式,通过&符号分隔开来
fragment片段 #后面内容 常见于链接 锚点
5.1 location对象的属性
location对象属性返回值
location.href获取或者设置 整个URL
location.host返回主机(域名)www.itheima.com
location.port返回端口号 如果未返回 空字符串
location.pathname返回路径
location.search返回参数
location.hash返回片段 #后面内容 常见于链接 锚点
   //login.html页面
   <form action="index.html">
      用户名:<input type="text" name="uname" />
      <input type="submit" value="登录" />
    </form>
    
   //index.html页面
 <body>
    <div></div>
    <script>
      //   console.log(location.search); //?uname=andy
      //   1、先去掉?字符串截取  substring(start,end)
      var params = location.search.substring(1);
      console.log(params);//uname=andy
      //   2、利用=把字符串分隔成为数组 split('=')
      var arr = params.split('=');
      console.log(arr); //['uname', 'andy']
      var unameArr = arr[1];
      var div = document.querySelector('div');
      div.innerHTML = '欢迎' + unameArr + '进入';
    </script>
  </body>
5.2 location对象的方法
location对象方法返回值
location.assign()跟href一样,可以跳转页面(也称为重定向页面)记录历史
location.replace()替换当前页面,因为不记录历史,所以不能后退页面
location.reload()重新加载页面,相当于刷新按钮或者 F5 如果参数为true 强制刷新ctrl+f5
6、navigator对象

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

下面前端代码判断用户那个终端打开页面,实现跳转。

             
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
            window.location.href = ''; // 手机端页面链接
        } else {
            window.location.href = ''; // PC端页面
        }
7、history对象

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

history对象方法作用
back()可以后退功能
forward()前进功能
go(参数)前进后退功能 参数如果是1 前进一个页面 如果是-1 后退一个页面
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Magin_Baron

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值