前端之勇闯DOM关

一、DOM简介

1.1什么是DOM

文档对象类型(Document Object Model,简称DOM),是W3C组织推荐的处理课扩展标记语言(HTML或者XML)的标准编程接口

W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式

1.2DOM树

  • 文档:一个页面就是一个文档,DOM中使用document 表示
  • 元素:页面中的所有标签都是元素,DOM中使用element表示
  • 节点:网页中所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示

DOM把以上所有内容看作是对象

二、获取元素

2.1如何获取页面元素

  1. 根据ID获取
  2. 根据标签名获取
  3. 通过HTML5新增的方法获取
  4. 特殊元素获取

2.2根据ID获取

使用getElementById()方法可以获取带有ID的对象

javascript 复制代码
<div id="name">花花</div>
<script>
    var namer = document.getElementById('name');
    console.log(namer);//<div id="name">花花</div>
    console.dir(namer);//div#name
</script>
  • 因为我们文档页面从上往下加载,所以先得有标签,所以我们scrip写到标签的下面
  • 参数:id是大小写敏感的字符串
  • 返回的是一个元素对象
  • console.dir打印我们返回的元素对象,更好地查看里面的属性和方法

2.3根据标签名获取

使用getElementByTagName()方法可以返回带有知道标签名的对象的集合

javascript 复制代码
<ul>
    <li>1110</li>
    <li>111</li>
    <li>111</li>
    <li>111</li>
    <li>111</li>
</ul>
<script>
    var lis = document.getElementsByTagName('li');
    console.log(lis);
</script>

可以看见,是采用伪数组的形式存储的

所以也可以用数组的方法输出

javascript 复制代码
console.log(lis[0]);

想要依次打印里面的元素可以采用遍历的方式

javascript 复制代码
for (var i = 0; i < lis.length; i++) {
    console.log(lis[i]);
}

注意:

1.因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历

2.得到元素对象是动态的

3.如果页面只有一个li,返回的还是伪数组形式

4.如果页面中没有这个元素,返回的是空的伪数组的形式

获取某个元素(父元素) 内部所有指定标签的子元素

javascript 复制代码
element.getElementsByTagName('标签名');

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

例如:

javascript 复制代码
var ul = document.getElementsByTagName('ul');
console.log(ol.getElementsByTagName('ol'));

此时将伪数组作为父元素,报错啦

要指定一个确定的元素

javascript 复制代码
var ul = document.getElementsByTagName('ul');
console.log(ul[0].getElementsByTagName('ul'));

此时可以把ul里面所有li获取出来

但是这个方法还是有点麻烦,可以直接给ul一个id,根据id获取ul里面所有的li

2.4通过HTML5新增的方法获取

(1)根据类名返回元素对象集合

javascript 复制代码
document.getElementsByClassName('类名');//根据类型名返回元素对象集合

例如

javascript 复制代码
<div class="box">盒子1</div>
<div class="box">盒子2</div>
<div id="nav">
   <ul>
      <li>首页</li>
      <li>产品</li>
   </ul>
</div>
<script>
   var boxs=document.getElementsByClassName('box');
   console.log(boxs);
</script>

运行结果:

(2)根据指定选择器返回第一个元素对象

javascript 复制代码
document.querySelector('选择器');//根据指定选择器返回第一个元素对象

例如:

javascript 复制代码
var firstBox = document.querySelector('.box');
console.log(firstBox);
var nav = document.querySelector('#nav');
console.log(nav);
var firstli = document.querySelector('li');
console.log(firstli);

运行结果:

切记里面的选择器要加符号,.box #nav.....

(3)根据指定选择器返回所有对象

javascript 复制代码
document.querySelectorAll('选择器');//根据指定选择器返回所有元素对象

例如:

javascript 复制代码
var allBox = document.querySelectorAll('.box');
console.log(allBox);

运行结果:

2.5获取特殊元素(body,HTML)

(1)获取body元素

