JavaScript基础--DOM部分01--李南江

目录

一、DOM 简介    ​

二、如何获取DOM元素

1.获取DOM元素(标签)

2.获取子元素与子节点

三、如何操作DOM元素

1.操作元素

2.操作元素属性

3.操作元素内容

4.操作元素样式

四、DOM事件与定时器

1.DOM事件

2.定时器


一、DOM 简介

  • 1.什么是window?
    • window:是一个全局对象,代表浏览器中一个打开的窗口,每个窗口都是一个window对象
  • 2.什么是document?
    • document:是window的一个属性, 这个属性是一个对象,代表当前窗口中的整个网页内容
    • document对象:保存了网页上所有的内容,通过document对象就可以操作网页上的内容
  • 3.什么是DOM?
    • DOM 定义了访问和操作 HTML文档(网页)的标准方法
    • DOM全称:Document Object Model, 即文档模型对象,所以学习DOM,就是学习如何通过document对象操作网页上的内容
    •         console.log(window.document);
              console.log(typeof window.document);
              console.log(window.document.title);
    • 在JavaScript中HTML标签也称之为DOM元素
    • 使用document的时候,前面可以不用加 window
    •         var num = 1;
              console.log(window.num);
              console.log(num);
              // window 可以省略
              console.log(window.document);
              console.log(document); 

          

二、如何获取DOM元素

1.获取DOM元素(标签)

  • 1.通过 id 获取指定元素
    • document.getElementById()
    • 由于 id 不可以重复, 所以找到了就会将找到的标签包装成一个对象返回给我们, 找不到就返回 Null
    • 注意点:DOM 操作返回的是一个对象, 这个对象是宿主类型对象(浏览器提供的对象)
<div class="father">
    <form>
        <input type="text" name="test">
        <input type="password" name="test">
    </form>
</div>
<div class="father" id="box">我是div</div>
    let oDiv = document.getElementById("box");
    console.log(oDiv);
    console.log(typeof oDiv);

  • 2.通过 class 名称获取
    • document.getElementsByClassName()
    • 由于 class 可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
    let oDivs = document.getElementsByClassName("father");
    console.log(oDivs);

  • 3.通过 name 名称获取
    • document.getElementsByName()
    • 由于 name 可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组.
    • 注意点:getElementsByName  在不同的浏览器其中工作方式不同。在IE和Opera中, getElementsByName()  方法还会返回那些 id 为指定值的元素。
    let oDivs = document.getElementsByName("test");
    console.log(oDivs);

  • 4.通过 标签名称 获取
    • document.getElementsByTagName()
    • 由于标签名称可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
    let oDivs =  document.getElementsByTagName("div");
    console.log(oDivs);

  • 5.通过 选择器 获取
  • 5.1 第一种
    • document.querySelector()
    • querySelector 只会返回根据指定选择器,找到的第一个元素
    // let oDiv = document.querySelector("#box");
    // let oDiv = document.querySelector(".father");
    let oDiv = document.querySelector("div>form");
    console.log(oDiv);

  • 5.2 第二种
    • document.querySelectorAll()

    • querySelectorAll 会返回指定选择器找到的所有元素
    let oDivs = document.querySelectorAll(".father");
    console.log(oDivs);

2.获取子元素与子节点

  • 什么是节点
    • DOM对象(document), 这个对象以树的形式保存了界面上所有的内容
    • HTML页面每一部分都是由节点(标签/元素、文本、属性)组成的
  • DOM 树

1.获取指定元素的所有子元素(标签)

<div>
    <h1>1</h1>
    <h2>2</h2>
    <p class="item">3</p>
    <p>4</p>
    <span>5</span>
</div>
    let oDiv = document.querySelector("div");
    // children属性:获取到的是指定元素中所有的子元素
    console.log(oDiv.children);

2.获取指定元素所有的子节点(标签+文本+属性)

    let oDiv = document.querySelector("div");
    // childNodes属性:获取到的是指定元素中所有的子节点
    console.log(oDiv.childNodes);

 

