常见的DOM操作有哪些

大家好,我是IT修真院上海分院1期的Web学员刘洪利,今天给大家分享一下关于JavaScript中常见的DOM操作


1.背景介绍

        什么是DOM?简单地说,DOM是一套对文档的内容进行抽象和概念化的方法

        在现实世界里,人们对所谓的'世界对象模型'都不会陌生,例如,当用'汽车'、'房子'和'树'等名词来称呼日常生活环境里的事物时,我们都可以百分百的肯定对方知道我们说的是什么,这是因为人们在对这些名词所代表的的东西有着相同的认知。于是,当对别人说"汽车停在车库里"时,可以断定他们不会理解为"小鸟关在壁橱里"

        我们的"世界对象模型"不进可以用来描述客观存在的事物,还可以同来描述抽象概念。例如,假设有个人想我问路,而我给出的答案是"左边第三栋房子",这个答案有没有意义取决于那个人能够理解"左边"和"第三"的含义。如果他不会数数或者分不清左右,则不管他是否理解这几个概念,我的回答对他都不会有任何的帮助。在现实世界中,正是因为大家对抽象的"世界对象模型"有着基本的共识,人们才能用非常简单的话来表达出复杂的含义并得到对方的理解。

        而DOM的定义则是由W3C所制定的标准,定义为"一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态地访问和修改文档的内容`、结构和样式。"


2.知识剖析

        2.1. 节点是什么

        节点这个词是一个网络用语,代表了网络中的一个连接点。一个网络就是由一些节点构成的集合。

        在现实世界中,一切事物都由原子构成。原子就是现实世界的节点。但是原子同样还可以进一步分解为更细小的亚原子微粒。这些亚原子微粒同样也是节点。

        DOM也是同样的情况。文档是由节点构成的集合,只不过此时的节点是文档树上的树枝和树叶而已。

        在DOM中有许多不同类型的节点。就像原子包含着亚原子微粒那样,也有很多类型的DOM节点包含着其他类型的节点。接下来我们先看看其中的三种:元素节点、文本节点和属性节点。

        2.2. 元素节点

        在DOM中的原子就是元素节点。

        像是我们现在所看到的这个网页,我们在编写时,会用到诸如<body>、<head>、<p>这些元素。如果把Web上的文档比作一座大厦,那么元素就是建造这座大厦的砖块,这些元素在在文档中的布局形成了文档的结构。元素可以包含其他的元素,在我们所看到的页面页中,内容都被包含在在一个<section>元素的内部。而唯一没有被包含在其他元素中的唯一元素是'<html>',他和我们的节点树的根元素,其他的所有元素都被包含在'<html>'中。

网页的部分节点树

        2.3. 文本节点

        元素节点只是节点类型的一种。如果一份文档完全有一些空白元素构成,他将有一个结构,但这份文档本身将不会包含什么内容。

        在我们的ppt首页中,'<p>'元素包含着文本,'分享人:刘洪利'。他就是一个文本节点。在html文档里,文本节点总是被包含在元素节点的内部。

        2.4. 属性节点

        属性节点用来对元素做出更具体的描述。例如,几乎所有的元素都有一个title属性,而我们可以利用这个属性对包含在元素里的东西做出准确的描述:'<p title="a gentle reminder">这是一个带有温馨提示的p标签</p>'

        在DOM中,title="a gentle reminder"是一个属性节点。因为属性总是被放在起始标签里,所以属性节点总是被包含在元素节点中。并非所有的标签都包含着属性,但是所有的属性都被元素包含。

元素的构成

        2.5. 常见的DOM操作


获取DOM

        通过使用 getElementById() 方法匹配元素的id属性来访问元素节点,对元素节点进行操作

        通过使用 getElementsByTagName() 方法匹配元素的tagName来访问元素节点,对元素节点进行操作

        通过使用 getElementsByClassName() 方法匹配元素的className来访问元素节点,对元素节点进行操作

        值得注意的是, getElementsByTagName() 和 getElementsByClassName() 这两种方法因为其访问的是节点中的可能为复数的属性,所以得到的会是一个以数组的形式来体现出来的元素节点集合,我们可以通过打印获取到的DOM节点来判断类型

                                                                                                        demo

DOM事件

        onclick事件---当用户点击时执行

        onload事件---当用户进入时执行

        onunload事件---用用户离开时执行

        onmouseover事件---当用户鼠标指针移入时执行

        onmouseout事件---当用户鼠标指针移出时执行

        onmousedown事件---当用户鼠标摁下时执行

        onmouseup事件---当用户鼠标松开时执行

                                                                                                        demo


3. 常见问题

如何通过class和tag调用元素?如何对其设置属性?


4.解决方案

在一个页面中常常有多个class相同的元素,也有多个标签相同的元素,在调用时方法如下

                                                                                                        demo


5. 扩展思考

        onblur事件---当对象失去焦点时发生

        onchange事件---当对象域的值被改变时发生

        button 事件---属性可返回一个整数,指示当事件被触发时哪个鼠标按键被点击。

        更多的事件就不一一的描述了,有兴趣的同学可以去看下这个

                                                                                                     w3school