javascript 复制代码
document.body//返回body元素对象

实际应用:

javascript 复制代码
var bodyEle = document.body;
console.log(bodyEle);

(2)获取html元素

javascript 复制代码
document.documentElement//返回heml元素对象

实际应用:

javascript 复制代码
var htmlEle = document.documentElement;
console.log(htmlEle);

三、事件基础

3.1事件概述

JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为

简单理解:触发---响应机制

事件三要素:事件源,事件类型,事件处理程序

javascript 复制代码
<button id="btn">唐伯虎</button>
<script>
    //(1)事件源  事件:被触发的对象  谁:按钮
    var btn = document.getElementById('btn');
    //(2)事件类型 如何触发 什么事件  比如鼠标点击(onclick),还是鼠标经过,还是鼠标按下
    //(3)事件处理程序  通过一个函数赋值的方式完成
    btn.onclick = function () {
        alert('点秋香');
    }
</script>

3.2执行事件的步骤

1.获取事件源

2.注册事件(绑定事件)

3.添加事件处理程序(采取函数赋值形式)

案例:点击123,输出我被选中了

javascript 复制代码
<div>123</div>
<script>
    //1.获取事件源
    var xzl = document.querySelector('div');
    //2.绑定事件
    //div.onclick
    //3.添加事件处理程序
    xzl.onclick = function () {
       alert('我被选中了');
    }
</script>

3.3常见的鼠标事件

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

四、操作元素

4.1改变元素内容

javascript 复制代码
element.innerText

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

javascript 复制代码
element.innerHTML

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

案例:点击按钮,div的文字发生变化

javascript 复制代码
<button>显示时间</button>
<div>时间</div>
<p>1</p>
<script>
    var btn = document.querySelector('button');
    var div = document.querySelector('div');
    btn.onclick = function () {
        div.innerText = getDate();
    }
    function getDate() {
        var date = new Date();
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        var day = date.getDate();
        return year + '年' + month + '月' + day + '日';
    }
</script>

我们元素可以不用添加事件

javascript 复制代码
var p = document.querySelector('p');
p.inner.Text = getDate();

这样的事件,刷新网页后会自动跳出所需内容

element.innerText和element.innerHTML区别

1.inner.Text不识别html标签 非标准 去除换行与空格

2.inner.HTML识别html标签 W3C标准 保留空格和换行

3.这两个属性是可读写的,可以获取元素里面的内容

4.2常用元素的属性操作

1.innerText、innerHTML 改变元素内容

2.src、href

3.id、alt、title

例如使用src

javascript 复制代码
<button id="1">1</button>
<button id="2">2</button>
<img src="9.png" alt="">
<script>
   var but1 = document.getElementById('.1');
   var but2 = document.getElementById('2');
   var imgs = document.querySelector('img');
   but2.onclick = function () {
      imgs.src = '10.png';
   }
   but1.onclick = function () {
      imgs.src = '9.png';
   }
</script>

案例:分时显示不同图片,显示不同的问候语

javascript 复制代码
<div>上午好</div>
<img src="1.png" alt="">
<script>
   var date = new Date();
   var hour = date.getHours();
   var img = document.querySelector('img');
   var div = document.querySelector('div');
   if (hour < 12) {
       div.innerHTML = '上午好';
       img.src = '1.png';
   }
   else if (hour == 12) {
       div.innerHTML = '中午好';
       img.src = '2.png';
   }
   else if (hour < 18) {
       div.innerHTML = '下午好';
       img.src = '3.png';
   }
   else {
       div.innerHTML = '晚上好';
       img.src = '4.png';
    }
</script>

4.3表达原始的属性操作

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

type,value,checked,selected,disabled

(1)value(表单里面的文字内容是通过value来修改的)

javascript 复制代码
<button>按钮</button>
<input type="text" value="输入内容">
<script>
    var btn = document.querySelector('button');
    var input = document.querySelector('input');
    btn.onclick = function () {
       input.value = '被点击了';
   }   