3.获取指定元素所有的子元素内容(标签+内容)

    // 获取所有子元素内容(标签内容)
    // 方式1
    for (let node of oDiv.childNodes) {
        // console.log(node.nodeType);
        // if(node.nodeType === 1){
        if (node.nodeType === Node.ELEMENT_NODE) {
            console.log(node);
        }
    }
    // 方式2
    for(let node of oDiv1.children){
       console.log(node);
    } 

4.获取指定节点中的第一个子节点与子元素

    let oDiv = document.querySelector("div");
    // 获取指定节点中的第一个子节点
    console.log(oDiv.firstChild);
    // 获取指定元素中的第一个子元素
    console.log(oDiv.firstElementChild);

5.获取指定节点中的最后一个子节点与子元素

    let oDiv = document.querySelector("div");
    // 获取指定节点中最后一个子节点
    console.log(oDiv.lastChild);
    // 获取指定元素中最后一个子元素
    console.log(oDiv.lastElementChild);

6.通过子元素获取父元素与父节点

    let item = document.querySelector(".item");
    // 通过子元素获取父元素
    console.log(item.parentElement);
    // 通过子元素获取父节点
    console.log(item.parentNode);
    // 提高兼容性的写法(ES6之前火狐不支持parentElement)
    let parentEle = item.parentElement || item.parentNode;
    console.log(parentEle);

7.获取指定节点中相邻上一个节点与元素

    let item = document.querySelector(".item");
    // 获取相邻上一个节点
    console.log(item.previousSibling);
    // 获取相邻上一个元素
    console.log(item.previousElementSibling);

8.获取指定节点中相邻下一个节点与元素

    let item = document.querySelector(".item");
    // 获取相邻下一个节点
    console.log(item.nextSibling);
    // 获取相邻下一个元素
    console.log(item.nextElementSibling);

三、如何操作DOM元素

1.操作元素

<div>
    <h1>我是标题</h1>
    <p>我是段落</p>
</div>
  • 1.创建元素
    • document.createElement()

    let oSpan = document.createElement("span");
    console.log(oSpan);
    console.log(typeof oSpan);

  • 2.添加元素
    • appendChild()
    • 默认添加到最后面
    let oSpan = document.createElement("span");
    let oDiv = document.querySelector("div");
    oDiv.appendChild(oSpan)
    let oA = document.createElement("a");
    oDiv.appendChild(oA);

  • 3.插入元素
    • insertBefore()

    • 可以插入到任意位置

    let oSpan = document.createElement("span");
    let oDiv = document.querySelector("div");
    let oH1 = document.querySelector("h1");
    let oP = document.querySelector("p");
    // oDiv.insertBefore(oSpan, oH1);
    oDiv.insertBefore(oSpan, oP);

  • 4.删除元素
    • removeChild()
    • 在js中如果想要删除某一个元素, 只能通过对应的父元素来删除,元素是不能够自删的
    // let oSpan = document.createElement("span");
    // console.log(oSpan.parentNode);
    // oSpan.parentNode.removeChild(oSpan);    // Uncaught TypeError: Cannot read property 'removeChild' of null
    let oDiv = document.querySelector("div");
    console.log(oDiv.parentNode);
    oDiv.parentNode.removeChild(oDiv);

    console.log(oH1.parentNode);
    oDiv.removeChild(oH1);

  • 5.克隆元素
    • cloneNode()

    • 注意点:cloneNode方法默认不会克隆子元素, 如果想克隆子元素需要传递一个 true

    let oDiv = document.querySelector("div");
    // let newDiv =  oDiv.cloneNode();
    let newDiv =  oDiv.cloneNode(true);
    console.log(newDiv);

2.操作元素属性

  • 无论是通过 document 创建,还是查询出来的标签,系统都会将元素包装成一个对象返回给我们
  • 系统在包装这个对象的时候会自动将元素的属性都包装到这个对象中,所以只要拿到这个对象就可以拿到标签属性,操作标签属性
