只因小黑子的JavaScript入土过程第四章

小黑子的JavaScript入土过程第四章

JavaScript系列教程第四章

4.1 初识DOM

在这里插入图片描述

4.1.1 获取一个元素

通过 js 代码来获取页面中的标签
获取到以后我们就可以操作这些标签了

  <script>
    console.log(document.documentElement)//获取html的标签
    console.log(document.head)//获取head的标签
    console.log(document.body)//获取body的标签
  </script>

在这里插入图片描述

4.1.2 非常规的标签获取

一、getElementById(id获取)

因为在一个页面中 id 是唯一的,所以获取到的就是一个元素

  <div id="obox"></div>
  <script>
  	var obox = document.getElementById('obox')//字符串
  	console.log(obox)
  </script>

在这里插入图片描述

获取到的就是页面中的那个 id 为 obox 的 div 标签

二、getElementsByClassName(class获取)
> 因为页面中可能有多个元素的 class 名称一样,所以获取到的是一组元素

> 哪怕你获取的 class 只有一个,那也是获取一组元素,只不过这一组中只有一个 DOM 元素而已

> 获取到的是一组元素,是一个长得和数组一样的数据结构,但是不是数组,是 伪数组,有length的属性

> 这个一组数据也是按照索引排列的,所以我们想要准确的拿到这个 li,需要用索引来获取

> 即返回值是一个伪数组
  <ul>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
  </ul>
  <script>
  	var item = document.getElementsByClassName("newsitem")
    console.log(item.fillter)//无定义,是伪数组

    // item[0].innerHTML="news-11111"可以用其改变第一个li的值为news-11111
    for(var i=0;i<item.length;i++)
    {
      item[i].innerHTML ="news-"+i
    }//利用for循环对每个li的值进行顺序修改
  </script>

在这里插入图片描述
可以利用set结构的Array.form属性来使伪数组转化为真数组

    var newitem = Array.from(item)//将伪数组转换为真数组
    console.log(newitem.map)
三、getElementsByTagName(标签名获取)

getElementsByTagName 是用过标签的标签名称来获取标签的

因为页面中可能有多个元素的 标签 名称一样,所以获取到的是一组元素

哪怕真的只有一个这个标签名,那么也是获取一组元素,只不过这一组中只有一个 DOM 元素而已

和 getElementsByClassName 一样,获取到的是一个长得很像数组的元素

必须要用索引才能得到准确的 DOM 元素

  <ul>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
    <li class="newsitem">11111</li>
  </ul>
  <ul>
    <li class="aditem">11111</li>
    <li class="aditem">11111</li>
    <li class="aditem">11111</li>
    <li class="aditem">11111</li>
    <li class="aditem">11111</li>
    <li class="aditem">11111</li>
  </ul>
  <script>
    var item =document.getElementsByTagName("li")//找到标签一样的全部显示
    console.log(item)
  </script>

在这里插入图片描述

四、getElementsByName(name属性获取)

一般只适用于input标签

  <input type="text" name="username">
  <input type="password" name="password">
  <script>
    var item = document.getElementsByName("username")
    console.log(item[0])
    item[0].value = "steve"
  </script>

在这里插入图片描述

五、querySelector(选择器获取,返回一个)

有兼容性问题,不过现在基本上没太大问题

querySelector 是按照选择器的方式来获取元素
也就是说,按照我们写 css 的时候的选择器来获取
这个方法只能获取到一个元素,并且是页面中第一个满足条件的元素

  <ul>
    <li>111</li>
    <li>111</li>
    <li>111</li>
    <li>111</li>
    <li>111</li>
  </ul>
  <script>
    var item = document.querySelector("ul li")
    console.log(item)
  </script>

在这里插入图片描述

六、querySelectorAll(选择器获取,返回所有满足条件的)

也有兼容性问题,不过现在基本上没太大问题

querySelectorAll 是按照选择器的方式来获取元素
这个方法能获取到所有满足条件的元素,以一个伪数组的形式返回
获取到的是一组数据,也是需要用索引来获取到准确的每一个 DOM 元素

  <ul>
    <li class="newsitem">111</li>
    <li class="newsitem">111</li>
    <li class="newsitem">111</li>
    <li class="newsitem">111</li>
    <li class="newsitem">111</li>
    <li class="newsitem">111</li>
    <li>111</li>
  </ul>
  <script>
    var item = document.querySelectorAll("ul li.newsitem")
    console.log(item)
  </script>

在这里插入图片描述

4.2 操作元素属性

我们通过各种获取元素的方式获取到页面中的标签以后
可以直接操作 DOM 元素的属性,就能直接把效果展示在页面上

4.2.1 元素自带(原生)属性

可以通过class或id来直接操作原生的属性

  <div id="box" kerwin="hello">hello</div>
  <input type="text" value="hello" id="username">
  <input type="checkbox" checked id="rember">

  <script>
    box.innerHTML ="22222"
    username.type = "password"
    rember.checked = false
  </script>

原本的属性在sript中被修改了

4.2.2 自定义属性

一、setAttribute ,getAttibute ,removeAttibute

添加自定义属性setAttribute
在这里插入图片描述

获取自定义属性getAttibute
在这里插入图片描述

删除自定义属性removeAttibute
在这里插入图片描述
案例:

  <ul>
    <li>11111</li>
    <li >2222</li>
    <li >3333</li>
    <li ">44444</li>
  </ul>
  <script>
    var item = document.getElementsByTagName("li")//获取li
    for(var i=0;i<item.length;i++)
    {
      item[i].setAttribute("van",i)
    }
  </script>

利用for循环将每个li赋予顺序的自定义属性
在这里插入图片描述

二、dataset属性

利用dataset属性可以获取和设置自定义属性

删除自定义属性
delete 名字.自定义属性
在这里插入图片描述
案例:

  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
    var item=document.getElementsByTagName("li")
    for(var i=0;i<item.length;i++){
        item[i].dataset.tiechui=i
    }
