JS-part7.2- DOM

DOM简介

Document Object Model 文档对象模型
  + 一套操作页面元素的属性和方法

在这里插入图片描述

了解 DOM
  + DOM 是一个以树状结构存在的内容
  + DOM 的顶级是 document 表示当前文档
  + 因为我们 PC 端的文档是插入到 chrome 浏览器里面运行
    => 所以在 PC 端, document 上面还有一个 window

在这里插入图片描述

对 DOM 的操作
  + 从 document ~ 各种标签, 文本, 属性, 样式的操作

问题: window 下面有一个 document 对还是不对
  => 对! 反过来说, document 一定在 window 下就是错的了

获取 DOM 元素

+ 通过 JS 获取到页面中的元素, 进行操作
+ 两类标签

非常规标签

1.非常规标签:
    1-1. html
      => document.documentElement
    1-2. head
      => document.head
    1-3. body
      => document.body
// 1. 非常规标签
// 1-1. html
var html = document.documentElement;
console.log(html);

// 1-2. head
var head = document.head;
console.log(head);

// 1-3. body
var body = document.body;
console.log(body);

在这里插入图片描述

常规标签

+ 这种方法不是不能获取非常规标签,只是一般不这么用

getElementById()

2-1. getElementById()
  => 语法: 查找范围.getElementById('id名称')
  => 查找范围: document 或者是 一个元素
  => 返回值:
    -> 如果有这个 id 名匹配的元素,就是这个元素
    -> 如果没有, 就是 null
// 2-1. getElementById()
// 在 document 范围下通过 id 名称查找一个叫做 btn 的元素
var btn = document.getElementById('btn');
console.log(btn);

// 在 document 范围下通过 id 名查找一个叫做 a 的元素
// var p = document.getElementById('a');
// console.log(p);

// var div = document.getElementById('box');
// 在 div 元素范围内查找 id 名叫做 a 的元素
// var p2 = div.getElementById('a');
// console.log(p2);

第二种方法有点问题…

getElementsByTagName()

2-2. getElementsByTagName()
  => 语法: 查找范围.getElementsByTagName('标签名')
  => 查找范围: document 或者是 一个元素
  => 返回值: 是一个伪数组(用不了数组常用方法)
    -> 如果有这个标签名匹配的元素, 有多少获取多少
    -> 如果没有, 返回一个空的伪数组
// 2-2. getElementsByTagName()
var p1 = document.getElementsByTagName('p');
console.log(p1);
// 你想准确地拿到某一个元素, 要么遍历,要么使用[索引]
// console.log(p1[0]);

var div = document.getElementsByTagName('div')[0];
// 在 div 范围下通过标签名查找多个叫做 p 的元素
var p2 = div.getElementsByTagName('p');
console.log(p2);

在这里插入图片描述

getElementsByClassName()

2-3. getElementsByClassName()
  => 语法: 查找范围.getElementsByClassName('类名')
  => 查找范围: document 或者是 一个元素
  => 返回值: 是一个伪数组(用不了数组常用方法)
    -> 如果有这个类名匹配的元素, 有多少获取多少
    -> 如果没有, 返回一个空的伪数组
<ul>
    <li class="box">1</li>
    <li class="box">2</li>
    <li class="box">3</li>
    <li class="box">4</li>
    <li class="box">5</li>
    <li class="box">6</li>
    <li class="box">7</li>
    <li class="box">8</li>
    <li class="box">9</li>
    <li class="box">10</li>
</ul>
// 2-3. getElementsByClass()
var box = document.getElementsByClassName('box');
console.log(box);

在这里插入图片描述

getElementsByName()

2-4. getElementsByName()
 => 语法: 查找范围.getElementsByName('元素name属性的值')
 => 查找范围: document 或者是 一个元素
 => 返回值: 是一个伪数组(用不了数组常用方法)
   -> 如果有元素name属性的值匹配, 有多少获取多少
   -> 如果没有, 返回一个空的伪数组
<input type="text" name="username">
<input type="text">
<div name="username">123</div>