</script>

(2)disabled(让某个表单被禁用,不能再点击)

javascript 复制代码
btn.disabled = true;

(3)type

javascript 复制代码
input.type = '';

案例:仿京东显示密码

点击按钮将密码框切换为文本框,并可以查看密码明文

css部分

css 复制代码
.box {
   position: relative;
   width: 400px;
   border-bottom: 1px solid #ccc;
   margin: 100px auto;
}
.box input {
   width: 370px;
   height: 30px;
   border: 0;
   outline: none;
}
.box img {
   top: 5px;
   left: 365px;
   position: absolute;
   width: 24px;
}

HTML部分

html 复制代码
<div class="box">
        <label for="">
            <img src="yincang.png" alt="">
        </label>
        <input type="password" id="">
</div>

JavaScript部分

javascript 复制代码
var input = document.querySelector('input');
var img = document.querySelector('img');
var flag = 0;
img.onclick = function () {
      if (flag == 0) {
          input.type = 'text';
          img.src = 'display.png';
          flag = 1;
      }
      else {
          input.type = 'password';
          img.src = 'yincang.png';
          flag = 0;
      }
}

4.4样式属性操作

我们可以通过JS修改元素的大小、颜色、位置等样式

(1)行内样式操作

javascript 复制代码
element.style

案例:点击盒子,改变背景以及宽度

css:

css 复制代码
div {
   width: 200px;
   height: 200px;
   background-color: pink;
}

HTML:

html 复制代码
<div></div>

JavaScript:

javascript 复制代码
var div = document.querySelector('div');
div.onclick = function () {
      this.style.backgroundColor = 'purple';
      this.style.width = '250px';
}

注意:

1.JS里面的样式采取驼峰命名法,例如:fontSize、backgroundColor

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

案例:关闭二维码

css:

css 复制代码
.box {
    position: relative;
    width: 200px;
    height: 200px;
    margin: 100px auto;
}

.box .ma {
    width: 180px;
}

.box p {
    position: absolute;
    top: -20px;
    left: -15px;
    width: 5px;
}

HTML:

html 复制代码
<div class="box">
   <img src="二维码.jpg" alt="" class="ma">
   <p><img src="fork.png" alt=""></p>
</div>

JS:

javascript 复制代码
var fork = document.querySelector('p');
var box = document.querySelector('.box');
fork.onclick = function () {
     box.style.display = 'none';
}

案例:循环精灵图背景

可以用for循环设置一组元素的精灵图背景

css:

css 复制代码
.box {
    width: 305px;
    height: 170px;
    margin: 200px auto;
}

.box li {
    float: left;
    list-style: none;
    width: 24px;
    height: 24px;
    margin: 15px;
    background: url(sprite.png);
}

.box li:hover {
    border: 1px solid red;
}

HTML:

html 复制代码
<div class="box">
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>

JavaScript:

javascript 复制代码
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
    var index = i * 44;
    lis[i].style.backgroundPosition = '0 -' + index + 'px';
}

案例:显示隐藏文本内容

当鼠标点击文本框时,里面文字默认隐藏,当鼠标离开文本框时,文字显示

css:

css 复制代码
input {
   color: #999;
}

HTML:

html 复制代码
<input type="text" value="手机">

JavaScript:

javascript 复制代码
var text = document.querySelector('input');
text.onfocus = function () {
    if (this.value == '手机') {
         this.value = '';
    }
    this.style.color = 'black';
}
text.onblur = function () {
    if (this.value == '') {
          his.value = '手机';
    }
    his.style.color = '#999';
}

(2)类名样式操作

javascript 复制代码
element.ClassName

案例:使用className更改元素样式

css:

css 复制代码
div {
    height: 50px;
    width: 50px;
    background-color: pink;
}

.change {
    background-color: purple;
    color: #fff;
    font-size: 25px;
    margin-top: 100px;
}