</script>

在这里插入图片描述

4.3 密码可视案例

  <input type="password" id="password">
  <button id="eyebtn">eye</button>
  <script>
    var passinput = document.getElementById("password")
    var eyebtn = document.querySelector("#eyebtn")
    eyebtn.onclick = function () {
      console.log(passinput.type)

      if (passinput.type == "password") 
      {
        passinput.type = "text"
      } 
      else 
      {
        passinput.type = "password"
      }
    }
  </script>

点击前
在这里插入图片描述
点击后
在这里插入图片描述

4.4 购物车全选案例

  <input type="checkbox" id="all">全选/全不选
  <hr>
  <ul class="shop">
    <li>
      <input type="checkbox">商品1
    </li>
    <li>
      <input type="checkbox">商品2
    </li>
    <li>
      <input type="checkbox">商品3
    </li>
    <li>
      <input type="checkbox">商品4
    </li>
  </ul>

  <script>
    var oAll = document.querySelector("#all")
    var item = document.querySelectorAll(".shop input")

    oAll.onclick = function () 
    {
      console.log(oAll.checked)
      for (var i = 0; i < item.length; i++) 
      {
        item[i].checked = oAll.checked
      }//利用for循环实现全选选框给每个li顺序赋与选上,当全选或不选时所以相应
    }

    //每点其中的任何一项,都可以把四个循环一遍,看看里面是否被勾选
    //如果被勾,在以count为0的基础上加1,每点一个,都把count值重新赋值成0
    //再次地开始循环一下这四个,把里面勾了的数量找出来,加加
    for (var i = 0; i < item.length; i++) 
    {
      item[i].onclick = handler//这个for循环只是给每个li赋值一个函数
    }

    function handler() //每次li勾选这个函数,count都为0,开始循环判断被选上的count加加
    {
      var count = 0

      for (var i = 0;i<item.length; i++) 
      {
        if (item[i].checked) 
        {count++}
      }//for判断每一项如果checked count++

      if (count === item.length) //如果count自增到了整个数组一样就相当于每个li用户全选了
      {
        oAll.checked = true//li全选了那么就控制全选框也勾选上
      }
      else 
      {
        oAll.checked = false
      }
    }
  </script>

在这里插入图片描述

4.5 操作元素文本内容

4.5.1 innerHTML获取元素内部的 HTML 结构(所有内容)

   <div id="box">
    <span>hello</span>
    <div>steve</div>
  </div>

  <script>
    console.log(box.innerHTML)
    box.innerHTML="<h1>111111</h1>"//将box里的文本全部改成111,并且解析HTEML
  </script>

在这里插入图片描述

4.5.1innerText 获取元素内部的文本(只能获取到文本内容,获取不到 html 标签)

  <div id="box">
    <span>hello</span>
    <div>steve</div>
  </div>

  <script>
    console.log(box.innerText)//获取只有文本
    box.innerText = "<h1>111111</h1>"//不解析HTML
  </script>

在这里插入图片描述

4.5.1 value

可以读取,也可以赋值,大多时候用于表单元素

  <input type="text" id="username" value="hello">
  <select name="" id="select">
    <option value="1">11111</option>
    <option value="2" selected>22222</option>
    <option value="3">33333</option>
  </select>
  <script>
    console.log(username.value)
    username.value = "22222"
    console.log(select.value)
  </script>

在这里插入图片描述

4.6 渲染页面案例

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

    ul {
      list-style: none;
    }

    li {
      overflow: hidden;
    }

    li img {
      float: left;
      width: 200px;
      height: 200px;
    }
  </style>
  <ul>
    <!-- <li>
            <img src="" alt="">
            <h3></h3>
            <p></p>
        </li> 这样写不利于后面更新改写-->
  </ul>
  <script>
    var filmlist = [
      {
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100",
        title: "神奇麻瓜",
        grade: "7.4",
      },
      {
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100",
        title: "神奇麻瓜",
        grade: "7.4",
      },
      {
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100",
        title: "神奇麻瓜",
        grade: "7.4",
      },
    ]

    var newfilmitem = filmlist.map(function (item) 
    {//用map映射可以把数组映射成想要的结构,把每个item进来函数之后变成了同一个li结构
      return `<li>
            <img src="${item.url}" alt="">
            <h3>${item.title}</h3>
            <p>${item.grade}</p>
          </li>`//因为要后期要改的数据不一样,所以要用${}可以替换后台的变量
    })

    console.log(newfilmitem.join(""))//通过数组转换成字符串,就可以链接起来

    var oul = document.querySelector("ul")//通过获取ul的方式
  
    oul.innerHTML = newfilmitem.join("")//通过能解析的innerHTML就可以变除图片了
  </script>

在这里插入图片描述

4.7 操作元素样式

4.7.1 获取行间样式-行内样式方法

容易进行读写,更改样式数值
访问和更改复合样式时,不能使用常规的方法来获取
有以下两种方法

// 使用[](中括号)
// 使用驼峰式命名法
  <style>
    #box {
      height: 100px;
      background-color: yellow;
    }
  </style>

  <div id="box" style="width: 100px;color: black; background-color: yellow;">111111</div>

  <script>
    console.log(box.style.width)
    console.log(box.style.height)
    // 访问复合样式时,不能使用常规的方法来获取
    // 有以下两种方法

    // 使用[](中括号)
    // 使用驼峰式命名法
    console.log(box.style["background-color"])
    console.log(box.style.backgroundColor)

    box.style.width = "200px"
    box.style.backgroundColor = "red"//或者box.style["background-color"]
  </script>

改前
在这里插入图片描述
改后
在这里插入图片描述

4.7.2 获取的非行间样式getComputedstyle 获取

内部样式,外部样式,行内getComputedstyle 获取,不能用于赋值修改样式

