JavaScript-Basic WebAPIs Day2 Notes

1、.addEventListener() 方法中,常见的操作类型除了click还有哪些?

在 JavaScript 中,.addEventListener() 方法可以监听多种事件类型,常见的操作类型包括但不限于以下几种:

  1. click:用户单击元素时触发。

element.addEventListener('mouseover', function() {
    // 鼠标移入时执行的操作
});

  3.mouseout:当鼠标指针移出元素时触发。

element.addEventListener('mouseout', function() {
    // 鼠标移出时执行的操作
});

  4.mousedown:当用户按下鼠标按钮时触发。

element.addEventListener('mousedown', function() {
    // 鼠标按下时执行的操作
});

  5.mouseup:当用户释放鼠标按钮时触发。

element.addEventListener('mouseup', function() {
    // 鼠标释放时执行的操作
});

  6.dblclick:当用户双击元素时触发。

element.addEventListener('dblclick', function() {
    // 双击时执行的操作
});

  7.keydown:当用户按下键盘上的键时触发。

element.addEventListener('keydown', function(event) {
    // 键盘按下时执行的操作
});

  8.keyup:当用户释放键盘上的键时触发。

element.addEventListener('keyup', function(event) {
    // 键盘释放时执行的操作
});

  9.input:当用户在 <input><textarea><select> 元素中输入内容时触发。

element.addEventListener('input', function() {
    // 输入内容时执行的操作
});

  10.change:当用户更改 <input><textarea><select> 元素的值时触发(在失去焦点时)。

element.addEventListener('change', function() {
    // 值更改时执行的操作
});

  11.submit:当表单提交时触发。

element.addEventListener('submit', function(event) {
    event.preventDefault(); // 阻止表单提交
    // 表单提交时执行的操作
});

  12.focus:当元素获得焦点时触发。

element.addEventListener('focus', function() {
    // 元素获得焦点时执行的操作
});

  13.blur:当元素失去焦点时触发。

element.addEventListener('blur', function() {
    // 元素失去焦点时执行的操作
});

  14.resize:当窗口或元素的大小发生变化时触发。

window.addEventListener('resize', function() {
    // 窗口大小变化时执行的操作
});

  15.scroll:当用户滚动页面或元素时触发。

window.addEventListener('scroll', function() {
    // 滚动时执行的操作
});

 

2、如下代码中,为什么clearInterval里面要装一个timerId呢?这是什么含义?

几个字简单理解:一一对应。

    <script>

        const arr = ['马超', '黄忠', '赵云', '关羽', '张飞', '吕布']

        let timerId = 0
        let random = 0

        const qs = document.querySelector('.qs')

        const start = document.querySelector('.start')

        start.addEventListener('click', function(){
            timerId = setInterval(function(){
                random = parseInt(Math.random() * arr.length)
                qs.innerHTML = arr[random]
            }, 35)

            if(arr.length==1){
                start.disabled = true
                end.disabled = true
            }
        })
        
        const end = document.querySelector('.end')
        end.addEventListener('click', function(){
            clearInterval(timerId)
            arr.splice(random, 1)
            console.log(arr)
        })

    </script>

在你的代码中,clearInterval(timerId) 中的 timerId 是一个计时器的标识符(ID),用来表示由 setInterval 方法启动的计时器。为了理解这个概念,我们可以拆解代码并解释其含义。

setIntervalclearInterval

  • setInterval这是一个 JavaScript 内置的函数,用来以固定的时间间隔反复执行一个函数或一段代码。它会返回一个唯一的 ID,这个 ID 可以用来引用特定的计时器。

    在你的代码中,setInterval 被用来每隔 35 毫秒随机选择一个名字,并将其显示在 qs 元素中:

timerId = setInterval(function(){
    random = parseInt(Math.random() * arr.length)
    qs.innerHTML = arr[random]
}, 35)
  • timerId 就是 setInterval 返回的这个唯一标识符。

  • clearInterval:这是另一个 JavaScript 内置函数,用来停止一个由 setInterval 启动的计时器。它接受一个计时器 ID 作为参数,并用它来停止对应的循环操作。

    在你的代码中,当用户点击 "end" 按钮时,clearInterval(timerId) 会被调用:

end.addEventListener('click', function(){
    clearInterval(timerId)
    arr.splice(random, 1)
    console.log(arr)
})
  • 这里的 clearInterval(timerId) 使用了前面 setInterval 返回的 timerId,这样可以停止正在运行的 setInterval 计时器,停止进一步的循环操作。