// 2-4. getElementsByName()
// 只要有元素 name 属性的值是 username,就能获取到
var inp = document.getElementsByName('username');
console.log(inp);

在这里插入图片描述


h5觉得以上四个获取DOM元素的方法不够用,又新加了俩,IE低版本不支持这俩方法

querySelector()

2-5. querySelector()
 => 语法: 查找范围.querySelector('CSS选择器')
 => 选择器: 能在 css 里面写的选择器,这里都能写
 => 返回值:
   -> 如果找到选择器匹配的元素,返回第一个找到的内容
   -> 找不到,返回 null
 => IE 低版本不支持

注: 可看出,和getElementById一样,只找一个匹配的元素, 找不到就返回null ; 而找多个的不管找不到得到都是返回伪数组

<ul>
    <li class="box">1</li>
    <li class="active">2</li>
    <li class="box">3</li>
    <li class="box">4</li>
</ul>

// 2-5. querySelector()
// 通篇查找 li
var box = document.querySelector('li');
var box = document.querySelector('li.active');
var box = document.querySelector('ul > li');
console.log(box);

querySelectorAll()

2-6. querySelectorAll()
 => 语法: 查找范围.querySelectorAll('CSS选择器')
 => 选择器: 能在 css 里面写的选择器,这里都能写
 => 返回值: 是一个伪数组(用不了数组常用方法)
   -> -> 如果找到选择器匹配的元素, 有多少获取多少
   -> 如果找不到, 返回一个空的伪数组
 => IE 低版本不支持
// 2-6. querySelector()
var box = document.querySelectorAll('li');
var box = document.querySelectorAll('.active');
var box = document.querySelectorAll('ul > li');
var box = document.querySelectorAll('ul > li:nth-child(3)');
var box = document.querySelectorAll('ul > li:nth-child(odd)');   // 奇数
var box = document.querySelectorAll('ul > li:nth-child(even)');   // 偶数
console.log(box);

操作元素属性

元素的属性分类:
  1. id / class / style / src / type / name / href / border / ...原生属性
    => style 是属性名,这个属性的作用就是给元素设置内联样式
  2. index / abc / aaa / ... 自定义属性
    => 不是标签原生自带的属性,是我们自己随便写的
    => 难区分是自定义还是原生属性
  3. 以 data-xxx 开头的属性
    => 我们都叫做 H5 自定义属性
<div id="box" class="box" style="color:red">我是 div 标签</div>
<div index="hello" abc="你好世界" aaa="100">我是第二个 div 标签</div>
<div data-index="1" data-id="box">H5 标准下</div>
+ 使用 JS 语法操作标签上的三种属性:

1. 原生属性
  => 直接操作
  => 元素.属性名
  
2. 自定义属性
  => setAttribute()
  => getAttribute()
  => removeAttribute()
  
3. H5 自定义属性
  => 元素.dataset.xxx

原生属性

+ 语法: 元素.属性名
  => 读: 元素.属性名
    -> 获取元素该属性的值
  => 写: 元素.属性名 = '值'
    -> 设置该元素的该属性的值
+ 注意: class 除外, 操作类名使用 元素.className, 下一章单独说
<div></div>
<input type="text">
<img src="" alt="">

// 获取元素
var div = document.querySelector('div');
var inp = document.querySelector('input');
var img = document.querySelector('img');

// 1. 原生属性
// 给 div 设置一个 id 属性
div.id = 'box';

// 读取 div 上的 id 属性
console.log(div.id);
console.log(div);

// 给 input 设置一下 type 属性
inp.type = 'password';
inp.value = 'hello world';

// 给 img 设置一下 src 属性
img.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfcZ9I0Y6vUsqCSfi9Hpb7Kfls3M16OTSIQw&usqp=CAU';

自定义属性

+ 不能直接点语法操作
+ 三个方法
  1. setAttribute('属性名', '属性值')
    => 给元素标签上设置属性
  2. getAttribute('属性名')
    => 获取元素上的属性的值
  3. removeAttribute('属性名')
    => 删除元素上的属性
    
