认识DOM、class的封装、获取属性、获取节点

427 阅读4分钟

1、认识DOM

文档对象模型(document Object model),由W3C提出的标准,是一个使用脚本动态的访问和更新文档的内容、结构以及样式;
DOM 提供了相应的API(接口),可以对文档进行增删改查,以实现js对网页元素的静态(进行)控制,实现动态网页的功能

2、HTML 节点树

DOM 的原理是将文档装入内容,并以节点的形式解析为一棵节点树
HTML 文档就是一种树状的结构化文档

3、节点类型

  • 元素节点:就是指标签
  • 属性节点:就是指标签上的属性
  • 文本节点:就是指标签之间的文本内容 4、获取节点的辅助方法
  • childNodes: 返回该节点下所有的子节点列表【包含空白符】(集合)【类似数组结构】 语法:父节点.childNodes
  • .hasChildNodes(); --判断是否有子节点 语法:父元素.hasChildNodes();
  • firstChild --返回第一个子节点 语法:父元素.firstChild
  • lastChild --返回最后一个子节点 语法:父元素.lastChild
  • .previousSibling --返回上一个兄弟节点 语法:父元素.previousSibling
  • .nextSibling --返回下一个兄弟节点 语法:父元素.nextSibling

parentNode(靠谱) 语法:子节点.parentNode --返回父节点

children --返回所以子节点(靠谱,不包含空白符) 语法:父元素.children

5、节点属性

5.1 节点名字:nodeName

  • 元素节点的 nodeName 与标签名字一样;
  • 属性节点的 nodeName 与属性名一样;
  • 文本节点的 nodeName 固定值为 #text;

5.2 节点值: nodeValue

  • 元素节点的 nodeValue 为Undefined 或者 null
  • 属性节点的 nodeValue 为属性值
  • 文本节点的 nodeValue 为文本内容

5.3 节点类型: nodeType

  • 元素节点的 nodeType 为 1
  • 属性节点的 nodeType 为 2
  • 文本节点的 nodeType 为 3
<body>
    <div id="box">
        <h1>标题</h1>
        <div>
            <img src="" alt="LOGO">
        </div>
        <p>图片的描述</p>
    </div>
    <script>
        var box = document.getElementById('box');
        var children = box.childNodes;
        console.log(children);
        //获取元素节点的方法
        var arr = [];
        for(var i = 0; i < children.length;i++) {
            if(children[i].nodeType == 1) {
                arr.push(children[i]);
            }
        }
        //返回的全是元素节点
        console.log(arr);
        console.log('第一个子节点'+box.hasChildNodes());
        console.log('返回上一个兄弟节点'+box.previousSibling);
        console.log('返回父节点'+box.parentNode);
        console.log('返回所有子节点'+box.children)
    </script>
</body>