可以获取,但是不能更改样式,可以读取

在操作 DOM 的时候,很重要的一点就是要操作元素的 css 样式

那么在操作 css 样式的时候,我们避免不了就要获取元素的样式

之前说过可以用 元素.style.xxx 来获取

但是这个方法只能获取到元素行间样式,也就是写在行内的样式
  <style>
    #box {
      height: 100px;
      background-color: yellow;
    }
  </style>

  <div id="box" style="width: 100px;color: black; background-color: yellow;">111111</div>

  <script>
    var obox = document.getElementById("box")//严格获取obox放到下面函数作参数
    console.log(getComputedStyle(obox).height)
    console.log(getComputedStyle(obox).width)
    console.log(getComputedStyle(obox)["background-color"])
    console.log(getComputedStyle(obox).backgroundColor)
  </script>

在这里插入图片描述

4.8 操作元素类名

4.8.1 .className用来读取和赋值html里的class值

专门用来操作元素的类名

  <style>
   .item{
    width: 100px;
    height: 100px;
    background-color: red;
    color: black;
    border-radius: 10px;
   }
  </style>
  <div id="box" class="item item1 item2">16116</div>
  <script>
    box.className = ""
    //box.className = "item"可以设置留下几个属性,或者新建属性
    console.log(box.className)
  </script>

在这里插入图片描述

4.8.1 .classList用来读取和赋值html里的class值,但是是以伪数组的形式来读取或修改

一、.add()增加class值,不会添加相同的class值,一次只能添加一个值
二、.remove()删除class值
  <style>
   .item{
    width: 100px;
    height: 100px;
    background-color: red;
    color: black;
    border-radius: 10px;
   }
  </style>
  <div id="box" class="item item1 item2">16116</div>
  <script>
    console.log(box.classList)

    box.classList.add("item3")//.add()增加class值,不会添加相同的class值,一次只能添加一个值
    console.log(box.classList)
    
    box.classList.remove("item")//.remove()删除class值
    console.log(box.classList)
  </script>

在这里插入图片描述

三、toggle 切换

如果原本有这个class值,就会删除这个class值,如果没有,就会添加上这个class值
应用点击实现删除再现效果:

  <style>
   .item{
    width: 100px;
    height: 100px;
    background-color: red;
    color: black;
    border-radius: 10px;
   }
  </style>
  <div id="box" class="item item1 item2">16116</div>
  <button id="btn">wdnmd</button>
  <script>
    btn.onclick = function(){
      box.classList.toggle("item")
    }
  </script>

点击前
在这里插入图片描述
点击后
在这里插入图片描述

4.9 选项卡案例

4.9.1 简易选项卡原理

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

    ul {
      display: flex;
      list-style: none;
    }

    li {
      height: 50px;
      line-height: 50px;
      text-align: center;
      flex: 1;
    }

    .active {
      color: red;
      border-bottom: 1px solid red;
    }
  </style>
  <ul>
    <!-- 实现点击不同的li有下划线切换 -->
    <li class="active" id="item1">正在上映</li>
    <li id="item2">即将上映</li>
  </ul>
  <script>
    // 实现点击不同的li有下划线切换
    item1.onclick = function () {
      item1.classList.add("active")
      item2.classList.remove("active")
    }
    item2.onclick = function () {
      item1.classList.remove("active")
      item2.classList.add("active")
    }
  </script>

在这里插入图片描述

4.9.2 复杂选项卡

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

    ul {
      list-style: none;
    }

    .header {
      display: flex;
      width: 500px;
      margin: 0 auto;
    }

    .header li {
      flex: 1;
      height: 50px;
      line-height: 50px;
      text-align: center;
      border-bottom: 1px solid black;
    }

    .box {
      width: 500px;
      position: relative;
      margin: 0 auto;
    }

    .box li {
      position: absolute;
      left: 0;
      top: 0;
      width: 500px;
      height: 200px;
      background-color: yellow;
      display: none;
    }

    .header .active {
      background-color: red;
    }

    .box .active {
      display: block;
      /* 与li的display: none呼应,实现点击切换的效果 */
    }
  </style>

  <ul class="header">
    <li class="active">1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>
  <ul class="box">
    <li class="active">1111</li>
    <li>2222</li>
    <li>3333</li>
    <li>4444</li>
  </ul>

  <script>
    var oheaderitem = document.querySelectorAll(".header li")
    var oboxitem = document.querySelectorAll(".box li")
    // for (var i = 0; i< oheaderitem.length; i++ )
    // {
    //  oheaderitem[i].onclick = function () 
    //   {
    //     console.log(i)
    //   }
    // }由于单线程和人的手速没有这么快,导致for循环执行的比onclick这个事件快,进而i就会变成4,就有点像异步执行,不采用 

    for (var i = 0; i < oheaderitem.length; i++)
     {
      //在for循环中,给每个头部li设置自定义属性加索引,在点击时获取属性给外部函数执行
      oheaderitem[i].dataset.index = i
      //为了防止没点之前就执行完,将点击执行在外部
      oheaderitem[i].onclick = handler
    }
    //在外部定义好
    function handler() 
    {
      var index = this.dataset.index //this实现点击返回的是当前这一项,再利用dataset.index就可以知道点击时,是第几个
      for (var j = 0; j < oheaderitem.length; j++) //要给第几个加active,又要记住对上一个的actibe进行移除,太麻烦。对每一个的active先移除一遍,在点击时加active就行了
      {
        oheaderitem[j].classList.remove("active")
        oboxitem[j].classList.remove("active")
      }

      oheaderitem[index].classList.add("active")
      oboxitem[index].classList.add("active")
    }
  </script>

在这里插入图片描述

4.10 DOM节点

DOM 的节点我们一般分为常用的三大类 元素节点 / 文本节点 / 属性节点