+ 三种方法的特点:
  1. 可以操作自定义属性, 也可以操作原生属性和H5自定义属性, 但一般不这么用
  2. 不管你设置什么数据类型,当你再次从标签上拿到的时候,都是字符串
<div data-a="100"></div>
<input type="text">
<img src="" alt="">

// 获取元素
var div = document.querySelector('div');
var inp = document.querySelector('input');
var img = document.querySelector('img');

// 2. 自定义属性
// 设置自定义属性
div.setAttribute('index', 100);
div.setAttribute('abc', '你好');
// div.setAttribute('data-a', 'abcd');

// 获取自定义属性
var str = div.getAttribute('index');
console.log(str);   // hello
console.log(typeof str);   // string

// 删除元素属性
div.removeAttribute('abc');

H5 自定义属性

+ 每一个元素上有一个属性叫做 dataset
+ 里面包括了所有 H5 自定义属性
  => key 是除了 data- 以外的内容
  => value 就是这个属性的值
+ 操作 H5 自定义属性
  => 直接在 dataset 里面进行操作
+ 获取
  => 元素.dataset.名字
    -> 名字: 标签上写 data-a, 使用就是 a
+ 设置
  => 元素.dataset.名字 = '值'
    -> 名字: 如果你在这里写的是 a,那么映射在标签上是data-a
// 获取元素
var div = document.querySelector('div');
var inp = document.querySelector('input');
var img = document.querySelector('img');

// 3. H5 自定义属性
// 获取元素标签上的 data-a 属性
var str = div.dataset.a;
console.log(str);

// 设置元素标签上的 data-hello 属性,设置值为 world
div.dataset.hello = 'world';

// 删除元素标签上的data-hello属性
// 直接删除 dataset 对象中的 hello 成员
delete div.dataset.hello;

操作元素类名

+ 我们有两种方式操作元素类名

1. 按照原生属性操作:

  => 设置类名
    -> 元素.className = 'box'
  => 修改类名
    -> 元素.className = '新值'
  => 追加类名
    -> 元素.className = 元素.className + '新类名'
    -> 注意: 新类名前面要有一个空格!!!
  => 删除类名
    -> 获取类名
    1. 截取字符串
    2. 按照空格切开,循环遍历,找到一个你想删除的删除掉
    3. 再写一遍
  => 特点: 好加不好删
<div>我是 div 标签</div>

// 获取元素
var div = document.querySelector('div');
// 1. 原生属性方式操作类名
// 1-1. 设置类名
div.className = 'box';

// 1-2. 修改类名
div.className = 'box2';

// 1-3. 追加类名
div.className += ' abc'; 
2. H5 标准提供给我们的 API:

 => 元素身上有一个属性叫 classList
 => 里面包含了所有元素什么设置的类名,可直接查看
 => 这个 classList 提供了一系列方法来操作
   1. add()
     => 语法:元素.classList.add('你要添加的类名')
   2. remove()
     => 语法:元素.classList.remove('你要移除的类名')
   3. toggle()
     => 语法:元素.classList.toggle('你要切换的类名')
     => 当元素有这个类名的时候,就删除
     => 当元素没有这个类名的时候,就添加
<style>
   div{ 
       width: 100%; 
       height: 50px; 
       /* background-color: skyblue;
       display: none; */
       position: absolute;
       top: -50px;
       left: 0;
       background-color: skyblue;
       transition: .5s linear;
   }

   div.box{ 
       /* background-color: pink;
       display: block; */
       top: 0;
   }

   button{
       margin-top: 100px;
   }
</style>
<button>按钮</button>
<div class="a b c d e f g h i j">我是 div 标签</div>

// 获取元素
var div = document.querySelector('div');

// 2. H5 方式操作类名
// 2-1. 添加类名
div.classList.add('box');

// 2-2. 删除类名
div.classList.remove('h');

