JavaScript DOM基础


Posted in Javascript onApril 13, 2015

 DOM(Document Object Model)即文档对象模型,针对HTML和XML文档的API(应用程序接口);

 DOM描绘了一个层次化的节点树,运行开发人员可以添加/移除和修改页面的某一部分;

一 DOM介绍

 D(文档):可以理解为整个Web加载的网页文档;
 O(对象):可以理解为类似window对象之类的东西,可以调用属性和方法,这里说的是document对象;
 M(模型):可以理解为网页文档的树形结构;

1.节点

 加载HTML页面时,Web浏览器生成一个树形结构,用来表示页面内部结构;
 DOM将这种节点结构理解为由节点组成;
 html元素为根节点;head元素是html的子节点;meta元素和title元素之间是兄弟关系;

 
 2.节点种类:元素节点/文本节点/属性节点
<div title="元素属性">测试Div</div>
 元素节点 => div;
 属性节点 => title="元素属性"
 文本节点 => 测试Div二 查找元素
 W3C提供了比较方便简单的定位节点的方法和属性,以便我们快速的对节点进行操作;
 DOM(Document Object Model)即文档对象模型,针对HTML和XML文档的API(应用程序接口);

 DOM描绘了一个层次化的节点树,运行开发人员可以添加/移除和修改页面的某一部分;

元素节点查找方法
    方法                               说明
getElementById()              获取特定ID元素的节点;
getElementsByTagName()        获取相同元素的节点列表;
getElementsByName()           获取相同名称的节点列表;
getAttribute()                获取特定元素节点属性的值;
setAttribute()                设置特定元素节点属性的值;
removeAttribute()             移除特定元素节点属性;

1.getElementById()

// 方法接收一个参数:获取元素的ID;
// 如果找到相应的元素则返回该元素的HTMLDivElement对象;如果不存在,则返回null;
    document.getElementById('box');              // [object HTMLDivElement];
// 当我们通过getElementById()获取到特定元素节点时,这个节点对象就被我们获取到了;
// 而通过这个节点对象,我们可以访问它的一系列属性;
(1).访问元素节点的属性
    属性                             说明
    tagName                     获取元素节点的标签名;
    innerHTML                   获取元素节点里的内容,非W3C DOM规范;
    document.getElementById('box').tagName;      // =>DIV;
    document.getElementById('box').innerHTML;    // =>测试Div;

(2).访问HTML通用属性
    属性                             说明
    id                           元素节点的id名称;
    title                        元素节点的title属性值;
    style                        CSS内联样式属性值;
    className                    CSS元素的类;

    document.getElementById('box').id;           // =>id;
    document.getElementById('box').title;        // 获取title;

    document.getElementById('box').style;        // 获取CSSStyleDeclaration对象;
    document.getElementById('box').style.color;  // 获取style对象中的color的值;也就是设置在元素行内的样式值;
    document.getElementById('box').style.color='red';    // 设置style对象中的color的值;

    document.getElementById('box').className;    // 获取class;
    document.getElementById('box').className='pox';      // 设置class;

    document.getElementById('box').bbb;          // 获取自定义属性的值,非IE不支持;

2.getElementsByTagName()
// 方法返回一个对象数组HTMLCollection(NodeList)数组,这个数组保存着所有相同元素名的节点列表;
    document.getElementsByTagName('*');         // 利用通配符获取所有元素;
    // PS:IE在使用通配符时,会把文档最开始的html的规范声明当作第一个元素节点;

    document.getElementsByTagName('li');        // =>[object HTMLCollection];获取所有li元素;
    document.getElementsByTagName('li').[0];    // 获取第一个li元素;

3.getElementsByName()

 获取相同名称(name)设置的元素,返回一个对象数组HTMLCollection(NodeList);
     document.getElementsByName('add');          // 获取具有name='add'的input元素集合;
     // PS:对于并不是HTML合法的属性,那么在JS获取的兼容性上也会存在差异;
     // IE支持合法的name属性,但对于自定义的属性会出现不兼容问题;

4.getAttribute()
 方法将获取元素中某个属性值;
 但它和直接使用".attr"获取属性值的方法有一定区别;
     document.getElementById('box').getAttribute('mydiv');    // 获取自定义属性值;
     document.getElementById('box').mydiv;                    // 获取自定义属性值,仅IE支持;