<img src="images/1.jpg" alt="我是alt222" title="我是title" nj="666">
    let oImg = document.querySelector("img");
    // let oImg = document.createElement("img");
    console.dir(oImg);

  • 1.如何获取元素属性
    • 对象.属性名称     (无法获取到自定义属性的取值)
    • getAttribute()      (可以获取到自定义属性的取值)
    let oImg = document.querySelector("img");
    // 方式1:
    // console.log(oImg.alt);
    // 方式2:
    // console.log(oImg.getAttribute("alt"));
    // 注意点: 通过 对象.属性名称 方式无法获取到自定义属性的取值
    //        通过 getAttribute 方式可以获取到自定义属性的取值
    console.log(oImg.nj);
    console.log(oImg.getAttribute("nj"));

  • 2.如何修改元素属性
    • 对象.属性名称 = 新的属性值                (无法获取到自定义属性的取值)
    • setAttribute(属性名称, 新的属性值)      (可以获取到自定义属性的取值)
    let oImg = document.querySelector("img");
    // 方式1:
    // oImg.title = "新的title";
    // 方式2:
    // oImg.setAttribute("title", "新的title222");
    // 注意点: 通过 对象.属性名称 方式无法修改到自定义属性的取值
    //        通过 setAttribute 方式可以获取到自定义属性的取值
    // oImg.nj = "123";
    oImg.setAttribute("nj", "123");
  • 3.如何新增元素属性
    •  setAttribute(属性名称, 属性值) 
    • 如果属性不存在就是新增,如果属性存在就是修改
    let oImg = document.querySelector("img");
    // oImg.it666 = "itzb";       //无法新增
    // 注意点: setAttribute方法如果属性不存在就是新增, 如果属性存在就是修改
    oImg.setAttribute("it666", "itzb");
  • 4.删除元素属性
    • 对象.属性名称=""             # 将属性的值置空                                      (无法清空自定义属性)

    • removeAttribute()            # 删除属性(包括属性名称与属性值)      (可以删除自定义属性)

    let oImg = document.querySelector("img");
    // 方式1:将属性的值置空
    // oImg.alt = "";    
    // 方式2:删除属性(包括属性名称与属性值)
    // oImg.removeAttribute("alt");
    // 注意点:通过 对象.属性名称="" 方式无法清空自定义属性的取值
    // 通过 removeAttribute 方式可以删除自定义属性
    // oImg.nj = "";
    oImg.removeAttribute("nj");

3.操作元素内容

  • 1.获取元素内容
    • 1.1 innerHTML 获取的内容包含标签,innerText / textContent 获取的内容不包含标签
    • 1.2 innerHTML / textContent 获取的内容不会去除两端的空格,innerText 获取的内容会去除两端的空格
<div>
    我是div
    <h1>我是标题</h1>
    <p>我是段落</p>
</div>
   let oDiv = document.querySelector("div");
   console.log(oDiv.innerHTML);
   console.log(oDiv.innerText);
   console.log(oDiv.textContent);

  • 2.设置元素内容
    • 特点
      • 无论通过 innerHTML / innerText / textContent 设置内容,新的内容都会覆盖原有的内容
    • 区别
      • 如果通过 innerHTML 设置数据,数据中包含标签,会转换成标签之后再添加
      • 如果通过 innerText / textContent 设置数据,数据中包含标签,不会转换成标签,会当做一个字符串直接设置
    let oDiv = document.querySelector("div");
    // oDiv.innerHTML = "123";
    // oDiv.innerText = "456";
    // oDiv.textContent = "789";

    oDiv.innerHTML = "<span>我是span</span>";
    // oDiv.innerText = "<span>我是span</span>";
    //  oDiv.textContent = "<span>我是span</span>";
  • 使用 innerText / textContent 数据中包含的标签,会当做一个字符串直接设置(解决浏览器兼容性)
    setText(oDiv, "www.it666.com");
    function setText(obj, text) {
        if("textContent" in obj){
            obj.textContent = text;
        }else{
            obj.innerText = text;
        }
    }

4.操作元素样式

  • 1.设置元素样式
  • 方式1:css设置样式
    <style>
        .box{
            width: 200px;
            height: 200px;
            background-color: red;
        }
    </style>

<div class="box"></div>
  • 方式2:className + CSS
    <style>
        .box{
            width: 200px;
            height: 200px;
            background-color: red;
        }
    </style>

<div> </div>

<script>
    let oDiv = document.querySelector("div");
    // 注意点: 由于class在JS中是一个关键字, 所以叫做className
    oDiv.className = "box";
</script>
  • 方式3:对象.style.属性名 = 属性值
    • 注意点:通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式