6. 参考文献

书籍:《JavaScript DOM编程艺术》

网址:w3school


7.更多讨论

            Q:dom操作是异步的吗

            A:dom的操作其实是同步的,但是渲染是异步的。因为JavaScript引擎线程跟GUI渲染线程是互斥的,即我执行的时候,你就靠边站,我执行完你才能执行。具体的可以看下这篇文章https://segmentfault.com/a/1190000005803237----《关于修改DOM是异步还是同步的问题

            Q:除了getElementsByClassName()、getElementsByTagName()、getElementById()还有什么可以获取dom节点的方法

            A:

1.通过节点属性得到元素

                    1)node属性:来获取节点的名称、类型、值。

js代码:

                    window.onload=function(){ 子节点

                        var pox = document.getElementById('pox');

                        alert(pox.childNodes.length) //子节点数量

                        alert(pox.childNodes[0].nodeValue); // 第一个子节点的内容

                        alert(pox.firstChild.nodeValue);  // 第一个子节点的内容

                        alert(pox.lastChild.nodeValue); // 最后一个节点的内容

                    };

        注意:node只能获取当前节点的东西,在上面的js代码中node本身把节点指针放在元素上,所以本身没有value值,

2.层次节点属性:层级节点可以分为父子节点和兄弟节点,通过当前节点可以获取其他层次的节点。

        2.1)子节点childNodes、第一个字节点firstChilds、最后一个子节点lastChilds。

js代码:

        window.onload=function(){ 子节点

            var pox = document.getElementById('pox');

            alert(pox.childNodes.length) //子节点数量

            alert(pox.childNodes[0].nodeValue); // 第一个子节点的内容

            alert(pox.firstChild.nodeValue);  // 第一个子节点的内容

            alert(pox.lastChild.nodeValue); // 最后一个节点的内容

        };

        2.2)父节点parentChild、兄弟节点previousSibing,nextSibing。

js代码:

        window.onload=function(){ 父节点,上下节点

            var pox = document.getElementById('pox');

            alert(pox.parentNode);    //pox节点的父节点body节点

            alert(pox.firstChild.nextSibling);    //pox节点的子节点中第一个节点的下一个节点

            alert(pox.lastChild.previousSibling);  //pox节点的子节点中最后一个节点的上一个节点

            alert(pox.lastChild.previousSibling.nodeName)

        };

本回答摘自-----------《获取元素节点(DOM基础 )》http://blog.csdn.net/u010928364/article/details/43935875

            Q:dom操作的最佳实践应该是什么样的

            A:

                    1. 平稳退化:正确的使用JavaScript脚本,让访问者在他们浏览器不支持JavaScript的情况下仍能顺利的浏览你的网站,即是有些功能无法使用,但最基本的操作仍能顺利完成。

                    2. 分离JavaScript:将HTML内部DOM事件分离到外部来,保证HTML的纯净,同时可以在外部js文件通过获取DOM节点来给这个节点添加事件的形式来运行外部JavaScript文件。

                    3. 向后兼容:因为不同浏览器对JavaScript的支持程度也不一致,绝大多数的浏览器都可以或多或少的支持JavaScript,,但比较古老的浏览器却很有可能无法理解DOM提供的方法和脚本。因此,我们通过以下几点来确保那些古老的浏览器不会因为脚本代码而出问题。

                            3.1. 对象检测:检测浏览器对JavaScript的支持程度。我们可以通过将某种方法打包在一个if语句中,然后根据这条语句的条件表达式的求值结果为true(这个方法存在)还是false(这个方法不存在)来决定应该采取怎么样的行动。

                            例如,如果有一个使用了getElementById()方法的函数么就可以在调用getElementById()方法之前先检查用户所用的浏览器是否支持这个方法。在使用对象检查时,一定要删除方法名后面的圆括号,如果不删掉,测试的将是方法的结果,无论方法是否存在

                            代码:

if( ! document.getElementById ) return false;


                    4. 性能考虑: 为保证应用流畅的运行,在为文档编写和应用脚本时,需要注意一些问题。

                            4.1. 尽量少访问DOM和尽量减少标记

                                    访问DOM的方式对脚本性能会产生很大的影响。例如当我们需要访问html页面中所有的div元素来找到我们想要的那个节点,我们不知道会有多少div元素来面对着我们,所以浏览器会去搜索整个DOM树,从中查找可能匹配的元素。

                                    另一个是尽量减少文档中的标记数量。过多不必要的元素只会增加DOM树的规模,进而增加遍历DOM树以查找特定元素的时间。

                            4.2. 合并和放置脚本

                                    我们通过合并外部JavaScript文件来减少加载页面时发送的请求数量。减少请求数量通常都是在性能优化时优先考虑的。

                            4.3. 压缩脚本

                                    通过将脚本文件中不必要耳朵字节,如空格和注释统统删除,从而达到“压缩文件”的目的。


小课堂提问



鸣谢

感谢大家观看

分享人:刘洪利

IT修真院上海Web第1期学员刘洪利: 邀请码14898047

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容