什么是分类,比如我们在获取元素的时候,通过各种方法获取到的我们叫做元素节点(标签节点)

比如我们标签里面写的文字,那么就是文本节点

写在每一个标签上的属性,就是属性节点
在这里插入图片描述

4.10.1 元素节点

我们通过 getElementBy… 获取到的都是元素节点
在这里插入图片描述
在这里插入图片描述

4.10.2 属性节点

我们通过 getAttribute 获取的就是元素的属性节点
在这里插入图片描述

4.10.3 文本节点

我们通过 innerText 获取到的就是元素的文本节点
在这里插入图片描述

4.10.4 注释节点

在这里插入图片描述
例子:
在这里插入图片描述
上面div中有5个节点

4.11 获取节点的方式

4.11.1 childNodes:获取某一个节点下所有的子一级节点

  <div>
    <p>hello</p>
  </div>
  
  <script>
    // 这个 Div 获取的是页面中的 div 元素,就是一个元素节点
  	var Div = document.querySelector('div')  
    console.log(Div.childNodes) 
  </script>
拿到以后是一个伪数组,里面有三个节点
一个 text:从 <div> 一直到 <p> 中间有一个换行和一堆空格,这个是第一个节点,是一个文本节点
一个 p:这个 p 标签就是第二个节点,这个是一个元素节点
一个 text:从 </p> 一直到 </div> 中间有一个换行和一堆空格,这个是第三个节点,是一个文本节点
这个时候就能看到我们有不同的节点类型了

在这里插入图片描述

4.11.2 children :获取某一节点下所有的子一级 元素节点

上例加

 console.log(Div.children) 

在这里插入图片描述

只有一个节点了,因为 children 只要元素节点
div 下面又只有一个元素节点,就是 p
所以就只有一个,虽然只有一个,但是也是一个伪数组

4.11.3 firstChild:获取某一节点下子一级的 第一个节点

上例加

console.log(Div.firstChild) 
这个是只获取一个节点,不再是伪数组
获取的是第一个
第一个就是 <div> 一直到 <p> 的那个换行和空格,是文本节点

在这里插入图片描述

4.11.4 firstElementChild:获取某一节点下子一级 第一个元素节点

上例加

console.log(Div.firstElementChild) 
只获取一个节点,不在是伪数组
获取的是第一个 元素节点
第一个元素节点就是 p 标签,是一个元素节点

在这里插入图片描述

4.11.5 lastChild:获取某一节点下子一级的 最后一个节点

上例加

console.log(Div.lastChild) 
只获取一个节点,不再是伪数组
获取的是最后一个
最后一个就是 </p> 一直到 </div> 之间的换行和空格,是个文本节点

在这里插入图片描述

4.11.6 lastElementChild:获取某一节点下子一级 最后一个元素节点

  <div>
    <p>hello</p>
    <p>22222</p>
  </div>
  
  <script>
  	var Div = document.querySelector('div')  
    console.log(Div.lastChild) 
  </script>
只获取一个节点,不再是伪数组
获取的是最后一个元素节点
最后一个元素节点是 <p>22222</p>,是一个元素节点

在这里插入图片描述

4.11.7 previousSibling:获取某一个节点的 上一个兄弟节点

  <ul>
    <li id="a">11111</li>
    <li id="b">22222</li>
    <li id="c">33333</li>
  </ul>
  
  <script>
  	var Li = document.querySelector('#b')
    
    console.log(Li.previousSibling)
  </script>
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的上一个兄弟节点
因为 id="b" 的上一个节点,是两个 li 标签之间的换行和空格,所以是一个文本节点

在这里插入图片描述

4.11.8 previousElementSibling:获取某一个节点的 上一个元素节点

上例加

console.log(Li.previousElementSibling) 
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的上一个兄弟元素节点
因为 id="b" 的上一个兄弟元素节点就是 id="a" 的 li,是一个元素节点
parentNode

在这里插入图片描述

4.11.9 nextSibling:获取某一个节点的下一个兄弟节点

上例加

console.log(Li.nextSibling) 
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的下一个兄弟节点
因为 id="b" 的下一个节点,是两个 li 标签之间的换行和空格,所以是一个文本节点

在这里插入图片描述

4.11.10 nextElementSibling:获取某一个节点的 下一个元素节点

上例加

console.log(Li.nextElementSibling) 
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的下一个兄弟元素节点
因为 id="b" 的下一个兄弟元素节点就是 id="c" 的 li,是一个元素节点

在这里插入图片描述

4.11.11 parentNode:获取某一个节点的父节点

上例加

console.log(Li.parentNode) 
只获取一个节点,不是伪数组
获取的是当前这个 li 的父元素节点
因为这个 li 的父亲就是 ul,所以获取到的就是 ul,是一个元素节点

在这里插入图片描述

4.11.12 parentElement:获取父一个节点的元素

上例加

  console.log(Li.parentElement.parentElement) 

在这里插入图片描述

4.11.13 attributes:获取某一个元素节点的所有属性节点

上例加

    console.log(Li.attributes)

获取的是一组数据,是该元素的所有属性,是一个伪数组
在这里插入图片描述

4.12 节点操作

我们所说的操作无非就是 增删改查
创建一个节点(因为向页面中增加之前,我们需要先创建一个节点出来)
向页面中增加一个节点
删除页面中的某一个节点
修改页面中的某一个节点
获取页面中的某一个节点

4.12.1 创建一个节点

一、createElement:用于创建一个元素节点
  <div id="box">
    <div id="child">111111</div>
  </div>

  <script>
    var odiv = document.createElement("div")
    odiv.innerHTML = "我是新创建的节点"
    console.log(odiv)
  </script>

在这里插入图片描述

二、createTextNode:用于创建一个文本节点

4.12.2 向页面中增加一个节点