5.setAttribute()
 方法将设置元素中某个属性和值;接收两个参数:属性名和值;
 如果属性本身已存在,那么就会覆盖;
     document.getElementById('box').setAttribute('align','center');    // 设置属性和值;
     // PS:在IE7及以下,使用setAttribute()方法设置class和style属性没有效果;

6.removeAttribute()
 方法可以移除HTML属性;
     document.getElementById('box').removeAttribute('style');         // 移除style样式属性;

三 DOM节点

1.node节点属性

// 节点可以分为:元素节点/属性节点和文本节点;
// 这些节点都有三个属性:nodeName/nodeType和nodeValue;

                  信息节点属性
 节点类型            nodeName            nodeType         nodeValue 
   元素                 元素名称             1              null
   属性                 属性名称             2              属性值 
   文本                 #text               3              文本内容
   document.getElementById('box').nodeType;            // =>1; 元素节点;

2.层次节点属性
// 层次节点可以划分为:父节点与子节点/兄弟节点;

// 当我们获取其中一个元素节点的时候,就可以使用层次节点属性来获取它相关层次的节点;

JavaScript DOM基础

节点关系示意图

层次节点属性
    属性                         说明
childNodes             读取当前元素节点的所有子节点;
firstChild             读取当前元素节点的第一个子节点;
lastChild              获取当前元素节点的最后一个子节点;
ownerDocument          获取该节点的文档根节点,相当于document;
parentNode             获取当前节点的父节点;
previousSibling        获取当前节点的前一个同级节点;
nextSibling            获取当前节点的后一个同级节点;
attributes             获取当前元素节点的所有属性节点集合;

(1).childNodes属性

 属性获取某一个元素节点的所有子节点,这些子节点包含元素节点和文本节点;
 PS:使用childNodes[n]返回子节点对象的时候,有可能返回的是元素子节点,比如:HTMLElement;
 也可能返回的是文本子节点,比如:Text;
 元素子节点可以使用nodeName或者tagName获取标签名称;而文本子节点可以使用nodeValue获取;
    var box = document.getElementById('box');
    for(var i=0; i<box.childNodes.length; i++){
         判断是元素节点,输出元素标签名;
        if(box.childNodes[i].nodeType === 1){
            console.log('元素节点:'+box.childNodes[i].nodeName);
         判断是文本节点,输出文本内容;
        }else if(box.childNodes[i].nodeType ===3){
            console.log('文本节点:'+box.childNodes[i].nodeValue);
        }
    }
     PS1:在获取到文本节点(重点在于已经不是元素节点)的时候,是无法使用innerHTML这个属性输出文本内容的;
     这个非标准的属性必须在获取元素节点的时候,才能输出里面包含的文本;
        alert(box.innerHTML);                                     innerHTML和nodeValue第一个区别;

     PS2:innerHTML和nodeValue在赋值的时候,nodeValue会把包含在文本里的HTML转义成特殊的字符,从而达到形成纯文本的效果;
     而innerHTML会解析文本里的特殊字符;
        box.childNodes[0].nodeValue = '<strong>abc</strong>';     =><strong>abc</strong>;
        box.innerHTML = '<strong>abc</strong>';                   =>abc(样式加粗);

(2).firstChild和lastChild属性
 firstChild = childNodes[0];获取当前元素的第一个子节点;
 lastChild = childNodes[box.childNodes.length-1];获取当前元素最后一个子节点;

(3).ownerDocument属性
 返回该节点的文档对象根节点,返回的对象相当于document;
   alert(box.ownerDocument === document);                        // =>true;根节点;

(4).parentNode/previousSibling/nextSibling属性

parentNode:返回该节点的父节点;
 previousSibling:返回该节点的前一个同级节点;
 nextSibling:返回该节点的后一个同级节点;
    alert(box.parentNode.nodeName);                      // 获取父节点的标签名;
    alert(box.firstChild.nextSibling);                   // 获取第二个节点;
    alert(box.lastChild.previousSibling);                // 获取倒数第二个节点;

(5).attributes属性
 属性返回该节点的属性节点集合;
     alert(document.getElementById('box').attributes);    // =>NamedNodeMap;

(6).忽略空白文本节点