获取节点的方法 1、获取节点方法(W3C)

  • 通过 ID 获取标签(获取一个标签 document.getElementByID(id);
  • 通过标签名获取:(获取一个标签的集合、类似数组结构) document.getElementsByTagName(tagname);
  • 通过 name 获取标签(获取的是一个集合) document .getElementsByName(name);
  • 通过 class 名字获取标签(获取一个标签的集合、类似数组结构)只支持IE9及以上 document.getElementsByClassName(classname)

2、其他方法:

  • 获取HTML标签(所有浏览器都支持的) document.documentElement

  • 获取body标签 document.body

  • 通过 form 的 name 获取表单 例如:

    console.log(document.loginForm.username); 语法:document.表单名字 document.表单名字.表单元素名

3、强大的 query【无法获取动态添加的 dom 节点】

  • document.querySelector(css选择器); --返回找到的第一个元素
  • document.querySelector('#nav');
  • document.querySelector('li');
  • document.querySelectorAll(css选择器) --返回找到的所有元素
//使用document.getElementsByClassName 老版本IE9以前的版本兼容
/**
* 根据类名查找元素,解决浏览器兼容问题
* @param className <String> 待查找的类名
* @return 返回查找到的元素集合
*/
function byClass(className) {
  if (document.getElementsByClassName) // 支持使用
  return document.getElementsByClassName(className);
/* 不支持使用 getElementsByClassName() 方法,解决兼容 */
// 定义保存结果的数组
  var result = [];
// 根据标签名查找所有元素
  var elements = document.getElementsByTagName("*");
// 遍历每个元素
  for (var i = 0, len = elements.length; i < len; i++) {
// 当前遍历到元素的所有类名
    var classNames = elements[i].className.split(" ");
// 遍历当前元素的类名
    for (var j = 0, l = classNames.length; j < l; j++) {
// 判断当前遍历到的类名是否与待查找元素的类名一致
      if (classNames[j] === className) {
// 一致,则说明当前遍历到的元素是待查找出元素其中之一
        result.push(elements[i]);
        break;
      }
    }
  }
// 返回查找到的结果
  return result;
}
//方法二
/*  
    *封装 class的获取方法
    *method  ByClass(classname)
    *param  [string] classname   class的名字
    *return  [string]    返回的class数组(元素集合)
*/

function ByClass(classname) {
    //判断 如果支持document.getElementsByClassName【document.getElementsByClassName】默认的只在IE9+
    if(document.getElementsByClassName) {
        return document.getElementsByClassName(classname);
    } else {    //针对IE 6、7、8
        var classArr = [];
        // 第一步:遍历所有元素节点
        var elesAll = document.getElementsByTagName('*');
        for(var i = 0; i< elesAll.length;i++) {
            // 第二步:将classname 与每一个标签的classname进行比对
            if(elesAll[i].className.index(classname) != -1) {
                //第三步:将匹配成功的推进新数组中
                classArr.push(elesAll[i]);
            }
        }
        return classArr;
    }
}
console.log(ByClass('one')); 

获取属性 1、获取属性:

  • 元素.attributes --获取元素属性集合 console.log(attributes); console.log(attributes[0]);
  • 元素.属性名【因为class是关键字,所以要写上className;用于获取元素】 console.log(baidu.className);
  • 元素.getAttribute(属性名)【用于获取某一个属性】 console.log(baidu.getAttribute('href')); [如果是class就不需要再用className了,因为''封装了不会起冲突] console.log(baidu.getAttribute('class'));

2、设置属性:

  • 元素.属性名 = '属性值'; baidu.style.color = 'red';
  • 元素.setAttribute(属性名,属性值); baidu.setAttribute('title','您点击之后不会发生改变');

3、移除属性 元素.removeAttribute(属性名);

4、判断是否有某一个属性 元素.hasAttribute(属性名) --返回值是一个布尔值

5、HTML5 自定义属性操作

  • element.dataset.自定义属性名(如:data-index)
  • element.getAttribute('data-index');
<body>
    <!--  
        HTML5 可以自定义属性,自定义的属性以 data- 开头,比如说设置index属性
    -->
    <a href="http://www.baidu.com" id="baidu" title="点击链接跳转到百度首页" class="baidu" data-index = '1'>首页</a>
    <script>
        var baidu = document.getElementsByTagName('a')[0];
        // 获取元素所有属性集合
        var attributes = baidu.attributes;
        console.log(attributes);
        console.log(attributes[0]);
        // 获取属性【因为class是关键字,所以要写上className;用于获取元素】
        console.log(baidu.href);
        console.log(baidu.className);
        console.log(baidu.getAttribute('href'));
        console.log(baidu.getAttribute('class'));
        baidu.style.color = 'red'; 
        baidu.setAttribute('title','您点击之后不会发生改变');
        //移除属性
        baidu.removeAttribute('class');
        console.log(attributes);
        if(baidu.hasAttribute('class')) {
            console.log(baidu.getAttribute('class'));
        } else {
            alert('您需要重新添加class');
        }
    </script>
</body>

通过获取节点修改css样式例子 1、JS动态创建标签

  • document.createElement(您需要创建的标签名字);document.createTextNode('动态创建文本内容');将文本放入标签
  • li.appendChild(text);//将子标签添加进父节点中
  • demo.appendChild(li);【父节点.appendChild(子节点);】 --将子节点添加到父节点的最后

2、删除子节点 父节点.removeChild(子节点); --代表移除子节点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .co {
            color: blue;
        }
    </style>
</head>
<body>
    <ul id="demo">
        <li>导航1</li>
        <li>导航2</li>
        <li>导航3</li>
    </ul>
    <button type="button" id="addColor">添加字体颜色</button>
    <button type="button" id="changeColor">修改字体颜色</button>
    <button type="button" id="addnav">添加导航</button>
    <script>
        var addColor = document.getElementById('addColor'),
            demo = document.getElementById('demo'),
            //获取demo下的所有li相当于后代选择器
            lis = demo.getElementsByTagName('li'),
            changeColor = document.getElementById('changeColor'),
            addNav = document.getElementById('addnav');
        // 给添加颜色按钮添加点击事件,改变css引用
        addColor.onclick  = function() {
            for(var i = 0;i < lis.length;i++) {
                lis[i].className = 'co';
            }
        }
        changeColor.onclick = function() {
            // 如果有颜色,就变为空,没有引用css样式
            if(lis[0].className) {
                for(var i = 0;i < lis.length;i++) {
                    lis[i].className = '';
                }
                // 如果没有颜色就把css样式引用起来,变为co
            } else {
                for(var i = 0;i < lis.length;i++) {
                    lis[i].className = 'co';
                }
            }
        }
        addNav.onclick = function() {
            //动态创建标签
            var li = document.createElement('li');
            //创建文本内容
            var text = document.createTextNode('动态创建文本内容');

            //将文本放入标签
            li.appendChild(text);
            //将子标签添加进父节点中

            demo.appendChild(li);
        }
    </script>
</body>
</html>

样式的操作 1、操作CSS样式

  • 元素.style.css属性名 = css属性值;【大多数都要加''因为是值】 demo.style.height = '50px'; demo.style.border = '2px solid red';

注意:【如果css单词是通过链接的单词,则需要写成驼峰式命名】 如:demo.style.borderBottom = '2px solid red';

【因为float是js中的保留字,所以要写为cssFloat】 如: demo.style.cssFloat = 'right';

  • cssText【可以帮助我么批量的设置CSS样式】demo.style.cssText += 'width: 400px;height: 50px;';
  • 添加 classname (推荐使用)提前在css中写好class,接下来动态添加class,比如:demo.className = 'demo box';demo.className = 'demo box'; 1、节点的创建、插入、替换和克隆
  • 创建标签节点document.createElement('标签名');
  • 创建文本节点document.createTextNode("文本内容")
  • 节点的增加父元素.appendChild(子节点); --将子节点添加到父元素的最后
  • 在某元素之前插入新元素父元素.insertBefore(新节点,旧节点);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            color: teal;
            background: lavender;
        }
    </style>
</head>
<body>
    <div class="demo"></div>
    <script>
        // 获取标签
        var demo = document.getElementsByClassName('demo')[0];
        // 设置css样式
        // demo.style.height = '50px';
        // demo.style.width = '50px';
        // demo.style.background = 'pink';
        // demo.style.borderBottom = '2px solid red';
        // demo.style.cssFloat = 'right';

        // demo.style.cssText += 'width: 400px;height: 50px;';

        // 优化部分
        // 通过动态添加class与移除class来改变css样式
        demo.className = 'demo box';
    </script>
</body>
</html>