DOM
DOM
DOM document object model 文档对象模型
【注】w3c文档对象模式(dom)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容,结构和样式
html css页面内容 js页面行为操作 【dom】是打通html css和js壁垒的工具
D(文档)可以理解为web加载的网页文档;O(对象)可以理解类似window对象之类的东西,可以调用属性和方法,这里说的是document对象;M(模型)可以理解为网页文档的树型结构;
不管什么时候,只要是查询DOM中的某些元素,浏览器都会搜索整个DOM树,从中查找可能匹配的元素,如果太多的执行相同搜索操作,会影响性能,更好的办法是把第一次搜索的线索保存在一个变量中,然后在循环中重用该结果,还有个需要注意的,就是要减少文档中标记的数量,过多不必要元素只会增加DOM树的规模,进而增加遍历DOM树以查找特定元素的时间
节点
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
- 整个文档是一个文档节点
每个 HTML 元素是元素节点
- HTML 元素内的文本是文本节点
- 每个 HTML 属性是属性节点
- 注释是注释节点
- dom的第一个节点是HTML
DOM中节点种类一共三种 [注】在js中所有节点都是对象
例子 <div title="属性节点">测试div</div>
元素节点 <div></div>
属性节点 title="属性节点“
文本节点 测试div
当点击按钮使用document.write时,会使整个页面内容覆盖,它的使用范围有局限性,它只能在页面加载的时候去输出,不能在事件中去使用。
每次dom的改变会导致页面的重绘,字符串的每次拼接,因为字符串的不可变。都会重新开辟内存。需要耗费时间
// 最后输出<h1>我</h1> oDiv.tagName 输出DIV
HTML属性的属性
id、title(在鼠标移到元素上时显示一段工具提示文本)、style、className在获取class时,必须使用className 不能使用class
访问这些属性,这里指的是,比如要获取一个div的class名 不能div.class 会输出unfined,得使用div.className,才能得到class名
访问属性两种方式
元素节点.属性名
元素节点【属性名】
赋值操作
window.onload = function(){
var odiv =document.getElementById("div1");
odiv.title="world";
odiv.className="oxb";
odiv.style.width="400px;//赋值操作 修改id为div1的title和className  style属性
odiv.style.backgroundColor="blue";//在style样式中 有类似background-color使用-链接的属性 访问时需要把-去掉,然后将后续单词首字母大写
} 
</script>
<body>
<div id="div1" class="div2" title="hello" style="width=300px;heigjt:300px;">123</div>
</body>
document.getElementsByTagName()
参数:标签名 功能:获取当前页面上所有符合该标签名标准的元素节点 返回值:所有符合条件的元素节点
也可以写成 node(节点).getElementsByTagName() [注】从node节点内部,找出所有符合条件的元 素节点
如果把特殊字符串 " * " 传递给 getElementsByTagName() 方法,它将返回文档中所有元素的列表,元素排列的顺序就是它们在文档中的顺序。
可以用 getElementsByTagName() 方法获取任何类型的 HTML 元素的列表。例如,下面的代码可获取文档中所有的表:
例
<body>
<ul id="ul1">
<li>1111</li>
<li>222</li>
<li>333</li>
<ul>
<script>
var a =document.getElementById("ul1");
var b=a.getElementsByTagName("li");//获取了ul下所有的li标签
</script>
</body>
document.getElementsByName()
参数 name的值 返回值:装有符合条件的元素节点的数组 【注】不支持从某个节点开始检索
name 属性规定 input 元素的名称。
name 属性用于对提交到服务器后的表单数据进行标识,或者在客户端通过 JavaScript 引用表单数据。
注释:只有设置了 name 属性的表单元素才能在提交表单时传递它们的值。
id要符合标识的要求,比如大小写敏感,最好不要包含下划线(因为不兼容CSS)。而name基本上没有什么要求,甚至可以用数字。ID就像是一个人的身份证号码,而Name就像是他的名字,ID显然是唯一的,而Name是可以重复的。
例子
var a =document.getElementsByName("hello")检索符合name=“hello”的节点
node.getElementsByClassName()
【注】IE6 7 8版本不支持此方法,为了避免不兼容可以通过封装函数,封装一个兼容的方法
获取所有指定类名的元素:
var x = document.getElementsByClassName("example");
功能:获取node节点下,所有符合条件的元素节点。 所有符合条件的元素节点组成的数组
兼容封装方式

获得当前样式getComputedStyle
格式 getComputedStyle(元素节点)【获取样式类型】
例子 getComputedStyle(odiv)["width"]
【注】获取当前“”有效“”样式(有效得看样式优先级);只有火狐,谷歌,safari支持
IE下 元素节点.currentStyle【获取样式类型】;
IE【注】浏览器兼容window.onload = function(){
var a =document.getElementById("div1");
alert(getStyle(a,"width"));
};//这里得用window.onload 要不获取不到getStyle封装函数,因为封装函数在下面创建的
function getStyle(elem,attr){
return elem.currentStyle ? elem.currentStyle[attr]:
getComputedStyle(elem)[attr];
};//先用三元操作符判断currentstyle是否存在,如果存在输出 IE的elem.currentStyle[attr]:,如果不存在输出getComputedStyle(elem)[attr];       
</script>
</head>
<body>
<div id="div1" style="width:400px;height:300px;>
123
</div>
textContent
textContent 属性设置或者返回指定节点的文本内容。
如果你设置了 textContent 属性, 任何的子节点会被移除及被指定的字符串的文本节点替换。
提示: 某些时候 textContent 属性可以被 nodeValue 属性取代,但是请记住这个属性同样可以返回所有子节点的文本。
<ul id="myList"><li id="item1">Coffee</li><li id="item2">Tea</li></ul> <p id="demo">单击按钮获取列表元素的文本内容</p> <button onclick="myFunction()">点我</button> <script> function myFunction(){ var lst=document.getElementById("myList"); var x=document.getElementById("demo"); x.innerHTML=lst.textContent; }
//输出了CoffeeTea

 
?号 三元操作符
这个是三元操作符,它在每一种语言中的功能和语法都是一样的。
举例:   int a?1:0;
解释:a存在的话 返回1,a不存在返回0;
?是判断的意思,: 是否则的意思。
在js中应用
js的三元操作符简便使用方法
 oBth.onclick=function(){
        if (oUl.style.display=='block') {
            oUl.style.display=='none';
        }else{
            oUl.style.display=='block';
        }
    }
类似三元:
oBth.onclick=function(){
    oUl.style.display == "block" ? oUl.style.display="none" : oUl.style.display="block"
}
多个三元操作符
function ef(a){
if(60<=a&a<70){
 return "及格";
 }else{
 if(70<=a&a<90){
 return "优秀";}
 else{
 if(90<=a){
 return "天才"}
 else{
 return "不及格";
 }
 }
 }
 };
 alert(ef(70));
等于
 function ff(b){
 return b>=60?>70?b>90?"天才":"优秀":"及格":"不及格";
 };
alert(ff(70));
两者相同,多个?三元操作符 就是一个个往里面加 满足上一个条件,就在?后面添加条件 后面添加的条件得满足上个条件,类似一个个缩小的区间,比如先满足b>=60 然后再加个条件,b>70 ,然后条件变为 60<=b<90,之后再加条件,b<70,条件变为60<=b<70
三元用法 this.xxx=this.xxx==-1?1:-1; //因为this.xxx不存在是undefined,不等于-1所以根据三元式返回-1,此时this.xxx被赋值了-1,下次调用根据三元就会被赋值成1,可以用在场景,点一下换一种操作的时候
封装函数
把
id document.getElementById()
tagName node.getElementsByTagName()
name document.getiElementsByName()
className document.getElementsByClassName()
通过封装函数简化操作 封装一个函数,可以拥有几种获取元素节点的功能。
【注】 css选择器
#id 通过id获取元素节点
.class 通过className获取元素节点
tagName 通过tagName获取元素节点
name=xxx 通过name获取元素节点
set/getAttribute() 设置和获取节点属性
removeAttrite()删除当前元素节点某个属性
【注意】它们不属于document对象,所以不能通过document对象调用,只能通过元素节点调用
例子
<script>
window.onload = function(){
odiv = document.getElementById("div1");
//alert(odiv.title)访问div1的title
//odiv.title="xxx" 修改divtitle
//alert(odiv.getAttribute("title"))访问div1的title
//odiv.setAttribute("title","xxx")修改div1title
</script>
<body>
    <div  id="div1" title="hello" name="world" class="box">123</div>
</body>
/*上述两种方式区别,
- 通过getAttribute("属性名")和setAttribute("属性名","属性值") 可以获取或修改标签上的属性值
- 通过 点操作符+属性名 可以获取或修改元素对应的DOM对象的属性值
- 用 . 来引用,必须是内置的(IE 可以访问自定义属性),而且引用的时候,区分大小写。
- 用getAttribute 来引用,可以访问自定义属性,不区分大小写。
- 使用 . 运算符和 setAttribute都可以。但是对于自定义属性,使用.运算符的设置的属性无法通过getAttribute获取,反之亦然,只有setAttribute设置的自定义属性才能用getAttribute获取
2、设定用户自定义属性
直接获取的方式只能获取节点本来具有的属性,而getAttribute()可以获取自己定义的属性,例如阿猫阿狗;
3、removeAttribute可以删除属性,点操作不行,最多设置为空
例子
<p id="name" align="left" title="名字" test="测试">妙音天女</p>
    var myname=document.getElementById("name");//myname是HTMLParagraphElement类型的DOM对象
 
    console.log(myname.title);//名字 //HTMLParagraphElement具有title属性(继承自父类HTMLElement)
    console.log(myname.getAttribute("title"));//名字 //p标签具有title属性(html标签的全局属性)
 
    console.log(myname.align);//left //HTMLParagraphElement具有align属性
    console.log(myname.getAttribute("align"));//left //p标签具有align属性
 
    console.log(myname.test);//undefined//HTMLParagraphElement类型的myname对象没有test属性
    console.log(myname.getAttribute("test"));//测试 //此处的p标签具有自定义的test属性
 
    console.log(myname.innerHTML);//妙音天女 //HTMLParagraphElement具有innerHTML属性(继承自祖父类Element)
    console.log(myname.getAttribute("innerHTML"));//null //p标签没有innerHTML属性
 
    myname.hi="hello";
    console.log(myname.hi);//hello //myname对象具有hi属性
    console.log(myname.getAttribute("hi"));//null //p标签没有hi属性
我们可以清晰地看到,
- 对于HTML标签和相应的DOM对象都具有的属性(如例子中的title属性和align属性),两种方法取得的值是相同的
- 对于HTML标签具有而DOM对象不具有的属性(通常是标签上的自定义属性,如例子中的test属性,或data-* 属性),getAttribute()可以取得相应的属性值,但点操作符返回undefined
- 对于DOM对象具有而HTML标签不具有的属性(如例子中的innerHTML和对象上自定义的hi属性),点操作符可以取得相应的属性值,但getAttribute()返回null
元素节点属性
DOM节点类型 元素节点 本文节点 属性节点
其中nodeValue可以用来设置节点的值
nodeName 对于html文档始终返回大写形式(可以用toLowerCase改成小写),对于xml文档,因为xml文档区别大小写,所以返回值与源代码形式一致
childNodes
获取当前元素节点的所有子节点,包括两种节点类型,文本节点 元素节点
例子
<div id="div1"><em>123</em>abc<strong>bbb</strong></div>
odiv=document.getElementById("div1");   
odiv.childNodes     odiv.childNodes.length//输出3 因为包含2个节点 文本节点1 元素节点2
 
但是如果div这样写
<div id="div1">
      <em>123</em>
       abc
       <strong>bbb</strong>
</div>    //输出5 因为多了两个空白文本节点,因为在键盘上输出的所有字符都是字符串 包括回车 换行 tab 空格
空白节点
1.为什么会出现空白节点的问题
因为浏览器的差异在对于非空文本节点前面或后面有空格或换行符等特殊的文本字符组成,IE和FF(火狐)就会产生分歧,IE会忽略这些节点,而FF则认可这些节点
【问题】如何将空白节点取出
通过正则表达式 /^\s+$/.test() 如果空白节点返回true,不是返回false
//删除空白节点的第一个方法封装函数,但是父节点上空白节点还在
第二个方法 使用firstChild 和lastChile 从父节点上删除空白节点
firstChild 快速找到元素节点子节点的第一个 例子 odiv.firstChild.nodeName //em
lastChild 快速找到元素节点子节点的最后一个 例子 odiv.lastChild.nodeName //strong
删除数组元素必须倒序删除 ,因为正序删除,如果删除到后面的数,后面的未接触到的数会往前顶,下标会发生改变,而倒序删除,未接触的数下标不会发生改变
ownerDocument属性
parentNode
属性返回该节点的父节点
previousSibling
属性返回该节点的前一个同级节点//会有空白文本节点,得删除空白节点
nextSibling属性
返回元素节点之后的兄弟节点(包括文本节点、注释节点,即回车、换行、空格、文本等等);
这三个后面得加需要的元素,比如nodeName 需要什么元素就在后面加什么元素、加上了后就是输出需要的元素,比如UL,要不然会输出object HTMLUListElement ,object HTMLUListElement 是整个UL元素。而我们只需要它的其中一个元素。
nextElementSibling
属性只返回元素节点之后的兄弟元素节点(不包括文本节点、注释节点);
attribute属性
返回该节点的属性节点集合 【集合特点】1、不重复 2、无序
读取 <a href="dom_obj_attributes.php" target="_blank">Attr 对象</a>. <p id="demo">单击按钮以显示上述链接的目标属性的值</p> <button onclick="myFunction()">点我</button> <script> function myFunction(){ var a=document.getElementsByTagName("a")[0]; document.getElementById("demo").innerHTML=a.getAttribute("target"); } </script> //_blank
返回 id=“div”
节点操作
属性节点是由 nodeName nodeType nodeValue组成
createElement()
【格式】document.createElement(标签名);【功能】创建一个新节点
appendChild()
【格式】 parent.appendChild(newNode) ;【功能】将newNode插入到parent子节点的末尾
createTextNode()
【格式】 document.createTextNode(文本内容);【功能】创建文本节点 
如果要插入一个带文本的节点,那就先创建新节点,再创建文本节点 之后用 新节点名.appendChild(文本节点) 把文本内容添加进新节点 之后再用appendChild把新节点插入到想插入的
插入一个带文本的节点的第二个方法,直接创造一个带文本节点 通过封装函数
insertBefore()
[格式]父节点.insertBefore(插入的节点,旧节点);
功能:将插入的节点插入到旧节点之前
例子
这里的creatElementWithTxt是封装函数。详情看上上图
【注】js中没有 insertAfter()这个方法,只能通过封装函数来创建
//nextSibling 属性返回该节点的后一个同级节点//会有空白文本节点,得删除空白节点
节点操作方法
replaceChild()
[格式] parent.replaceChild(newNode,oldNode);
功能 :用newNode将oldNode给替换掉
cloneNode()
[格式]node.cloneNode()
功能:克隆节点 返回值:新克隆的节点
参数:true 默认是false 如果传true,就会复制元素节点中的innerHTML
例子 var node=oDiv.cloneNode();这是默认参数 var node=oDiv.cloneNode(true);这样会复制innerHTML
removeChild()
[格式] node.parentNode.removeChild(node); 功能 删除指定元素的某个指定的子节点。
例子odiv.removeChild(odiv.childNodes[0]);删除odiv子节点的第一个
获得焦点focus方法
深入理解javascript中的焦点管理 https://www.cnblogs.com/xiaohuochai/p/5874447.html
focus()方法用于将浏览器的焦点设置到表单字段,即激活表单字段,使其可以响应键盘事件
[注意]前面介绍过,若非表单元素,设置为tabIndex为-1,也可以获取焦点
例子
<span id="test1" style="height:30px;width:100px;">span</span>
<input id="test2" value="input">
<button id="btn1">span元素获得焦点</button>
<button id="btn2">input元素获得焦点</button>
<script>
btn1.onclick = function(){test1.tabIndex=-1;test1.focus();}
btn2.onclick = function(){test2.focus();}
</script>
失去焦点 brus
失去焦点 blur
如果使用javascript使元素失去焦点,那么就要使用blur()方法
blur()方法的作用是从元素中移走焦点。在调用blur()方法时,并不会把焦点转移到某个特定的元素上;仅仅是将焦点从调用这个方法的元素上面移走而已
 
                    
                










 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号