四、appendChild:是向一个元素节点插入一个节点
  <div id="box">
    <div id="child">111111</div>
  </div>

  <script>
    var odiv = document.createElement("div")
    odiv.innerHTML = "我是新创建的节点"
    odiv.id="aaa"
    odiv.style.background="yellow"
    console.log(odiv)

    box.appendChild(odiv)
  </script>

在这里插入图片描述

五、insertBefore:向某一个节点前插入一个节点

上例代码将 box.appendChild(odiv)改成如下

 box.insertBefore(odiv)

在这里插入图片描述

4.12.3 删除页面中的某一个节点

六、removeChild:移除某一节点下的某一个节点

上例

    box.removeChild(child)//删除后代
    box.remove()//删除自己以及后代

在这里插入图片描述

4.12.5 修改页面中的某一个节点

七、replaceChild:将页面中的某一个节点替换掉
  <div id="box">
    <div id="child">111111</div>
  </div>

  <script>
    var odiv = document.createElement("div")
    odiv.innerHTML = "我是新创建的节点"
    odiv.id="aaa"
    odiv.style.background="yellow"
    console.log(odiv)

    var odiv2 = document.createElement("div")
    odiv2.innerHTML = "222222222"
    box.replaceChild(odiv2,child)
  </script>

在这里插入图片描述

4.12.6 克隆页面中的某一个节点

八、cloneNode 克隆

克隆节点()
false 不克隆后代
true克隆后代

  <div id="box">
    <div id="child">111111</div>
  </div>

  <script>
    var odiv = document.createElement("div")
    odiv.innerHTML = "我是新创建的节点"
    odiv.id="aaa"
    odiv.style.background="yellow"
    console.log(odiv)

    var oCloneBox = box.cloneNode(true)
    console.log(oCloneBox)
    oCloneBox.id = "box2"
    document.body.appendChild(oCloneBox)
  </script>

在这里插入图片描述

4.13 动态删除案例

  <ul id="list"></ul>
  <script>
    var arr = ["111", "2222", "333"]
    for (var i = 0; i < arr.length; i++) 
    {
      var oli = document.createElement("li")
      //把按钮追加到li中
      oli.innerHTML = arr[i]
      var obutton = document.createElement("button")
      // 再按钮里放内容
      obutton.innerHTML = "delate"
      // 将函数赋予点击属性
      obutton.onclick = handlr
      oli.appendChild(obutton)
      list.appendChild(oli)
    }
    function handlr() 
    {
      this.parentNode.remove()//利用this选择到点击的部分,如果没有parentNode则点击只会删除按钮不会删除li部分
    }
  </script>

在这里插入图片描述

4.14 节点属性

在这里插入图片描述

  <ul test="我是 ul 的一个属性">
    <li>hello</li>
  </ul>
  
  <script>
    // 先获取 ul
    var oUl = document.querySelector('ul')
    
    // 获取到 ul 下的第一个子元素节点,是一个元素节点
    var eleNode = oUl.firstElementChild
    
    // 获取到 ul 的属性节点组合,因为是个组合,我们要拿到节点的话要用索引
    var attrNode = oUl.attributes[0]

    // 获取到 ul 下的第一个子节点,是一个文本节点
    var textNode = oUl.firstChild
  </script>

在这里插入图片描述

4.14.1 nodeType:获取节点的节点类型,用数字表示

console.log(eleNode.nodeType) // 1
nodeType === 1 就表示该节点是一个 元素节点

console.log(attrNode.nodeType) // 2
nodeType === 2 就表示该节点是一个 属性节点

console.log(textNode.nodeType) // 3
nodeType === 3 就表示该节点是一个 注释节点

4.14.2 nodeName:获取节点的节点名称

console.log(eleNode.nodeName) // LI
元素节点的 nodeName 就是大写标签名

console.log(attrNode.nodeName) // test
属性节点的 nodeName 就是属性名

console.log(textNode.nodeName) // #text
文本节点的 nodeName都是#text

4.14.3 nodeValue: 获取节点的值

console.log(eleNode.nodeValue) // null
元素节点没有 nodeValue

console.log(attrNode.nodeValue) // 我是 ul 的一个属性
属性节点的 nodeValue 就是属性值

console.log(textNode.nodeValue) // 换行 + 空格
文本节点的 nodeValue 就是文本内容

4.15 获取元素尺寸

就是获取元素的 “占地面积”,而不是元素的大小
可以实现懒加载的效果(像京东的商品栏)

好处:当滑块滑到底部时再加载,可以减少用户的缓存

注意:

获取到的尺寸是没有单位的数字

不会对box-sizing有影响

当元素在页面中不占位置的时候, 获取到的是 0

display: none; 元素在页面不占位

visibility: hidden; 元素在页面占位

4.15.1 offsetWith 和 offsetHeight

offsetWidth : 获取的是元素 内容 + padding + border 的宽度
offsetHeight : 获取的是元素 内容 + padding + border 的高度

4.15.2 clientWidth 和 clientHeight

clientWidth : 获取的是元素 内容 + padding 的宽度
clientHeight : 获取的是元素 内容 + padding 的高度

  <style>
    div{
      width: 100px;
      height: 100px;
      padding: 10px;
      border: 5px solid red;
      background-color: yellow;
    }
  </style>
  <div id="box"></div>
  <script>
    console.log(box.offsetWidth,box.offsetHeight)
    console.log(box.clientWidth,box.clientHeight)
  </script>

在这里插入图片描述

4.16 获取元素的偏移量

元素在页面上相对于参考父级的左边和上边的距离
在这里插入图片描述

4.16.1 offsetParent

获取元素的偏移量参考父级
其实就是假设要给一个元素绝对定位的时候
它是根据谁来进行定位的
那么这个元素的偏移量参考父级就是谁

4.16.2 offsetLeft 和 offsetTop

获取的是元素左边的偏移量和上边的偏移量
offsetLeft : 该元素相对于参考父级的左侧偏移量
offsetTop : 该元素相对于参考父级的上侧偏移量