<div> </div>

<script>
    let oDiv = document.querySelector("div");
    // 注意点: 过去CSS中通过-连接的样式, 在JS中都是驼峰命名
    // 通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式
    oDiv.style.width = "300px";
    oDiv.style.height = "300px";
    oDiv.style.backgroundColor = "blue";
</script>

  • 2.获取元素样式
    • 对象.style.属性名            (只能过去到行内样式的属性值, 获取不到CSS设置的属性值)
    • window.getComputedStyle(对象).属性名称        (想要获取到CSS设置的属性值, 必须通过getComputedStyle方法来获取)
    <style>
        .box{
            width: 200px;
            height: 200px;
            background-color: red;
        }
    </style>

<div class="box"></div>
<script>
    let oDiv = document.querySelector("div");
    
    // oDiv.style.width = "300px";
    // 注意点: 通过style属性只能获取到行内样式的属性值, 获取不到CSS设置的属性值
    // console.log(oDiv.style.width);
    
    // 注意点: 如果想获取到CSS设置的属性值, 必须通过getComputedStyle方法来获取
    // getComputedStyle方法接收一个参数, 这个参数就是要获取的元素对象
    // getComputedStyle方法返回一个对象, 这个对象中就保存了CSS设置的样式和属性值
    let style = window.getComputedStyle(oDiv);
    console.log(style.width);
</script>

四、DOM事件与定时器

1.DOM事件

  • 1.什么是事件?
    • 用户浏览器之间的交互行为我们就称之为事件,比如:点击,移入/移出
  • 2.如何给元素绑定事件?
    • 在JavaScript中所有的HTML标签都可以添加事件
    • 元素.事件名称 = function(){};       # 当对应事件被触发时候就会自动执行function中的代码
<button>我是按钮</button>

<script>
    let oBtn = document.querySelector("button");
    oBtn.onclick = function () {
        alert("按钮被点击了");
    };
</script>

<a href="http://www.it666.com">我是a标签</a>

<script>
    // 注意点: 如果给元素添加了和系统同名的事件, 默认我们添加的事件不会覆盖系统添加的事件
    let oA = document.querySelector("a");
    oA.onclick = function () {
        alert("a标签被点击了");
        // 设置返回值为false后,我们添加的事件就会覆盖掉系统同名的事件
        return false;
    };
</script>

2.定时器

在JavaScript中有两种定时器,一种是重复执行的定时器,一种是只执行一次的定时器

  • 1.重复执行的定时器
    • setInterval(函数, 时间)    间隔多久执行一次函数 (时间单位为毫秒)
<button id="start">开始</button>
<button id="close">结束</button>
<script>
    // 每隔1000毫秒执行一次setInterval中function函数里的内容
    // setInterval(function () {
    //     console.log("666");
    // }, 1000);

    // 点击开始按钮时,启动定时器
    // 1.根据标签选择器获取DOM元素
    let startBtn = document.querySelector("#start");
    let id = null;
    // 2.绑定点击事件(点击按钮后,开始执行定时器)
    startBtn.onclick = function () {
        // 3.设置定时器
        id = setInterval(function () {
            console.log("666");
        }, 1000);
    }

    // 点击结束按钮时,关闭定时器
    // 1.根据标签选择器获取DOM元素
    let closeBtn = document.querySelector("#close");
    // 2.绑定点击事件(点击按钮后,结束执行定时器)
    closeBtn.onclick = function () {
        // 3.结束定时器
        clearInterval(id);
    }
</script>
  • 2.只执行一次的定时器
    • setTimeout(函数, 时间)   多久以后开始执行函数 (时间单位为毫秒)
<button id="start">开始</button>
<button id="close">结束</button>
<script>    
    // 5000毫秒后开始执行setTimeout中function函数里的内容
    // window.setTimeout(function () {
    //     console.log("666");
    // }, 5000);

    // 1.根据标签选择器获取DOM元素
    let startBtn = document.querySelector("#start");
    let id = null;
    // 2.绑定点击事件(点击按钮后,开始执行定时器)
    startBtn.onclick = function () {
        // 3.设置定时器
        id = window.setTimeout(function () {
            console.log("666");
        }, 5000);
    };

    // 1.根据标签选择器获取DOM元素
    let closeBtn = document.querySelector("#close");
    // 2.绑定点击事件(点击按钮后,结束执行定时器)
    closeBtn.onclick = function () {
        // 3.结束定时器
        clearTimeout(id);
    }