总结

  • timerId 的作用是保存 setInterval 返回的计时器标识符,这样你可以在需要时用它来停止这个计时器。
  • clearInterval(timerId) 中的 timerId 用来标识需要停止的计时器。如果不保存这个 ID,将无法准确地停止特定的计时器。

如果不使用 clearInterval 来清除计时器,定时器将会持续运行下去,即使页面内容发生变化或用户停止了某些操作,计时器依然会继续工作。这就是为什么需要保存 timerId,并在适当的时候清除它。

 

3、在一个html文件中,是否可以插入多个script, style标签?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multiple Script and Style Tags</title>
    
    <!-- 第一个脚本 -->
    <script>
        console.log('这是第一个脚本');
    </script>
</head>
<body>
    
    <!-- 第二个脚本 -->
    <script>
        console.log('这是第二个脚本');
    </script>

    <!-- 外部脚本 -->
    <script src="external-script.js"></script>

</body>
</html>

每个 <script> 标签中的代码会按照它们在文档中出现的顺序执行。

多个 <style> 标签

同样,你可以在页面中多次插入 <style> 标签来定义不同的 CSS 样式。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multiple Script and Style Tags</title>

    <!-- 第一个样式 -->
    <style>
        body {
            background-color: lightblue;
        }
    </style>
    
    <!-- 第二个样式 -->
    <style>
        h1 {
            color: darkblue;
        }
    </style>
</head>
<body>

    <h1>这是一个标题</h1>

</body>
</html>

多个 <style> 标签中的样式会按照它们在文档中出现的顺序应用。如果有冲突的样式规则,后面出现的样式规则会覆盖前面的规则。

总结

在一个 HTML 文件中,可以插入多个 <script><style> 标签。它们会按照在文档中出现的顺序加载和执行/应用。

这种方法通常用于分离不同功能的脚本或样式,或者在文档不同部分中添加局部样式或脚本。

 

3、如下JS代码的API如何理解

<body>
    <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]')
        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>
</body>

在CSS中,blockdisplay 属性中的含义与“封锁”无关。

相反,display: block; 是一种布局模式,它决定了元素如何在页面上展示。让我们更详细地解释一下:

display 属性的含义

  • display: block;这个值将元素显示为块级元素。块级元素会独占一行,其宽度默认会扩展到父容器的宽度。常见的块级元素有 <div><p><h1> 等。当你将 display 设置为 block 时,元素会被正常显示,并且会在页面上占据它应有的位置。

  • display: none;:这个值会隐藏元素。元素将不会显示在页面上,并且不会占据任何空间。

  • 其他常见的 display

    • inline将元素显示为内联元素,内联元素不会独占一行,常见的内联元素有 <span><a><img> 等。
    • inline-block将元素显示为内联块级元素,这意味着它像块级元素那样可以设置宽高,但又像内联元素那样不会独占一行。

为什么设置为 'block' 就能显示?

在你的代码中:

ul.style.display = 'block';

这行代码的作用是将 <ul> 元素(即搜索建议列表)的 display 属性设置为 block,让它以块级元素的形式显示出来。

如果之前这个元素的 display 属性被设置为 none(隐藏状态),那么将其设置为 block 后,它就会显示在页面上,并且占据一行。

因此,block 并不是“封锁”的意思,而是指一种布局模式,表示这个元素以块级的形式展示在页面上。

 

追问:不太理解input.classList.add('search') 还有input.classList.remove('search') 为什么需要这两行代码?能有什么作用

input.classList.add('search')input.classList.remove('search') 这两行代码的作用是动态地为 input 元素添加或移除一个叫做 'search' 的 CSS 类,以实现不同的样式效果。

1. classList.add('search') 的作用

  • 这行代码是用来为 input 元素添加一个叫做 'search' 的 CSS 类。例如,当用户点击搜索框并使其获得焦点时,这行代码会执行,input 元素就会多出一个 'search' 类。
  • 添加这个类后,浏览器会应用与这个类相关联的 CSS 样式,从而改变 input 元素的外观。

例如,你可能在 CSS 文件中定义了一个样式规则:

.search {
    border: 2px solid blue;
    background-color: lightyellow;
}

input 元素获得焦点时,classList.add('search') 会将 'search' 类添加到 input 上,导致 input 元素的边框变成蓝色,背景颜色变成淡黄色。

2. classList.remove('search') 的作用

  • 这行代码是在 input 元素失去焦点时执行的,用来移除之前添加的 'search' 类。
  • 'search' 类被移除后,input 元素会恢复到原来的样式,即移除了与 'search' 类相关的样式。

例如,如果你希望当用户不再点击搜索框时,搜索框恢复原样,可以在 blur 事件中使用 classList.remove('search')