4.17 获取浏览器窗口尺寸

前面学过一个 innerWidth 和 innerHeight获取到的是窗口包含滚动条的尺寸
下面学习两个不包含滚动条的尺寸获取方式
document.documentElement.clientWidth : 可视窗口的宽度
document.documentElement.clientHeight : 可视窗口的高度

4.18 懒加载案例

懒加载b站链接

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

    html,body{
      height: 100%;
    }

    ul li{
      overflow: hidden;
      height: 150px;
    }

    ul li img{
      float: left;
      width: 120px;
    }

  </style>

  <h1>标题</h1>
  <ul id="list"></ul>


  <script>
    var arr1 =[
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      }
    ]
    var arr2 =[
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      },
      {
        name: "哆啦A梦:大雄的宇宙小战争2021",
        url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
      }
    ]


    renderHTML(arr1)//因为函数声明都是会预读到前面,所以实际调用写在函数声明前也可以
    function renderHTML(arr){
      // list.innerHTML += arr.map//+=用作与下滑到底时叠加arr2,直接=会覆盖掉前面的
      // (//映射出arr数组的每个元素,利用函数调用返回显示
      //   function(item){
      //     return  `<li>
      //     <img src="${item.url}" alt="">
      //     <h3>${item.name}</h3>
      //     </li>`//将静态网页写的形式套用进来,要变的量写成${}形式在标签内
      //   }
      // ).join("")//对映射部分的逗号起到消除作用

      for(var i=0;i<arr.length;i++){//对上面代码的优化,可以在加载数据时不出现闪动
        var oli = document.createElement("li")
        oli.innerHTML = `<img src="${arr[i].url}" alt="">
          <h3>${arr[i].name}</h3>`
          list.appendChild(oli)
      }
    }

    isLoading = false//用于触发到底了停止打印
    window.onscroll = function()
    {
      // console.log("111111")
      var listHeight = list.offsetHeight
      var listTop = list.offsetTop
      // console.log(listHeight+listTop)

      var scrollTop = document.documentElement.scrollTop ||
      document.body.scrollTop

      var windowHeight = document.documentElement.clientHeight

      if(isLoading) return
      if((listHeight+listTop)-Math.round(windowHeight+scrollTop)<50)//快到底时触发
      {
        console.log("到底了")
        isLoading = true

        //渲染下一个数据
        setTimeout(function(){//设置拉到底之后过段实际再加载数据
            renderHTML(arr2)
            isLoading = false//下一次到底事件再次触发
          },1000
        )
      }

    }


  </script>

在这里插入图片描述

4.19 初识事件

一个事件由什么东西组成
触发谁的事件:事件源
触发什么事件:事件类型
触发以后做什么:事件处理函数

4.19.1 dom0 类型—但如果后面另外写了函数会覆盖前面的

 <script>
var obox = document.querySelector('div')

obox.onclick = function () {}
// 谁来触发事件 => Div => 这个事件的事件源就是 Div
// 触发什么事件 => onclick => 这个事件类型就是 click事件
// 触发之后做什么 => function(){} => 这个事件的处理函数就会执行
  </script>

我们想要在点击 div 以后做什么事情,就把我们要做的事情写在事件处理函数里面

 <script>
var obox = document.querySelector('div')

obox.onclick = function () {
  console.log('你点击了 div')
}
  </script>

当我们点击 div 的时候,就会执行事件处理函数内部的代码
每点击一次,就会执行一次事件处理函数

419.1 dom2 类型—绑定多个事件处理函数按照顺序执行

一、addEventListener : 非 IE6 7 8下使用

语法: 元素.addEventListener(‘事件类型’, 事件处理函数, 冒泡还是捕获)

但是对IE6、7、8有兼容性问题

  <div id="box2">bbbb</div>
  <script>
    box2.addEventListener("click",function(){
      console.log("111111")
    })
    box2.addEventListener("click",function(){
      console.log("222222")
    })
    box2.addEventListener("click",function(){
      console.log("333333")
    })
  </script>

当点击 div 的时候,两个函数都会执行,并且会按照你注册的顺序执行
注意: 事件类型的时候不要写 on,点击事件就是 click,不是 onclick
在这里插入图片描述

二、attachEvent :IE 6 7 8 下使用(不推荐)

可以用attachEvent让IE兼容反应

  <script>
    box2.attachEvent("click",function(){
      console.log("111111")
    })
        box2.attachEvent("click",function(){
      console.log("2222222")
    })
        box2.attachEvent("click",function(){
      console.log("3333333")
    })
  </script>

4.20 事件解绑

  <button id="btn">抽奖</button>
  <script>
    btn.onclick = function () {
      console.log("谢谢惠顾")
      // console.log(this)
      this.disabled = "disabled"
    }
  </script>

当点击抽奖时被禁用,但是可以在开发者工具中删除就能再次抽奖,为了防止这种情况,需要事件解绑
在这里插入图片描述

4.20.1 dom节点.onclick = null 赋值为空

上例修改

  <script>
    btn.onclick = function () {
      console.log("谢谢惠顾")
      this.onclick = null
    }
  </script>

点击之后无法再次修改
在这里插入图片描述

4.20.2 dom2类型 removeEventListener

上例修改,对同一对象使用removeEventListener值,需要用到 addEventListener 的方式添加事件

  <script>
    function handler(){
      console.log("谢谢惠顾")
      thie.removeEventListener("click",handler)
    }
    //在外部设置函数相当于设定了个函数钥匙,调用时就可以用多把这种钥匙来调用
    btn.addEventListener("click",handler)

  </script>

但是存在IE兼容性问题,可以使用detachEvent

  <script>
    function handler() {
      console.log("谢谢惠顾" )
      btn.detachEvent("onclick",handler)
    }
    btn.attachEvent("onclick",handler)

  </script>