HTML:

html 复制代码
<div>文本</div>

JavaScript:

javascript 复制代码
var div = document.querySelector('div');
div.onclick = function () {
    this.className = 'change';
}

注意:

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

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

3.className会直接更改元素类名,会覆盖原先的类名

4.如果想要保留原先类名,可以用多类名选择器

javascript 复制代码
this.className = 'first change';

案例:密码框格式提示错误信息

用户如果离开密码框。里面输入个数不是6-16,则提示错误信息,否则提示输入正确信息

css:

css 复制代码
.register {
     margin: 200px 500px;
}
.ipt {
     height: 20px;
}
.message {
     display: inline-block;
     color: #999;
     font-size: 12px;
     padding-left: 20px;
     background: url(mess.png) no-repeat left center;
}
.wrong {
     color: red;
     background: url(wrong.png) no-repeat left center;
}
.right {
     color: green;
     background: url(right.png) no-repeat left center;
}

HTML:

html 复制代码
<div class="register">
    <input type="password" name="" class="ipt">
    <p class="message">请输入6~16位密码</p>
</div>

JavaScript:

javascript 复制代码
var ipt = document.querySelector('input');
var p = document.querySelector('p');
ipt.onblur = function () {
    if (this.value.length < 6 || this.value.length > 16) {
        p.className = 'message wrong';
        p.innerHTML = '您输入的位数不正确,要求6~16位';
    }
    else {
        p.className = 'message right';
        p.innerHTML = '您输入的位数正确';
    }
}

4.5排他思想

案例:点击按钮变色,上一个按钮恢复原来颜色

HTML:

html 复制代码
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<button>按钮6</button>

JavaScript:

javascript 复制代码
var btns = document.querySelectorAll('button');
for (var i = 0; i < btns.length; i++) {
    btns[i].onclick = function () {
        for (var i = 0; i < btns.length; i++) {
            btns[i].style.backgroundColor = '';
        }
    this.style.backgroundColor = 'pink';
    }
}

如果有一组元素,我们想要某一个元素实现某个样式,需要用到循环的排他思想算法

案例:百度换肤

css:

css 复制代码
* {
     margin: 0;
     padding: 0;
}

body {
     background: url(3.png) no-repeat center top;
}

.baidu {
     overflow: hidden;
     margin: 100px auto;
     background-color: #fff
     width: 410px;
     padding-top: 3px;
     display: flex;
     justify-content: center;
}

.baidu li {
     list-style: none;
}

.baidu img {
     width: 100px;
}

HTML:

html 复制代码
<ul class="baidu">
   <li><img src="3.png" alt=""></li>
   <li><img src="download.jpg" alt=""></li>
   <li><img src="OIP-C.jpg" alt=""></li>
</ul>

JavaScript:

javascript 复制代码
var imgs = document.querySelector('.baidu').querySelectorAll('img');
var body = document.querySelector('body');
for (var i = 0; i < imgs.length; i++) {
    imgs[i].onclick = function () {
          body.style.backgroundImage = 'url(' + this.src + ')';
    }
}

案例:表格隔行变色

css:

css 复制代码
table {
   border-collapse: collapse;
   border: 1px solid skyblue;
   margin: 100px auto;
}

th,
td {
   border: 1px solid skyblue;
}

th {
   background-color: #4196c1;
   color: #fff;
}

.bg {
   background-color: #0ad5eb;
}

HTML:

html 复制代码
<table>
   <thead>
      <th>表头1</th>
      <th>表头2</th>
   </thead>
   <tbody>
      <tr>
         <td>1</td>
         <td>2</td>
      </tr>
      <tr>
         <td>3</td>
         <td>4</td>
      </tr>
   </tbody>
</table>

JavaScript:

javascript 复制代码
var trs = document.querySelector('tbody').querySelectorAll('tr');
for (var i = 0; i < trs.length; i++) {
     trs[i].onmouseover = function () {
         this.className = 'bg';
     }
     trs[i].onmouseout = function () {
         this.className = '';
     }
}