input.addEventListener('blur', function () {
    ul.style.display = 'none';
    input.classList.remove('search');
});

为什么需要这两行代码?

  • 视觉反馈:通过在不同状态下为元素添加或移除类,你可以动态地改变元素的样式,给用户提供视觉反馈。例如,当用户点击搜索框时,可以让搜索框的边框颜色变成蓝色,让用户感知到搜索框处于“激活”状态。

  • 简洁性:通过这种方式,可以保持 CSS 样式与 JavaScript 逻辑的分离,使得代码更易于维护。如果你在多个地方需要应用相同的样式变化,只需在 CSS 中定义一次 'search' 类,然后在需要的地方添加或移除这个类即可,而不需要在 JavaScript 中手动设置或移除具体的样式属性。

 

4、对于如下代码,如果我需要精确锁定键盘上的每一个键,那应该如何写操作类型呢?对于如下代码,如果我需要精确锁定键盘上的每一个键,那应该如何写操作类型呢?

    <script>

        const input = document.querySelector('input')

        input.addEventListener('keydown', function (){
            console.log('键盘按下了')
        })

        input.addEventListener('keyup', function (){
            console.log('键盘回弹了')
        })

    </script>

在你的代码中,已经使用了 keydownkeyup 事件来分别检测键盘按下和键盘释放的操作。

如果你需要精确锁定和识别用户按下的每一个键,可以在事件监听器中使用 event 对象的 keycode 属性来判断具体是哪一个键。

keydownkeyup 事件

  • keydown:当用户按下一个键时触发,即使用户按住键不放,这个事件也只会触发一次。
  • keyup:当用户释放一个键时触发。

event.keyevent.code

  • event.key返回用户按下的键对应的字符。例如,按下字母 a 会返回 "a",按下回车键会返回 "Enter"
  • event.code返回物理键盘按键的位置或标识。例如,按下左侧的 Shift 键会返回 "ShiftLeft",即使用户使用的是其他键盘布局。

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Key Detection</title>
</head>
<body>

    <input type="text" placeholder="按下任意键">

    <script>
        const input = document.querySelector('input');

        input.addEventListener('keydown', function(event) {
            console.log('键盘按下了: ' + event.key);
        });

        input.addEventListener('keyup', function(event) {
            console.log('键盘回弹了: ' + event.key);
        });
    </script>

</body>
</html>

示例解释

  • keydown 事件监听器中,当用户按下某个键时,会触发回调函数,并通过 event.key 输出按下的键。例如,按下 a 会在控制台打印 "键盘按下了: a"
  • keyup 事件监听器中,当用户释放某个键时,同样会触发回调函数,并输出释放的键。

如何处理特殊键

如果你想处理特殊键(例如 EnterShiftCtrlAlt 等),可以对 event.keyevent.code 进行条件判断。例如:

input.addEventListener('keydown', function(event) {
    if (event.key === 'Enter') {
        console.log('你按下了回车键');
    } else if (event.key === 'Escape') {
        console.log('你按下了Esc键');
    } else {
        console.log('按下的键是: ' + event.key);
    }
});

这种方式可以让你在键盘上按下任何键时,都能够精确地知道按下了哪个键,并根据需要进行相应的操作。

 

4、请解释下如下代码,什么是伪类选择器,为什么要叫伪类,如何理解这个名称和概念

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        input {
            width: 200px;
            transition: all .3s;
        }

        input:focus{
            width: 300px;
        }

    </style>
</head>

<body>
    <input type="text">
</body>

</html>

伪类选择器是什么?

伪类选择器是CSS中的一种特殊选择器,用于选择元素的特定状态或条件下的样式。例如,当用户将鼠标悬停在一个元素上,或者当一个输入框获得焦点时,伪类选择器可以应用不同的样式。

代码示例解析

<style>
    input {
        width: 200px;
        transition: all .3s;  # 理解,见追问部分
} input:focus { width: 300px; }
</style>

在这段代码中,input:focus 是一个伪类选择器,它选择在用户点击或触摸输入框时的状态。

当输入框获得焦点时(focus),它的宽度从200px变为300px,并且这个变化会在0.3秒内平滑过渡(由于transition的设置)。

为什么叫伪类?

“伪类”(Pseudo-class)这个名称来源于它的作用:伪类选择器并不是基于HTML元素的实际结构或属性来选择元素,而是基于元素的一种“虚拟”状态或行为。

例如,:hover 伪类选择器是基于元素是否被鼠标悬停,而不是元素本身的属性。同样,:focus 伪类选择器是基于元素是否被聚焦,而不是HTML中直接定义的。