4.21 事件类型

常见的事件
我们在写页面的时候经常用到的一些事件
大致分为几类,浏览器事件 / 鼠标事件 / 键盘事件 / 表单事件 / 触摸事件
不需要都记住,但是大概要知道

4.21.1 鼠标事件

click :单击事件

dblclick :双击事件

contextmenu : 右键单击事件

mousedown :鼠标左键按下事件

mouseup :鼠标左键抬起事件

mousemove :鼠标移动在上方就触发

mouseover :鼠标移入事件

mouseout :鼠标移出事件

区别:
当盒子有父子关系时,mouseover和mouseout移入移出也会触发
而mouseenter和mouseleave则不会

mouseenter :鼠标移入事件

mouseleave :鼠标移出事件

4.21.2 键盘事件

keyup : 键盘抬起事件

keydown : 键盘按下事件

keypress : 键盘按下再抬起事件

4.21.3 焦点事件

focus:获取焦点事件

blur: 失去焦点事件

change 获取焦点和失去焦点的对比里面内容不一样才会触发

4.21.4 表单事件

change : 表单内容改变事件

input : 表单内容输入事件

submit : 表单提交事件

4.21.5 触摸事件(移动端)

touchstart : 触摸开始事件

touchend : 触摸结束事件

touchmove : 触摸移动事件

touchcancel: 正在触摸手机屏幕,突然有电话这种消息打来就会触发

4.21.5 浏览器事件

load : 页面全部资源加载完毕

scroll : 浏览器滚动的时候触发

4.22 事件对象

什么是事件对象?
就是当你触发了一个事件以后,对该事件的一些描述信息

例如:

你触发一个点击事件的时候,你点在哪个位置了,坐标是多少
你触发一个键盘事件的时候,你按的是哪个按钮

每一个事件都会有一个对应的对象来描述这些信息,我们就把这个对象叫做事件对象

浏览器给了我们一个 黑盒子,叫做 window.event,就是对事件信息的所有描述

比如点击事件
你点在了 0,0 位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
你点在了 10, 10 位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
odiv.onclick = function () {
  console.log(e.X轴坐标点信息)
  console.log(e.Y轴坐标点信息)
}

但是一般来说,好用的东西就会有兼容性问题

在 IE低版本 里面这个东西好用,但是在高版本IE 和 Chrome 里面不好使了

就得用另一种方式来获取 事件对象

在每一个事件处理函数的行参位置,默认第一个就是 事件对象

我们以后在每一个事件里面,想获取事件对象的时候,都用兼容写法

odiv.onclick = function (e) {
  e = e || window.event
  console.log(e.X轴坐标点信息)
  console.log(e.Y轴坐标点信息)
}

4.23 事件对象鼠标事件

4.23.1 clientX和clientY 距离浏览器可视窗口的左上角的坐标值

相对于可视窗口
这里的可视窗口就是窗口的大小
在这里插入图片描述

4.23.2 pageX和pageY 距离页面文档流的左上角的坐标值

相对于整个文档的x和y
在这里插入图片描述

4.23.3 offsetX和offsetY 距离触发元素的左上角的坐标值

相对点击盒子左上角的位置
若大盒子包裹小盒子,点击小盒子,就会显示距离小盒子左上角的距离
在这里插入图片描述

4.24 鼠标跟随案例

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

    div {
      width: 200px;
      height: 50px;
      background-color: yellow;
      position: relative;

      margin: 100px;
    }

    div p {
      width: 300px;
      height: 200px;
      background-color: red;
      position: absolute;
      left: 100px;
      top: 100px;
      display: none;
      pointer-events: none;
       /* 鼠标事件穿透——可以让移动时不会出现抖动 */
      z-index: 100;
    }
  </style>

  <div id="box">
    steve头像
    <p>
      steve介绍
    </p>
  </div>
  <div>22222222</div>
  <script>
    box.onmouseover = function () {
      this.firstElementChild.style.display = "block"//移入显出
    }
    box.onmouseout = function () {
      this.firstElementChild.style.display = "none"//移开消失
    }
    box.onmousemove = function (evt) {//鼠标移动在上方触发
      this.firstElementChild.style.left = evt.offsetX + "px"//让p标签距离父盒子box左上角贴合
      this.firstElementChild.style.top = evt.offsetY + "px"
    }
  </script>

在这里插入图片描述

4.25 鼠标拖拽案例

方案一

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

    div {
      width: 100px;
      height: 100px;
      background-color: skyblue;
      position: absolute;
    }
  </style>
  <div id="box"></div>

  <script>
    box.onmousedown = function () {
      console.log("down")
      //move放在down的处理函数中,可以让点击之后才触发跟随
      document.onmousemove = function (evt) {//用document表示在浏览器窗口中跟随,用box的话只能在box中跟随

        //用于鼠标移动时位于盒子中心  
        var x = evt.clientX - box.offsetWidth/2
        var y = evt.clientY - box.offsetHeight/2

        //设置无法超出可视窗口边界
        if(y<=0)y=0
        if(x<=0)x=0
        if(x>=document.documentElement.clientWidth-box.offsetWidth)
        x = document.documentElement.clientWidth-box.offsetWidth
        if(y>=document.documentElement.clientHeight-box.offsetHeight)
        y = document.documentElement.clientHeight-box.offsetHeight

        //用于点击后能够移动盒子
        box.style.left = x + "px"
        box.style.top = y + "px"
      }
    }
    box.onmouseup = function () {
      console.log("up")
      document.onmousemove = null //对松开抬起按键时进行解绑
    }
  </script>