</script>  

案例1-小渔打字

<!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>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        html, body{
            /* 默认html和body的宽度均为浏览器的宽度 */
            /* width: 100%; */
            /* 默认html和body都没有高度 */
            height: 100%;
        }
        body{
            /* 设置背景图片: 图片地址 不平铺 图片位置(水平方向居中 垂直方向居中) */
            background: url(images/bg.jpg) no-repeat center center;
            /* 设置图片填满整个网页 */
            /* 告诉系统图片需要等比拉伸 */
            /* 告诉系统图片需要拉伸到宽度和高度都填满元素 */
            background-size: cover;
            /* 隐藏滚动条 */
            overflow: hidden;
        }
        .play{
            position: absolute;
            /* 当一个盒子绝对定位之后不能使用 margin: 0 auto; 让盒子自身水平居中 */
            /* margin: 0 auto; */
            top: 50%;
            left: 50%;
            /* 从其当前位置向左移动50%,并向上移动50% */
            transform: translate(-50%, -50%);
        }

        .box{
            /* 注意div的宽高必须比幽灵图片宽高大才能完全展示出来 */
            width: 300px;
            height: 300px;
            /* border: 1px solid red; */
            background: url(images/yy.png) no-repeat;
            /* 相对位置会占位置,导致幽灵上下排布 */
            /* position: relative; */
            position: absolute;
            top: 1000px;
        }

        .box>span{
            color: blue;
            font-size: 60px;
            /* 加粗 */
            font-weight: bold;
            /* 文字阴影 */
            text-shadow: 5px 5px 5px #3e437a;
            /* 定位:子绝父相 */
            position: absolute;
            top: 200px;
            left: 70px;
        }
    </style>