案例:表单全选取消全选

css:

css 复制代码
table {
    border-collapse: collapse;
    border: 1px solid skyblue;
    margin: 100px auto;
}

th,
td {
    border: 1px solid skyblue;
}

th {
    background-color: #4196c1;
    color: #fff;
}

HTML:

html 复制代码
<table>
   <thead>
      <th><input type="checkbox" name="" id="j_cbAll"></th>
      <th>表头1</th>
      <th>表头2</th>
   </thead>
   <tbody id="j_tb">
      <tr>
         <td><input type="checkbox" id="checkbox"></td>
         <td>1</td>
         <td>2</td>
      </tr>
      <tr>
         <td><input type="checkbox" id="checkbox"></td>
         <td>3</td>
         <td>4</td>
      </tr>
   </tbody>
</table>

JavaScript:

javascript 复制代码
var j_cbAll = document.querySelector('#j_cbAll');
var j_tbs = document.querySelector('#j_tb').getElementsByTagName('input');
j_cbAll.onclick = function () {
     console.log(this.checked);
     for (var i = 0; i < j_tbs.length; i++) {
          j_tbs[i].checked = this.checked;
      }
}
for (var i = 0; i < j_tbs.length; i++) {
     j_tbs[i].onclick = function () {
           var flag = true;
           for (var i = 0; i < j_tbs.length; i++) {
                if (!j_tbs[i].checked) {
                     j_cbAll.checked = false;
                     flag = false;
                }
            }
            j_cbAll.checked = flag;
      }
}

4.6自定义属性的操作

(1)获取属性值

1.element.属性

javascript 复制代码
var div = document.querySelector('div');
console.log(div.id);

2.element.getAttribute('属性')

javascript 复制代码
console.log(div.getAttribute('id'));

区别:

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

2.element.getAttribute('属性') 主要获取自定义属性(我们程序员自定义的属性)

(2)设置属性值

1.element.属性 = '值' 设置内置属性值

javascript 复制代码
div.id = 'test';
div.className = 'navs';

2.element.setAttribute('属性','值') 主要针对于自定义属性

javascript 复制代码
div.setAttribute('id','test');
div.setAttribute('class','footer');

class特殊,这里写的就是class,不是className

(3) 移除属性

element.removeAttribute('属性')

javascript 复制代码
div.removeAttribute('id');

案例:tab栏切换

css:

css 复制代码
* {
  margin: 0;
  padding: 0;
}

ul {
  display: inline-block;
}

li {
  font-size: 20px;
  list-style: none;
  display: inline-block;
  padding: 5px;
  line-height: 20px;
}

.tab_list {
  width: 510px;
  background-color: #efecec;
}

.current {
  background-color: #ba7272;
  color: #fff;
}

HTML:

html 复制代码
<div class="tab">
    <div class="tab_list">
        <ul>
            <li>商品介绍</li>
            <li>规格与包装</li>
            <li>售后与保障</li>
            <li>商品评价</li>
            <li>手机社区</li>
        </ul>
    </div>
    <div class="tab_con">
        <div class="item">
            商品模块介绍内容
        </div>
        <div class="item">
            规格与包装介绍内容
        </div>
        <div class="item">
            售后与保障介绍内容
        </div>
        <div class="item">
            商品评价介绍内容
        </div>
        <div class="item">
            手机社区介绍内容
        </div>
    </div>
</div>

JavaScript:

javascript 复制代码
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
   lis[i].setAttribute('index', i);
   var items = document.querySelectorAll('.item');
   lis[i].onclick = function () {
       for (var i = 0; i < lis.length; i++) {
          lis[i].className = '';
       }
       this.className = 'current';
          var index = this.getAttribute('index');
          for (var i = 0; i < items.length; i++) {
              items[i].style.display = 'none';
          }
       items[index].style.display = 'block';
   }
}