伪类 表示它们“假装”是在操作元素的类,但实际上并不需要在HTML中显式地添加或移除类名。它们是CSS提供的工具,用来处理元素的特定状态或行为。

如何理解这个名称和概念

  • “伪”表示这些选择器操作的是元素的某种临时状态,而不是静态的属性或类。例如,input:focus 选择器并不是在HTML中真正存在一个类叫做 focus,而是在元素被用户聚焦时,CSS会“假装”它有这个类,从而应用特定的样式。

  • “类”:虽然是“伪类”,它们的行为与标准的类选择器类似,都用来选择和应用特定的样式。

其他常见的伪类

  • :hover:当用户将鼠标悬停在元素上时应用的样式。
  • :active:当用户点击并按住元素时应用的样式。
  • :visited:已经访问过的链接应用的样式。

伪类选择器在Web开发中非常重要,它们能够根据用户的交互或元素的状态,动态地改变页面的样式,使页面更加生动和响应。

 

追问:transition: all 0.3s 这个all是什么意思?

transition: all 0.3s 是CSS中的一个简写属性,用于定义在元素的某些属性变化时,如何进行动画过渡。

各个部分的含义

  • all: 指代所有支持过渡的CSS属性。当你使用 all 时,任何该元素上发生变化的CSS属性都会应用过渡效果。

  • 0.3s: 这是过渡动画的持续时间,表示动画从开始到结束所花费的时间是0.3秒。

具体解释

  • all: 如果你希望元素的多个属性变化都使用相同的过渡效果,就可以使用 all
  • 例如,如果你想同时改变元素的宽度(width)、高度(height)、背景色(background-color)等多个属性的变化都应用相同的过渡效果,all 会非常方便。

示例

假设你有一个按钮,正常状态下是蓝色,宽度为100px;当用户将鼠标悬停在按钮上时,背景颜色变为绿色,宽度增加到150px。

<style>
    button {
        width: 100px;
        background-color: blue;
        transition: all 0.3s;
    }

    button:hover {
        width: 150px;
        background-color: green;
    }
</style>
<button>Click me</button>

在这个例子中:

  • 当鼠标悬停时,按钮的 widthbackground-color 都会发生变化。
  • 因为 transition: all 0.3s 被应用,所以这两个属性的变化会同时在0.3秒内平滑过渡。

自定义过渡属性

如果你只想对某些特定属性应用过渡,而不是所有属性,你可以替换 all 为具体的CSS属性名,例如:

transition: width 0.3s, background-color 0.3s;

这样,只有 widthbackground-color 发生变化时才会应用过渡效果,而其他属性的变化将是即时的,没有动画过渡。

总结

  • all: 表示所有支持的CSS属性在变化时都应用过渡效果。
  • 0.3s: 表示过渡效果的持续时间为0.3秒。

使用 all 可以让你的代码更简洁,适合那些希望在元素的多个属性发生变化时,都应用统一的过渡效果的场景。

 

5、在html中,i这个标签是指什么? 

<i class="avatar"></i>

在HTML中,<i> 标签通常用于表示斜体文本,它代表 "italic"(斜体)。然而,随着HTML5的推出,<i> 标签也可以用来表示一些其他的含义,比如技术术语、外来词或缩写词等,这些情况通常需要通过CSS来实现不同的样式。

在你提供的示例 <i class="avatar"></i> 中,<i> 标签被用作一个语义上不明确的容器,它本身并不直接表示任何特定的内容。

然而,通过添加 class="avatar" 这个类,开发者可以利用CSS来为这个元素定义特定的样式,比如图标、图片或者特定的布局样式。这种情况下,<i> 标签的使用更多是出于样式和布局的考虑,而不是其传统的语义含义。

例如,CSS可以这样定义:

.avatar {
  width: 50px;
  height: 50px;
  background-image: url('path/to/avatar.png');
  display: inline-block;
  vertical-align: middle;
}

这样,<i class="avatar"></i> 就会显示为一个具有特定背景图像的图标,通常用作用户头像。

 

6、对于如下代码的this应该怎么理解呢?经常容易弄混淆