var body = document.getElementsByTagName('body')[0];// 获取body元素节点;  
  alert(body.childNodes.length);           // 非IE=7;  IE=3;

  // PS:在非IE中,标准的DOM具有识别空白文本节点的功能,而IE自动忽略了;
  function filterSpaceNode1(nodes){
    // 新数组;
    var ret = [];
    for(var i=0; i<nodes.length; i++){
      // 如果识别到空白文本节点,就不添加到数组;
      if(nodes[i].nodeType ===3 && /^\s+$/.test(nodes[i].nodeValue)) continue;
      // 把每次的元素节点,添加到数组里;
      ret.push(nodes[i]);
    }
    return ret;
  }

  // PS:上面的方法,采用忽略空白文件节点的方法,把得到的元素节点累加到数组里返回;
  function filterSpaceNode2(nodes){
    for(var i=0; i<nodes.length; i++){
      if(nodes[i].nodeType ===3 && /^\s+$/.test(nodes[i].nodeValue)){
        // 得到空白节点之后,一道父节点上,删除子节点;
        nodes[i].parentNode.removeChild(nodes[i]);
      }
    }
    return nodes;
  }

  // PS:firstChild等方法在获取节点时遇到空白节点,处理方法;
  function removeWhileNode(nodes){
    for(var i=0; i<nodes.childNodes.length; i++){
      if(nodes.childNodes[i].nodeType ===3 && /^\s+$/.test(nodes.childNodes[i].nodeValue)){
        nodes.childNodes[i].parentNode.removeChild(nodes.childNodes[i]);
      }
    }
    return nodes;
  }

四 节点操作
// DOM不单单可以查找节点,也可以创建节点/复制节点/插入节点/删除节点和替换节点

节点操作方法
    方法                     说明
write()             这个方法可以把任意字符串插入到文档中;
createElement()     创建一个元素节点;
appendChild()       将新节点追加到子节点列表的末尾;
createTextNode()    创建一个文件节点;
insertBefore()      将新节点插入在前面;
replaceChild()      将新节点替换旧节点;
cloneNode()         复制节点;
removeChild()       移除节点;

(1).write()方法
// write()方法可以把任意字符串插入到文档中去;
document.write('<p>这是一个段落!</p>'); // 解析后文字;

(2).createElement()方法
createElement()方法可以创建一个元素节点;
document.createElement('p'); // [object HTMLParagraphElement];

(3).appendChild()方法
appendChild()方法将一个新节点添加到某个节点的子节点列表的末尾上;
var box = document.getElementById('box');
var p = document.createElement('p'); // 创建一个新元素节点<p>;
box.appendChild(p); // 把新元素节点<p>添加子节点末尾;

(4).createTextNode()方法
该方法创建一个文本节点;
var text = document.createTextNode('段落');
p.appendChild(text); // 将文本节点添加到子节点末尾;

(5).insertBefore()方法

// 该方法可以把节点添加到指定节点的前面;
  box.parentNode.insertBefore(p,box);      // 在<div>之前添加一个<p>;
  box.insertBefore(newNode,null);        // 将newNode添加到box自列表的最后节点;

  //PS:insertBefore()方法可以给当前元素的前面创建一个节点,但没有提供给当前元素的后面创建一个节点;
  function insertAfter(newElement,targetElement){
    // 得到父节点;
    var parent = targetElement.parentNode;
    // 如果最后一个子节点是当前元素,那么直接添加即可;
    if(parent.lastChild === targetElement){
      parent.appendChild(newElement);
    }else{
    // 否则,在当前节点的下一个节点之前添加;达成在当前节点后面添加节点的需求;
      parentNode.insertBefore(newElement,targetElement.nextSibling);
    }
  }

 (6).replaceChild()方法
该方法可以把节点替换成指定的节点;
box.parentNode.replaceChild(p,box); // 把<div>换成了<p>;

(7).cloneNode()方法

// 该方法可以把子节点复制出来;复制后返回的节点副本属于文档所有,但并没有为它指定父节点;
// 参数为true:执行深复制,就是复制节点及其整个子节点树;
// 参数为false:执行浅复制,只复制节点本身;
    var box = document.getElementById('box');
    var clone = box.firstChild.cloneNode(true);        // 获取第一个子节点,true表示复制内容;
    box.appendChild(clone);                            // 添加到子节点列表末尾;