</head>
<body>
    <!-- 播放图片 -->
    <img src="images/play.png" class="play">

    <!-- 音频 -->
    <audio src="media/bg.ogg" class="bg"></audio>
    <!--注意点:
            在谷歌浏览器中默认情况下不允许自动播放音乐, 只有用户和网页交互之后才可以播放音乐 
            解决方案:
            让用户和网页交互之后再播放
    -->

    <!-- 幽灵 -->
    <!-- 
        <div class="box">
            <span>m</span>
        </div> 
    -->
    <!-- 一个div就是一个幽灵,将幽灵封装到类中,一个幽灵就创建一个幽灵对象 -->

    <script>
        // 根据选择器获取元素
        let oImg = document.querySelector(".play");
        let oAudio = document.querySelector(".bg");
        // 定义数组,保存所有创建出来的幽灵对象
        let list = [];
        // 绑定点击事件
        oImg.onclick = function(){

            // 当点击play播放图片时,删除该元素,并播放音频 // 

            // 1.修改元素样式
            // display: none  设置元素不可见
            // oImg.style.display = "none";

            // 1.删除元素(必须通过它的父元素/父节点进行删除,元素不能自删)
            // removeChild:删除子元素
            // 1.1 获取父节点
            let parent = oImg.parentNode;
            // 1.2 删除子元素
            parent.removeChild(oImg);
            // 2.播放音频
            oAudio.play();


            // 当点击play播放图片时,创建幽灵,并让幽灵向上飞 // 

            // // 3.创建幽灵对象
            // let s = new Specter();
            // // 4.调用幽灵对象的fly方法
            // s.fly();

            // 设置定时器,每隔一段时间就创建一个幽灵
            setInterval(function() {
                // 3.创建幽灵对象
                let s = new Specter();
                // 4.调用幽灵对象的fly方法
                s.fly();

                // 将创建的幽灵对象添加到list数组中
                list.push(s)
            }, 1000);

        }
 
        // 创建幽灵类
        class Specter{
            // 构造函数,定义属性
            constructor(){
                // 1.创建div并设置样式
                let oDiv = document.createElement("div");
                // 设置div的类名
                // oDiv.className = "box";
                // 通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式
                // 幽灵的高度都一样,但水平方向的位置不同
                oDiv.style.top = "1000px";
                // 设置div水平位置随机
                // Math.random():生成0-1的随机数
                oDiv.style.left = Math.random() * 1500 + "px";

                // 2.创建span并设置内容
                let oSpan = document.createElement("span");
                // 先将span中的内容都设置为m
                // oSpan.innerText="m";
                // 调用generateKey方法,将span中的内容都设置为随机字母
                let key = this.generateKey();
                oSpan.innerText = key;
                // 给div设置两个类名,一个是box,另一个是随机字母
                oDiv.className = "box "+ key;

                // 3.将span添加到div中
                oDiv.appendChild(oSpan);

                // 4.将div添加到body中
                // let oBody = document.querySelector("body");
                // oBody.append(oDiv);
                document.body.append(oDiv);

                // 保存oDiv到类的属性中
                this.oDiv = oDiv;
            }

            // 为了提高性能,当幽灵飞出界面后,需要删除幽灵并关闭定时器
            bomb(){
                // 1.删除当前幽灵
                document.body.removeChild(this.oDiv);      // Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'
                // 2.关闭当前幽灵对应的定时器
                clearInterval(this.timer);
            }

            // 定义 幽灵向上移动 的方法
            fly(){
                // 1.获取当前top值
                // let offset = this.oDiv.style.top;
                // console.log(offset);  //1000px
                // parseInt: 提取整数部分
                let offset = parseInt(this.oDiv.style.top);
                // console.log(offset);    //1000


                // // 保存this到self变量中
                // let self = this;
                // // 2.设置定时器,让top值不断减小
                // this.timer = window.setInterval(function(){
                //     // console.log(this);   //window  (普通函数/方法中的this, 谁调用就是谁)
                //     // console.log(self);
                //     offset -= 20;

                //     if(offset<=-300){
                //         // 当幽灵飞出界面后,调用bomb方法,删除幽灵并关闭定时器
                //         self.bomb();
                //     }

                //     // this.oDiv.style.top = offset + "px";
                //     self.oDiv.style.top = offset + "px";
                // }, 200);
                

                // 改进为箭头函数,此时便不需要提前保存this
                // 2.设置定时器,让top值不断减小
                this.timer = window.setInterval(() => {
                    // console.log(this);   //对象  (箭头函数中的this, 是父作用域的this)
                    offset -= 20;

                    if(offset<=-300){
                        // 当幽灵飞出界面后,调用bomb方法,删除幽灵并关闭定时器
                        this.bomb();
                    }

                    this.oDiv.style.top = offset + "px";
                }, 200);

            }

            // 定义 生成随机大写字母 的方法
            generateKey(){
                // 1.生成65-90的随机数
                let num = Math.floor(Math.random() * (90 - 65 + 1)) + 65;
                // 2.将数字转换为对应的字母(大写字母)
                let char = String.fromCharCode(num);
                return char;
            }
        }

        // let s = new Specter();
        // s.fly();


        // // 生成A-Z随机字母
        // // 定义函数(随机生成某个时段数字)
        // function getRandomIntInclusive(min, max) {
        //         min = Math.ceil(min);
        //         max = Math.floor(max);
        //         return Math.floor(Math.random() * (max - min + 1)) + min;   //含最大值,含最小值
        // }
        // // 1.生成65-90的随机数
        // let num = getRandomIntInclusive(65, 90);
        // // 2.将数字转换为对应的字母
        // let char = String.fromCharCode(num);
        // console.log(char);


        // 绑定键盘按键事件
        // 监听用户按下键盘中的某个按键,删除对应按键下的幽灵oDiv;比如按下A,删除幽灵上随机字母为A的幽灵
        document.body.onkeydown = function(event){
            // console.log("666");
            // keyCode: 按键对应的数字
            // console.log(event.keyCode);
            // key:按键 (小写字母)
            // console.log(event.key);
            // 1.获取用户输入的按键
            let key0 = event.key;
            // 2.将小写字母转换为大写字母(因为幽灵身上的随机字母是大写字母)
            let key = key0.toUpperCase()
            // console.log(key);
            // 3.根据用户按键,找到对应的幽灵并删除
            // 通过类选择器找到对应的div元素
            let oDiv = document.querySelector("."+key);
            // console.log(oDiv);


            // 删除oDiv幽灵
            // document.body.removeChild(oDiv);      // Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'
            // 删除了一个不存在的oDiv,所以才会报错
            // 当你按下键盘A,会删掉随机字母为A的幽灵,当幽灵飞出界面时,会调用bomb方法,此时又会执行删除当前幽灵,但此时这个幽灵已经在按键时被删除了,所以就会产生删除一个不存在的幽灵,就会报错


            // 删除幽灵的正确方法!
            // 1.找到幽灵对象在list数组中的位置
            // findIndex: 找到,返回 索引; 找不到,返回 -1
            let currentIndex = list.findIndex(function(currentValue){
                // currentValue是一个幽灵对象,而oDiv只是是幽灵对象的一个属性
                return currentValue.oDiv === oDiv;   // 如果等式成立则返回true
            });
            // 2.如果没有找到,则什么也不返回
            if(currentIndex === -1){
                return;
            }
            // console.log(currentIndex);
            // 3.根据索引找到list数组中对应的幽灵对象
            let currentSpecter = list[currentIndex];
            // 4.调用幽灵对象的bomb方法,删除幽灵并关闭定时器
            currentSpecter.bomb();
            // 5.从list数组中删除该幽灵对象
            // splice: 从currentIndex索引开始,删除1个元素
            list.splice(currentIndex, 1);
        }

        // // toLowerCase: 全部转换为小写
        // console.log("aBc".toLowerCase());
        // // toUpperCase:全部转换为大写
        // console.log("aBc".toUpperCase());
    </script>