<body>
    
    <div class="tab">
        <div class="tab-nav">
          <h3>每日特价</h3>
          <ul>
            <li><a class="active" href="javascript:;">精选</a></li>
            <li><a href="javascript:;">美食</a></li>
            <li><a href="javascript:;">百货</a></li>
            <li><a href="javascript:;">个护</a></li>
            <li><a href="javascript:;">预告</a></li>
          </ul>
        </div>
        <div class="tab-content">
          <div class="item active"><img src="tab00.png" alt="" /></div>
          <div class="item"><img src="tab01.png" alt="" /></div>
          <div class="item"><img src="tab02.png" alt="" /></div>
          <div class="item"><img src="tab03.png" alt="" /></div>
          <div class="item"><img src="tab04.png" alt="" /></div>
        </div>
      </div>

    
    <script>
        const as = document.querySelectorAll('.tab-nav a')

        for(let i = 0; i < as.length; i++){
            as[i].addEventListener('mouseenter', function (){
                
                document.querySelector('.tab-nav .active').classList.remove('active')
                this.classList.add('active')

                document.querySelector('.tab-content .active').classList.remove('active')
                document.querySelector(.tab-content .item:nth-child(${i + 1})).classList.add('active')
            })
            
        }

    </script>

</body>

在JavaScript中,this 是一个非常重要但容易混淆的概念。this 的值取决于它在代码中的使用上下文。对于你提供的代码,this 的解释如下:

this 的含义

在事件处理函数中(如 addEventListener 中),this 指的是触发事件的元素具体到你的代码中,thismouseenter事件的回调函数中指代的是当前被鼠标悬停的那个 <a> 元素。

代码解析

const as = document.querySelectorAll('.tab-nav a')

for(let i = 0; i < as.length; i++){
    as[i].addEventListener('mouseenter', function (){
        document.querySelector('.tab-nav .active').classList.remove('active')
        this.classList.add('active')

        document.querySelector('.tab-content .active').classList.remove('active')
        document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
    })
}

详细解释

  1. 循环遍历每个 <a> 元素:

const as = document.querySelectorAll('.tab-nav a')

  2.为每个 <a> 元素绑定 mouseenter 事件:

as[i].addEventListener('mouseenter', function (){

  • 这里使用了 addEventListener,当用户将鼠标悬停在某个 <a> 元素上时,会触发这个事件处理函数。

  3.this 的作用:

this.classList.add('active')
  • 当事件触发时,this 指向当前被鼠标悬停的 <a> 元素。这个元素会获得 active 类,从而被高亮或标记为选中。

  4.更新 tab-content 中的内容:

document.querySelector('.tab-content .active').classList.remove('active')
document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')

    首先,移除当前 .tab-content 中已经有的 active 类。

    然后,使用 nth-child(${i + 1}) 来选中对应的 .item 元素,并添加 active 类,这样内容会切换到对应的选项卡。 

为什么容易混淆 this

  • 不同的上下文: this 在不同的上下文中会有不同的值,比如在全局作用域、对象方法、构造函数、以及事件处理函数中都可能有不同的指向。这种灵活性使得理解 this 变得复杂。

  • 箭头函数: 在箭头函数中,this 的行为不同,箭头函数的 this 是由外层作用域决定的,而不是当前事件触发的元素。

关键点总结

  • 在事件处理函数中,this 通常指向触发事件的DOM元素(比如这里的 <a> 标签)。
  • 通过 this,你可以访问和操作当前元素的属性、样式,或添加/移除类。

理解 this 最好的方法是通过实际例子和调试工具,比如在浏览器控制台中使用 console.log(this) 来查看每次事件触发时 this 的值。

 

7、追问:使用 nth-child(${i + 1}) 而不是i 是不是因为索引是从1开始的?

在CSS选择器中,nth-child 是基于1开始的索引来选择元素的而JavaScript中的数组和NodeList的索引是从0开始的。这就是为什么在你使用nth-child(${i + 1})时,需要加1的原因。

更详细的解释

  • JavaScript中的索引: i 是JavaScript中的循环变量,它是从0开始计数的。例如,如果你有一个包含5个元素的数组,那么它们的索引分别是0、1、2、3、4。

  • CSS中的 nth-child: 这个伪类选择器是基于1开始的索引来选择元素的。例如,如果你想选择一个列表中的第一个元素,你会使用 nth-child(1)

示例

假设 i 是0,那么:

  • JavaScript中的第一个元素是 i = 0
  • 但在CSS中,选择第一个元素需要使用 nth-child(1)

所以,在代码中,你会看到nth-child(${i + 1}),这样就确保了i从0开始时,选择器能正确对应到CSS中的第一个子元素。

document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
  • i = 0 时,nth-child(${i + 1}) 就是 nth-child(1),选择第一个 .item 元素。
  • i = 1 时,nth-child(${i + 1}) 就是 nth-child(2),选择第二个 .item 元素。

这样,i 的0基索引和nth-child的1基索引能够正确匹配。

 

posted @ 2024-08-24 20:51  AlphaGeek  阅读(16)  评论(0)    收藏  举报