方案二

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

    div {
      width: 100px;
      height: 100px;
      background-color: skyblue;
      position: absolute;
    }
  </style>
  <div id="box"></div>

  <script>
    isDown = false
    box.onmousedown = function () {
      console.log("down")
      isDown = true
      //move放在down的处理函数中,可以让点击之后才触发跟随

      box.onmouseup = function () {
        console.log("up")
        isDown = false
        // document.onmousemove = null //对松开抬起按键时进行解绑
      }
      document.onmousemove = function (evt) {//用document表示在浏览器窗口中跟随,用box的话只能在box中跟随

        if(!isDown) return
        
        //用于鼠标移动时位于盒子中心  
        var x = evt.clientX - box.offsetWidth / 2
        var y = evt.clientY - box.offsetHeight / 2

        //设置无法超出可视窗口边界
        if (y <= 0) y = 0
        if (x <= 0) x = 0
        if (x >= document.documentElement.clientWidth - box.offsetWidth)
          x = document.documentElement.clientWidth - box.offsetWidth
        if (y >= document.documentElement.clientHeight - box.offsetHeight)
          y = document.documentElement.clientHeight - box.offsetHeight

        //用于点击后能够移动盒子
        box.style.left = x + "px"
        box.style.top = y + "px"
      }
    }
  </script>

在这里插入图片描述

4.26 DOM事件流

在这里插入图片描述
标准的dom事件流:

  • 捕获: window=>docuemtn=> body= >outer
  • 目标: inner
  • 冒泡: outer= > body= >docuemnt= >window、

默认情况只在冒泡触发
按照dom2事件绑定,并进行配置才能看到捕获的回调函数被触发。

4.27 节点.stopPropagation() 阻止事件传播

拿动态删除举例
1.大部分浏览器

  <ul id="list"></ul>
  <script>
    var arr = ["111", "2222", "333"]
    for (var i = 0; i < arr.length; i++) 
    {
      var oli = document.createElement("li")
      //把按钮追加到li中
      oli.innerHTML = arr[i]
      var obutton = document.createElement("button")
      // 再按钮里放内容
      obutton.innerHTML = "delate"
      // 将函数赋予点击属性
      obutton.onclick = handlr
      oli.appendChild(obutton)
      oli.onclick = function(){
        location.href = "http://www.baidu.com"
      }//点击li部分会跳转,但是由于DOM事件传播影响点删除也会跳转
      list.appendChild(oli)
    }
    function handlr(evt) 
    {
      console.log(this.parentNode)
      this.parentNode.remove()//利用this选择到点击的部分,如果没有parentNode则点击只会删除按钮不会删除li部分

      //阻止事件传播
      evt.stopPropagation()
    }
  </script>

2.IE的兼容性问题
function handlr(evt) 修改

    function handlr(evt) 
    {
      this.parentNode.parentNode.removeChild(this.parentNode)

      //阻止事件传播
      evt.cancelBubble = true
    }

4.28 阻止默认行为

4.28.1 dom0 return 阻止默认行为

  <script>
    //dom0 return 阻止默认行为
    document.oncontextmenu = function(){
      console.log("右键单击,自定义右键菜单")
      return false//阻止右键默认出现浏览器的菜单
    }
  </script>

4.28.2 dom2 evt.preventDefault

  <script>
    //dom2 evt.preventDefault
    document.addEventistener ("contextmenu",function(evt){
      console.log("右键单击,自定义右键菜单")
      return false//阻止右键默认出现浏览器的菜单
    })
  </script>

4.29 自定义右键菜单案例

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

    ul {
      list-style: none;
      width: 200px;
      padding: 10px;
      border: 1px solid black;
      display: none;
      position: absolute;
    }

    ul li:hover {
      background-color: skyblue;
    }
  </style>

  <ul id="list">
    <li class="aaa">111111</li>
    <li class="bbb">222222</li>
    <li class="ccc">333333</li>
  </ul>

  <script>
    document.addEventListener("contextmenu",function(evt){
      evt.preventDefault()
      list.style.display = "block"
      var x = evt.clientX
      var y = evt.clientY
      if(x>=document.documentElement.clientWidth-list.offsetWidth)
      x = document.documentElement.clientWidth
      if(x>=document.documentElement.clientHeight-list.offsetHeight)
      x = document.documentElement.clientHeight

      list.style.left = x + "px"
      list.style.top = y + "px"
    })
    //加个左键单击事件消失
    document.addEventListener(
      "click",()=>{
        list.style.display = "none"
      }
    )
  </script>

在这里插入图片描述

4.30 事件委托

  • 就是把我要做的事情委托给别人来做
  • 因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件
  • 所以我们就可以把子元素的事件委托给父元素来做
  • 好处:
  • 减少多个函数的绑定的性能损耗
    动态添加li,也会有事件处理

在这里插入图片描述

4.30.1 target 表示点击的目标

  • target这个属性是事件对象里面的属性,表示你点击的目标
  • 当你触发点击事件的时候,你点击在哪个元素上,target 就是哪个元素
  • 这个target也不兼容,在IE’下要使用srcElement
    在这里插入图片描述
  <ul id="list">
    <li>
      111111
      <button>add</button>
    </li>
  </ul>

  <script>
    list.onclick = function (evt) {
      console.log(evt.target || evt.srcElement)//IE才用后面的那个
    }
  </script>

当点击li就返回li,当点击按钮就返回按钮
在这里插入图片描述
动态删除采用委托

  <ul id="list"></ul>
  <script>
    var arr = ["111", "2222", "333"]
    for (var i = 0; i < arr.length; i++) 
    {
      var oli = document.createElement("li")
      //把按钮追加到li中
      oli.innerHTML = arr[i]
      var obutton = document.createElement("button")
      // 再按钮里放内容
      obutton.innerHTML = "delate"
      // 将函数赋予点击属性
      oli.appendChild(obutton)
      list.appendChild(oli)
    }
    //给ul进行绑定,让父委托
    list.onclick = function(evt){
      console.log(evt.target.nodeName)
      if(evt.target.nodeName==="BUTTON")
      evt.target.parentNode.remove()
    }
    
  </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值