// 2-3. 切换类名
var btn = document.querySelector('button');
btn.onclick = function(){
    // 执行这句代码的时候,如果 div 没有 box 类名,就添加
    // 执行这句代码的时候,如果 div 有 box 类名,就删除
    div.classList.toggle('box');
}
console.log(div.classList);

在这里插入图片描述
在这里插入图片描述

操作元素文本内容

+ 分成三种
  1. innerHTML
  2. innerText
  3. value

innerHTML

+ 一个读写的属性
+ 操作元素的超文本内容
+ 读:获取元素内部的所有内容
  => 文本 + 标签全部内容
  => 以字符串的形式返回
  => 语法:元素.innerHTML
+ 写:设置元素内部的超文本内容
  => 完全覆盖式的书写
  => 语法: 元素.innerHTML = '你要设置的内容'
  => 当你的字符串里面出现 html 结构的时候,会自动解析
<div>
    hello world
    <p>你好 世界</p>
    hello world
</div>
// 获取元素
var div = document.querySelector('div');

// 1. innerHTML
// 1-1. 获取元素的超文本内容
var str = div.innerHTML;
console.log(str);
console.log(typeof str);   // string

// 1-2. 设置元素的超文本内容
div.innerHTML = '<span>我是新来的内容</span>';

在这里插入图片描述
在这里插入图片描述

innerText

+ 一个读写的属性
+ 操作元素的文本内容
+ 读:获取元素内部的所有文本内容
  => 包括子元素所有后代元素里面的文本内容
  => 标签内容不获取
  => 语法:元素.innerText
+ 写:设置元素内部的文本内容
  => 完全覆盖式的写入
  => 语法:元素.innerText = '你要设置的值'
  => 当你的字符串里面出现 html 结构的时候,不会自动解析,原样输出
<div>
    hello world
    <p>你好 世界</p>
    hello world
</div>
// 获取元素
var div = document.querySelector('div');

// 2. innerText
// 2-1. 获取元素的文本内容
var str = div.innerText;
console.log(str);

// 2-2. 设置元素的文本内容
div.innerText = '<span>我是新来的内容</span>';

在这里插入图片描述在这里插入图片描述

value

+ 一个读写的属性
+ 操作表单元素的 value 属性
+ 读:获取表单元素的 value 值
  => 语法:元素.value
+ 写:设置表单元素的 value 值
  => 语法:元素.value = '你要设置的值'
// 3. value 属性
// 3-2. 设置元素的 value 值
inp.value = '你好 世界';

// 3-1. 获取元素的 value 值
var str = inp.value;
console.log(str);

在这里插入图片描述

案例

全选

<div class="box">
    <div class="all">
        全选:<input type="checkbox">
    </div>
    <hr>
    <div class="items">
        选项一:<input type="checkbox"> <br>
        选项二:<input type="checkbox"> <br>
        选项三:<input type="checkbox"> <br>
        选项四:<input type="checkbox"> <br>
    </div>
</div>