4.7H5自定义属性

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

自定义属性通过getAttribute('属性')获取

有些自定义属性不容易判断是元素的内置属性还是自定义属性

(1)设置H5自定义属性

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

例如:

html 复制代码
<div data-index='1'></div>

或者用JS设置:

javascript 复制代码
element.setAttribute('data-index');

(2)获取H5自定义属性

1.兼容获取 element.getAttribute('data-index');

2.H5新增element.dataset.index 或者 element.dataset['index'] ie11才开始支持

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

如果自定义属性比较长,使用getAttribute比较方便,使用dataset的话使用驼峰命名法,例如:

html 复制代码
<div data-list-name="andy"></div>
javascript 复制代码
console.log(div.getAttribute('data-list-name');
console.log(div.dataset.listName);

五、节点操作

5.1节点概述

上面DOM树提过节点的概念,也就是页面所有内容全是节点

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

  • 元素节点 nodeType值为1------------>我们主要操作的节点类型
  • 属性节点 nodeType值为2
  • 文本节点 nodeType值为3 (文本节点包含文字、空格、换行等)

5.2节点层级

(1)父节点

parentNode 得到的是离元素最近的节点(亲爸爸),如果找不到父元素返回null

在下面有父子关系的盒子中,要得到父元素:

html 复制代码
<div class="box">
    <span class="erweima">x</span>
</div>

原来的方法:

javascript 复制代码
var erweima = document.querySelector('.erweima');
var box = document.querySelector('.box');

使用 父节点:

javascript 复制代码
var erweima = document.querySelector('.erweima');
console.log(erweima.parentNode);

(2)子节点

1.childNodes

childNodes得到的所有子节点包含元素节点、文本节点等等

在下面有父子关系的盒子中,要得到子元素:

html 复制代码
<div class="box">
    <span class="erweima">x</span>
    <span class="erweima">x</span>
    <span class="erweima">x</span>
    <span class="erweima">x</span>
</div>

原来的方法:

javascript 复制代码
var box = document.querySelector('.box');
var erweima = box.querySelector('.erweima');

使用子节点:

javascript 复制代码
var box = document.querySelector('.box');
console.log(box.childNodes);

如果只想获得里面的元素节点,则需专门处理:

javascript 复制代码
var box = document.querySelector('.box');
for (var i = 0; i < box.childNodes.length; i++) {
    if (box.childNodes[i].nodeType == 1) {
        console.log(box.childNodes[i]);;
    }
}
2.parentNode .children

parentNode .children 非标准 获得所有的子元素节点

javascript 复制代码
console.log(box.children);
3.parentNode.firstChild

parentNode.firstChild 获得子元素第一个节点,不管是文本节点还是元素节点

javascript 复制代码
console.log(box.firstChild);
4.parentNode.lastChild

parentNode.larstChild 获得子元素最后一个节点,不管是文本节点还是元素节点

javascript 复制代码
console.log(box.lastChild);
5.parentNode.firstElementChild

parentNode.firstElementChild 返回第一个子元素节点

javascript 复制代码
​console.log(box.firstElementChild);
6.parentNode.lastElementChild

parentNode.lastElementChild 返回最后一个子元素节点

javascript 复制代码
​console.log(box.lastElementChild);

注意:5和6有兼容性问题,IE9以上才支持

7.获得子元素第一个和最后一个节点的写法(开发中)

此方法无兼容性问题

javascript 复制代码
console.log(box.children[0]);
console.log(box.children[box.children.length - 1]);

**案例:**下拉菜单

css:

css 复制代码
* {
   margin: 0;
   padding: 0;
}

a {
   display: inline-block;
   width: 69px;
   color: #000;
   text-decoration: none;
}

.nav {
    display: inline-block;
    width: 210px;
    text-align: center;
}

.nav ul {
    display: inline-block;
}

.nav>li {
    width: 65px;
    position: relative;
}

.under {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
}

.under li {
     width: 68px;
     border-collapse: collapse;
     border: 1px solid orange;
}

li {
     display: inline-block;
     list-style: none;
}

.nav>li a:hover {
     background-color: #ec040475;
}

.under li:hover {
     background-color: #f18e16ba;
}

HTML:

html 复制代码
<ul class="nav">
   <li><a href="#">微博</a>
       <ul class="under">
             <li>私信</li>
             <li>评论</li>
             <li>@我</li>
       </ul>
   </li>
   <li><a href="#">微博</a>
       <ul class="under">
              <li>私信</li>
              <li>评论</li>
              <li>@我</li>
        </ul>
    </li>
    <li><a href="#">微博</a>
        <ul class="under">
              <li>私信</li>
              <li>评论</li>
              <li>@我</li>
        </ul>
    </li>
</ul>

JavaScript:

javascript 复制代码
var nav = document.querySelector('.nav');
var lis = nav.children;
for (var i = 0; i < lis.length; i++) {
    lis[i].onmouseover = function () {
         this.children[1].style.display = 'block';
    }
    lis[i].onmouseout = function () {
         this.children[1].style.display = 'none';
    }
}

(3)兄弟节点

1.node.nextSibling

node.nextSibling返回当前元素的下一个兄弟节点,找不到则返回null,包含所有节点,元素节点、文本节点等

例如在:

html 复制代码
<div>1</div>
<span>2</span>

使用 node.nextSibling,输出#text

javascript 复制代码
var div = document.querySelector('div');
console.log(div.nextSibling);//#text
2.node.previousSibling

node.previousSibling返回当前元素的上一个兄弟节点,找不到则返回null,包含所有节点,元素节点、文本节点等

例如在:

html 复制代码
<div>1</div>
<span>2</span>

使用 node.previousSibling,输出#text

javascript 复制代码
var span = document.querySelector('span');
console.log(div.previousSibling);//#text
3.node.nextElementSibling

node.nextElementSibling返回当前元素的下一个兄弟节点,找不到则返回null

javascript 复制代码
var div = document.querySelector('div');
console.log(div.nextElementSibling);
4.node.previousElementSibling

node.previousElementSibling返回当前元素的上一个兄弟节点,找不到则返回null

javascript 复制代码
var span = document.querySelector('span');
console.log(div.previousElementSibling);

注意:3和4有兼容性问题,只有IE9以上才支持

可以自己封装一个兼容性函数

javascript 复制代码
function getNextElementSibling(element) {
   var el = element;
   while (el = el.nextSibling) {
        if (el.nodeType == 1) {
            return el;
        }
   }
   return null;
}

5.3创建节点

javascript 复制代码
document.createElement('tagName');

因为原先不存在,根据需求生成的,又叫动态创建元素节点

5.4添加节点

javascript 复制代码
node.appendChild(child);

(1)node.appendChild()

node.appendChild()将一个节点添加到指定父节点的末尾 ,类似于CSS里面after伪元素,又称为追加元素,类似于数组中的push

在一个ul里面添加li

javascript 复制代码
var li=document.createElement('li');
var ul=document.querySelector('ul');
ul.appendChild(li);

(2) nodeinsertBefore()

nodeinsertBefore(child,指定元素)

javascript 复制代码
var lili = document.createElement('li');
ul.insertBefore(lili,ul.children[0]);

案例:简单版发布留言案例

css:

css 复制代码
li {
   color: plum;
   background-color: rgb(250, 217, 222);
   margin-bottom: 10px;
}

textarea {
   margin-top: 20px;
   margin-left: 40px;
   resize: none;
   border: 1px solid pink;
   border-radius: 5px;
}

HTML:

html 复制代码
<textarea value=""></textarea>
<button>发布</button>
<ul></ul>

JavaScript:

javascript 复制代码
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
btn.onclick = function () {
    if (text.value == '') {
       alert('您没有输入内容');
       return false;
    }
    else {
       var li = document.createElement('li');
       li.innerHTML = text.value;
       ul.insertBefore(li, ul.children[0]);
    }
}

5.5删除节点

node.removeChild(child)方法从DOM中删除一个子节点,返回删除的节点

例如:

javascript 复制代码
ul.removeChild(ul.children[0]);

案例:删除留言节点

css:

css 复制代码
li {
   color: plum;
   background-color: rgb(250, 217, 222);
   margin-bottom: 10px;
}

li a {
   float: right;
}

textarea {
   margin-top: 20px;
   margin-left: 40px;
   resize: none;
   border: 1px solid pink;
   border-radius: 5px;
}

HTML:

html 复制代码
<textarea value=""></textarea>
<button>发布</button>
<ul></ul>

JavaScript:

javascript 复制代码
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
btn.onclick = function () {
    if (text.value == '') {
        alert('您没有输入内容');
        return false;
    }
    else {
        var li = document.createElement('li');
        li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
        ul.insertBefore(li, ul.children[0]);
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
             as[i].onclick = function () {
             ul.removeChild(this.parentNode);
        }
    }
}

5.6复制节点(克隆节点)

node.cloneNode()

1.如果括号参数为空或者是false ,则是浅拷贝,只克隆节点本身,不克隆里面的子节点

2.如果括号参数为true ,则是深拷贝,只克隆里面的内容

案例:动态生成表格

css:

css 复制代码
thead {
   background: #bababa;
}

th {
   border: 1px solid rgb(150, 149, 149);
   padding-left: 20px;
   padding-right: 20px;
}

td {
   border: 1px solid rgb(150, 149, 149);
   text-align: center;
}

HTML:

html 复制代码
<table cellspacing="0">
   <thead>
       <tr>
          <th>姓名</th>
          <th>科目</th>
          <th>成绩</th>
          <th>操作</th>
       </tr>
   </thead>
   <tbody>
   </tbody>
</table>

JavaScript:

javascript 复制代码
var datas = [{
   name: '魏璎珞',
   subject: 'JavaScript',
   score: 100
}, {
   name: '宏利',
   subject: 'JavaScript',
   score: 90
}, {
   name: '尹翼川',
   subject: 'JavaScript',
   score: 60
}]
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
   var tr = document.createElement('tr');
   tbody.appendChild(tr);
   for (k in datas[i]) {
       var td = document.createElement('td');
       td.innerHTML = datas[i][k];
       tr.appendChild(td);
   }
   var td = document.createElement('td');
   td.innerHTML = '<a href="jabasctipt:;">删除</a>';
   tr.appendChild(td);
}
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
   as[i].onclick = function () {
       tbody.removeChild(this.parentNode.parentNode);
   }
}

5.7三种动态创建元素的区别

(1)document.write()

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

(2)document.innerHTML

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

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

(3)document.createElement()

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

相关推荐
午后书香8 分钟前
入职前你需要知道的git操作大指南
前端·git·gitlab
天天扭码18 分钟前
一分钟解决 | 高频面试算法题——滑动窗口最大值(单调队列)
前端·算法·面试
星释21 分钟前
ASP.NET常见安全漏洞及修复方式
前端·ui·asp.net
Bunury40 分钟前
element-plus添加暗黑模式
开发语言·前端·javascript
心走44 分钟前
八股文中TCP三次握手怎么具象理解?
前端·面试
Aiolimp1 小时前
React常见Hooks使用(二)
前端·react.js
By北阳1 小时前
CSS 中实现 div 居中有以下几种常用方法
前端·css
在广东捡破烂的吴彦祖1 小时前
window配置Flutter开发环境
前端·flutter
辣椒粉丝1 小时前
记rspack想提issuse,提太慢白嫖不上了
前端·javascript
腰间盘突出的红利1 小时前
npm组件库搭建
前端