</body>
</html>

如何生成随机字母(A-Z:65-90)?

keycode对应表:

代码:

        // 生成A-Z随机字母

        // 定义函数(随机生成某个时段数字)
        function getRandomIntInclusive(min, max) {
                min = Math.ceil(min);
                max = Math.floor(max);
                return Math.floor(Math.random() * (max - min + 1)) + min;   //含最大值,含最小值
        }
        // 1.生成65-90的随机数
        let num = getRandomIntInclusive(65, 90);

        // 2.将数字转换为对应的字母
        let char = String.fromCharCode(num);
        console.log(char);

箭头函数与普通函数的区别:

(1).普通函数/方法中的this, 谁调用谁就是this

        function demo(){
            console.log(this)     //window
        }
        // demo();
        window.demo();

(2).箭头函数中的this, 是父作用域的this,而并非调用者

        // 创建对象
        let p = {
            name: "lily",
            say: function(){
                console.log(this);   //{name: "lily", say: ƒ, hi: ƒ}
            },
            // 因为没有将箭头函数放到其它的函数中, 所以箭头函数属于全局作用域
            // 在JS中只有定义一个新的函数才会开启一个新的作用域
            hi: () => {
                console.log(this);   //window
            }
        };
        p.say();
        p.hi();

        // 构造函数
        function Person(){
            this.name = "alice";
            this.age = 16;
            this.say = function(){
                console.log(this);   //Person {name: "alice", age: 16, say: ƒ, hi: ƒ}
            };
            // 因为将箭头函数放到其它的函数中, 所以箭头函数属于其它函数(当前的其它函数就是构造函数)
            // 既然箭头函数属于构造函数, 所以箭头函数中的this就是构造函数的this
            this.hi = () => {
                console.log(this);   //Person {name: "alice", age: 16, say: ƒ, hi: ƒ}
            }
        }
        p0 = new Person();
        p0.say();
        p0.hi();

注意点:箭头函数中的 this,永远都只看它所属的作用域的 this,无法通过 bind / call / apply 来修改

        function Person1(){
            this.name = "joke";
            this.say = function(){
                console.log(this);    //{name: "zs"}
            }
            this.hi = () => {
                console.log(this);   //Person1 {name: "joke", say: ƒ, hi: ƒ}
            }
        }
        let p1 = new Person1();
        p1.say.call({ name: "zs" });
        //  注意点: 箭头函数中的this永远都只看它所属的作用域的this
        //         无法通过bind/call/apply来修改
        p1.hi.call({ name: "zs" });

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值