<script>
    /*
      全选

      分析业务逻辑
        1. 点击全选按钮的时候
          => 如果全选按钮是选中,那么每一个选项按钮也被选中
          => 如果全选按钮是未选中,那么每一个选项按钮都是未选中
        2. 每一个选项按钮点击的时候
          => 如果所有的选项按钮都是选中,那么全选按钮选中
          => 只要有任意一个选项按钮未选中,那么全选按钮未选中

      代码:
        1. 获取元素
          => 全选按钮
          => 所有的选项按钮
        2. 给全选按钮添加一个点击事件
          => 获取全选按钮的选中状态
          => 使用 checked 原生属性
          => 循环遍历 itemBtns,给里面的每一个 input
          设置 checked 属性
          => 我自己是什么,就给他们设置成什么
        3. 给 itemBtns 里面的每一个添加点击事件
          => 每一个按钮的点击,都需要判断是不是所有的按钮都是选中
          => 遍历 itemBtns,判断里面每一个是不是都是选中的状态
            -> 做一个假设变量,假设所有的都是选中
            -> 循环遍历
            -> 只要有任意一个不是选中的,那么把我的假设否定掉
            -> 结束循环
          => 根据我判断的 flag 值给全选按钮设置选中状态
    */

    // 1. 获取元素
    var allBtn = document.querySelector('.all > input');
    // querySelectorAll 方法获取的元素集合可以用 forEach,这是它自带的方法,而非数组常用方法的 forEach
    var itemBtns = document.querySelectorAll('.items > input');

    // console.log(allBtn);
    // console.log(itemBtns);

    // 2. 给全选按钮添加点击事件
    allBtn.onclick = function(){
        // 2-2. 获取自己的状态
        var type = allBtn.checked;
        // console.log(type);

        // 2-3. 循环遍历 itemBtns 给他们设置
        // for(var i = 0; i < itemsBtn.length; i++){
        //     itemBtns[i].checked = type;
        // }
        itemBtns.forEach(function(item){
            item.checked = type;
        });
    };

    // 3. 给每一个选项按钮添加点击事件
    itemBtns.forEach(function(item){

        // 添加点击事件
        item.onclick = function(){

            // 3-2. 判断是不是每一个都是选中的  
            var flag = true;
            itemBtns.forEach(function(item){
                if(!item.checked) flag = false;
            });  
            // 3-3. 给全选按钮设置选中状态
            // flag === true, 表示全都选中,全选按钮选中
            // flag === false, 表示没有全部选中,全选按钮未选中
            allBtn.checked = flag;           
        };
    });

在这里插入图片描述
在这里插入图片描述

选项卡

使用for循环

/*
选项卡(tab 切换)

  分析业务逻辑
    1. 给每一个 ul 下面的 li 绑定点击事件
      => 在点击事件里面
        -> 切换自己的类名
        -> 让 ol > li 索引配套的那一个有类名
      => 当你点击 [0] 的按钮的时候,[1][2]按钮没有active
        -> [0]盒子有 active, [1] [2]的盒子有active
      => 当你点击 [1] 的按钮的时候, [0][2]按钮没有 active
        -> [1]盒子有 active, [0] [2]的盒子有active
      => 当你点击 [2] 的按钮的时候, [0][1]按钮没有 active
        -> [2]盒子有 active, [0] [1]的盒子有active
  代码实现:
    1. 获取元素
      => ul > li,为了点击事件,切换类名
      => ol > li,切换类名
    2. 给每一个 btns 里面的 li 添加点击事件
      => for 循环
      => 出现问题:
        1. 在点击事件里面不知道你点击的是哪一个 li?
        2. 在点击事件里面不知道你点击的那一个 li 索引是多少?
      => 分析问题:
        1. 当你点击的时候,循环已经结束了
        2. 因为元素身上并没有和索引相关的内容
      =>  解决问题:
        1. 在事件处理函数里面使用 this
          => 谁身上的事件,this 就是谁
        2. 在循环的时候因为要遍历到每一个 li
          => 记录一个自定义属性在每一个 li 身上,属性值记录 索引
          => setAttribute()
    3. 点击事件里面的操作
      => 按钮:
        -> 让所有的 按钮 没有 active 类名
        -> 只给我当前点击的 li 添加 active 类名
      => 切换盒子
        -> 让所有的 盒子 没有 active 类名
        -> 让索引配套的这个 盒子 有 active 类名
        -> 我点击的这个 li 身上有一个自定义属性 index 记录着索引
        -> 使用 getAttribute() 拿到就可以了
*/

// 1. 获取元素
// 所有按钮
var btns = document.querySelectorAll('ul > li')
// 切换盒子
var tabs = document.querySelectorAll('ol > li')