(8).removeChild()方法
该方法删除指定节点;
box.parentNode.removeChild(box);

小结:在下一章~

Javascript 相关文章推荐
JQuery操作三大控件(下拉,单选,复选)的方法
Aug 06 Javascript
JS中使用apply、bind实现为函数或者类传入动态个数的参数
Apr 26 Javascript
JS模拟bootstrap下拉菜单效果实例
Jun 17 Javascript
解决微信浏览器Javascript无法使用window.location.reload()刷新页面
Jun 21 Javascript
JavaScript编码风格指南(中文版)
Aug 26 Javascript
Vue.js实现在下拉列表区域外点击即可关闭下拉列表的功能(自定义下拉列表)
May 30 Javascript
Javascript实现一个简单的输入关键字添加标签效果实例
Jun 01 Javascript
微信页面弹出键盘后iframe内容变空白的解决方案
Sep 20 Javascript
微信小程序之侧边栏滑动实现过程解析(附完整源码)
Aug 23 Javascript
JS实现分页导航效果
Feb 19 Javascript
jQuery实现移动端笔触canvas电子签名
May 21 jQuery
vue使用v-model进行跨组件绑定的基本实现方法
Apr 28 Vue.js
JavaScript 浏览器对象模型BOM使用介绍
Apr 13 #Javascript
JavaScript 匿名函数和闭包介绍
Apr 13 #Javascript
jfreechart插件将数据展示成饼状图、柱状图和折线图
Apr 13 #Javascript
为什么JS中eval处理JSON数据要加括号
Apr 13 #Javascript
使用window.prompt()实现弹出用户输入的对话框
Apr 13 #Javascript
jsMind通过鼠标拖拽的方式调整节点位置
Apr 13 #Javascript
javascript继承的六大模式小结
Apr 13 #Javascript
You might like
模板引擎Smarty深入浅出介绍
2006/12/06 PHP
php 文章调用类代码
2011/08/11 PHP
php文件上传的简单实例
2013/10/19 PHP
php性能分析之php-fpm慢执行日志slow log用法浅析
2016/10/17 PHP
Linux平台PHP5.4设置FPM线程数量的方法
2016/11/09 PHP
php解决DOM乱码的方法示例代码
2016/11/20 PHP
Prototype使用指南之dom.js
2007/01/10 Javascript
node.js中的fs.appendFile方法使用说明
2014/12/17 Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
2015/02/20 Javascript
JS实现仿中关村论坛评分后弹出提示效果的方法
2015/02/23 Javascript
JavaScript实现显示函数调用堆栈的方法
2016/04/21 Javascript
AngularJS过滤器详解及示例代码
2016/08/16 Javascript
详解Weex基于Vue2.0开发模板搭建
2017/03/20 Javascript
Vue项目接入Paypal实现示例详解
2020/06/04 Javascript
js闭包的9个使用场景
2020/12/29 Javascript
python3编写C/S网络程序实例教程
2014/08/25 Python
python实现统计代码行数的方法
2015/05/22 Python
Python时间的精准正则匹配方法分析
2017/08/17 Python
python如何生成网页验证码
2018/07/28 Python
Python 存储字符串时节省空间的方法
2019/04/23 Python
用python生成与调用cntk模型代码演示方法
2019/08/26 Python
python 导入数据及作图的实现
2019/12/03 Python
python 图像的离散傅立叶变换实例
2020/01/02 Python
美体小铺瑞典官方网站:The Body Shop瑞典
2018/01/27 全球购物
必须要使用游标的SQL语句有那些
2012/05/07 面试题
用JAVA实现一种排序,JAVA类实现序列化的方法(二种)
2014/04/23 面试题
女大学生自我鉴定
2013/12/09 职场文书
执行力心得体会
2013/12/31 职场文书
简历中的自我评价怎么写
2014/01/29 职场文书
硕士生找工作求职信
2014/07/05 职场文书
护理实习生带教计划
2015/01/16 职场文书
贷款承诺书
2015/01/20 职场文书
2015年医德考评自我评价
2015/03/03 职场文书
学校勤俭节约倡议书
2015/04/29 职场文书
有关水浒传的读书笔记
2015/06/25 职场文书
小学英语教学随笔
2015/08/14 职场文书