// 2. 循环遍历
for(var i = 0; i < btns.length; i++){

  // 给每一个 li 添加一个自定义属性 index
  btns[i].setAttribute('index', i)
  // 给每一个 li 绑定点击事件
  btns[i].onclick = function(){
    // console.log(i);   // for循环出现问题1:打印的都是 3
    // console.log(btns[i]);   // for循环出现问题1:打印的都是 undefined, 因为btns的length只有3,最大索引只有2
    // console.log(this);   // 正确是用 this

    // 3-1. 让 btns 里面的每一个 li 没有 active 类名
    for(var j = 0; j < btns.length; j++){
      btns[j].className = ''
      console.log(btns)
    }

    // 3-2. 让当前点击的这个 li 有 active 类名
    // this 就是当前点击的这个 li
    this.className = 'active'
    // this.classList.add('active')

    // 3-3. 让 tabs 里面的每一个 li 没有 active 类名
    for(var k = 0; k < tabs.length; k++){
      tabs[k].className = ''
    }

    // 3-4. 让 tabs 里面索引配套的那一个 li 有 active 类名
    // 拿到我点击的 li 身上记录的索引
    var index = this.getAttribute('index') - 0;
    // 让 tabs 里面第 index 个有 active 类名
    tabs[index].className = 'active'
  }
}

  // for循环出现的问题1解释:
  /*
    函数的执行
      函数里面涉及到变量的时候
      在定义的时候是不解析变量,就是按照变量名保存
      只有当执行的时候,才会解析变量
  */
//  var num = 100;
//  function fn(){
//      // 如果函数定义阶段就解析了变量,那么存储的代码 console.log(100)
//      // 如果函数是在调用阶段解析了变量,那么存储的代码 console.log(num)
//      console.log(num);
//  }
//  num = 200;
//  fn();   // 200

/*
  全局变量 i = 0
    循环第一次
     btn[0].onclick = function(){console.log(i)}
     i++
    循环第二次
     btn[1].onclick = function(){console.log(i)}
     i++
    循环第三次
     btn[2].onclick = function(){console.log(i)}
     i++
     循环结束

     当你点击 [0] 的 li 的时候,执行的是第 [0] 个li的事件处理函数
       -> console.log(i)
       -> 自己没有 i 向上查找,找到全局 i,打印3
     当你点击 [1] 的 li 的时候,执行的是第 [1] 个li的事件处理函数
       -> console.log(i)
       -> 自己没有 i 向上查找,找到全局 i,打印3
     当你点击 [2] 的 li 的时候,执行的是第 [2] 个li的事件处理函数
       -> console.log(i)
       -> 自己没有 i 向上查找,找到全局 i,打印3

    this 问题
      当你点击 [0] 的时候触发的是第 [0] 个 li 身上的事件处理函数
        -> this:谁身上的事件处理函数,this就是谁,这里就是 [0] 的那一个 li
      当你点击 [1] 的时候触发的是第 [1] 个 li 身上的事件处理函数
        -> this:谁身上的事件处理函数,this就是谁,这里就是 [1] 的那一个 li
      当你点击 [2] 的时候触发的是第 [2] 个 li 身上的事件处理函数
        -> this:谁身上的事件处理函数,this就是谁,这里就是 [2] 的那一个 li
*/

优化:
把俩 for 循环写一起

for(var j = 0; j < btns.length; j++){
btns[j].className = ''
tabs[j].className = ''
}

使用forEach循环

/*
代码实现:
     1. 获取元素
       => ul > li,为了点击事件,切换类名
       => ol > li,切换类名
     2. 给每一个 btns 里面的 li 添加点击事件
       => forEach 遍历
     3. 事件处理函数里面的操作
       => 循环遍历让每一个 btns 和 tabs 里面的 li 没有类名
       => 让点击的这个 li 有 active 类名
       => 让 tabs 里面索引配套的那一个 li 有 active 类名
*/

// 1. 获取元素
// 所有按钮
var btns = document.querySelectorAll('ul > li')
// 切换盒子
var tabs = document.querySelectorAll('ol > li')

// 2. 遍历 btns
btns.forEach(function fn(item, index){

  // 给 btns 里面的每一个 li 添加点击事件
  item.onclick = function(){
    // 事件处理函数里面,item 就是你点击的这个 li
    // index 就是你点击的这个 li 的索引

    // 3-1. 取消类名
    tabs.forEach(function(t, i){
      t.className = ''
      btns[i].className = ''
    })

    // 3-2. 添加类名
    item.className = 'active'
    tabs[index].className = 'active'
  }
})

/*
  在循环的过程中
    => 你给 forEach 传递的那个 fn 函数会重复执行
    => fn 执行第一次
      -> 有一个自己的私有空间
      -> item 赋值为 li[0]
      -> index 赋值为 0
      -> li[0].onclick = function(){}
    => fn 执行第二次
      -> 有一个自己的私有空间
      -> item 赋值为 li[1]
      -> index 赋值为 1
      -> li[1].onclick = function(){}
    => fn 执行第三次
      -> 有一个自己的私有空间
      -> item 赋值为 li[2]
      -> index 赋值为 2
      -> li[2].onclick = function(){}
    
    当你点击 [0] 的 li 的时候,执行的是 第 [0] 个 li 的事件处理函数
      => fn 第一次执行的空间里面的 事件处理函数
      => item 和 index
      => 事件处理函数自己没有,就去 fn 第一次执行的空间里面查找
    当你点击 [1] 的 li 的时候,执行的是 第 [1] 个 li 的事件处理函数
      => fn 第二次执行的空间里面的 事件处理函数
      => item 和 index
      => 事件处理函数自己没有,就去 fn 第二次执行的空间里面查找
    当你点击 [2] 的 li 的时候,执行的是 第 [2] 个 li 的事件处理函数
      => fn 第三次执行的空间里面的 事件处理函数
      => item 和 index
      => 事件处理函数自己没有,就去 fn 第三次执行的空间里面查找
*/

在这里插入图片描述

回到顶部

<style>
    *{
        margin: 0;
        padding: 0;
    }

    body{
        height: 2000px;
    }
    .topBar{
        width: 100%;
        height: 50px;
        line-height: 50px;
        text-align: center;
        color: #fff;
        background-color:skyblue;
        position: fixed;
        font-size: 30px;
        left: 0;
        top: 0;

        display: none;
    }

    .topBar.active{
        display: block;
    }

    .goTop{
        width: 50px;
        height: 50px;
        line-height: 25px;
        font-size: 20px;
        color: #fff;
        background-color: pink;
        position: fixed;
        bottom: 50px;
        right: 50px;
        text-align: center;

        display: none;
    }

    .goTop.active{
        display: block;
    }
</style>
</head>
<body>
<div class="topBar">顶部通栏</div>
<div class="goTop">回到顶部</div>
<script>
    /*
      回到顶部

      代码实现:
        1. 获取元素
          => 顶部通栏
          => 回到顶部按钮
        2. 操作两个盒子显示和隐藏
          => 使用 window.onscroll 事件
          => 在事件里面随时获取浏览器卷去的高度
          => 通过卷去的高度判断(自己定义一个边界值)
          => 操作显示
            -> 添加类名 active
          => 操作隐藏
            -> 取消类名 active
          => 用哪种方式
            1. className - 好加不好去
            2. classList - 随便
        3. 点击回到顶部按钮的时候,滚动条回到顶部
          => 给 goTop 按钮绑定一个点击事件
          => 在事件处理函数里面使用 scrollTo()
    */

    // 1. 获取元素
    var topBar = document.querySelector('.topBar')
    var goTop = document.querySelector('.goTop')
   
    // 2. 操作两个盒子显示隐藏
    window.onscroll = function(){
        // 2-1. 获取浏览器卷去的高度
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop

        // 2-2. 自己定一个边界值进行判断(300)
        if(scrollTop >= 300){
            // 两个盒子显示
            topBar.classList.add('active')
            // topBaor.className = 'topBar active'
            goTop.classList.add('active')
        }else{
            // 两个盒子隐藏
            topBar.classList.remove('active')
            // topBar.className = 'topBar'
            goTop.classList.remove('active')
        }
    }
    
    // 3. 回到顶部
    goTop.onclick = function(){
        window.scrollTo({
            top: 0,
            behavior: 'smooth'
        })
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值