DOM,BOM

Posted pavilion-y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DOM,BOM相关的知识,希望对你有一定的参考价值。

1. DOM

1.1. DOM基本概念

1.1.2. 什么是DOM?

Document Object Model:文档对象模型,也叫文档树模型,是一套操作html和XML的一套API

1. 文档对象模型
HTML页面的所有的内容,包括标签、节点、注释、属性等,在JS的DOM中,都存在一个一个的对象与之对应。因此当我们想要操作这些HTML的内容时,只需要操作这些对象即可。

节点:页面中所有的内容,包括标签、节点、注释、树形都被封装成了对象,我们把这些对象叫做节点。
元素:我们最常操作的是标签节点,也叫元素。


2. 文档树模型
HTML结构是一个树形结构,同样的,这些对应的对象也是一个树形的结构,树形结构的好处是能够非常容易找到某个节点的子节点、父节点、兄弟节点。
子节点:child
兄弟节点:sibling
父节点:parent

3. API:Application Programming Interface:应用程序编程接口,其实就是一大堆的方法,我们可以把API看成是工具。做不同的事情需要不同的工具。
做饭需要一套做饭的工具:锅碗瓢盆
打仗需要一套打仗的工具:刀枪剑戟
找对象需一套找对象的工具:钱权颜缘 +  车房钱权
DOM:用来操作页面元素的一套工具。
BOM:用来操作浏览器一些行为的一套工具。

4. XML:XML(Extensible Markup Language:可扩展性标记语言,通常用于配置文件,或者和json一样用于数据交互。
<student>
    <name>张三</name>
    <age>18</age>
    <sex>男</sex>
</student>

树形结构示意图:

技术分享图片

1.2. DOM初体验

想要操作DOM,首先需要获取到DOM对象。

【案例:DOM对象初体验.html】

1.2.1. 根据id获取元素

<div id="box">123</div>
var element = document.getElementById("box");

1. document:指的是整个html页面,在DOM中被封装成了一个对象,就是document对象
2. getElementById:通过id获取元素
3. 参数是一个字符串,即id
4. 返回值是一个元素,即一个对象,标签中存在的属性,在这个元素中也有属性与之一一对应。

1.2.2. 如何打印一个对象

console.log():以标签的形式打印一个对象
console.dir():以对象的形式打印一个对象

1.3. 注册事件

javascript和HTML之间的交互是通过事件来实现的。 事件就是文档或者浏览器窗口发生的一些特定的交互瞬间。 JavaScript是一门事件驱动的脚本语言

 

1.3.1. 事件三要素

事件源:触发事件的元素
事件名称:触发的事件名称
事件处理函数:触发事件时调用的函数

1.3.2. 注册事件的两种方式

  • 行内式注册事件(不用)
<img src="images/1.jpg" alt="描述" id="img" onclick="changePic()">
  • 内嵌式注册事件
var img = document.getElementById("img");/*找到img这个标签*/
img.onclick = function() {
  img.src = "images/2.gif";
}

1.3.3. 给a标签注册事件

return false可以阻止页面跳转。

1.4. 查找DOM对象

1.4.1. 根据标签名获取元素

var links = document.getElementsByTagName(“a”)
//1. 根据标签名获取元素,返回的是一个伪数组
//2. 伪数组:可以跟数组一样进行遍历,但是不能使用数组的方法。
//3. this的使用,谁调用,指向谁
对于getElementsByTagName方法,不仅可以通过document调用,还可以通过元素来调用
1. document.getElementsByTagName("a");//查找页面中所有的a标签。
2. var box = document.getElementById("box");
    box.getElementsByTagName("a");//查找box中所有的a标签。

1. 属性操作

1.1. 普通标签属性

我们知道,在标签中存在的属性,在DOM对象中同样存在着对应的属性,只要修改了标签的属性或者DOM对象的属性,两边都会变化。常见的属性有:src、title、src、href、className、id等

鼠标经过事件与鼠标离开事件

onmouseover:当鼠标经过时触发
onmouseout:当鼠标离开时触发

1.2. 表单属性操作

常见的表单属性有:disabled、type、value、checked、selected

1.2.1. 布尔类型属性

对于disabled、checked、selected三个属性来说,比较特殊。

在标签中,只要指定了disabled属性,无论有值没值,都代表这个input是被禁用的。
在DOM对象中,disabled的属性是一个布尔类型的属性,值只有true或者false

获得焦点与失去焦点案例

onfocus:获得焦点时触发
onblur:失去焦点时触发

1.3. 标签的自定义属性

我们之前讨论的属性,都是HTML规范中,标签本来就有的属性,对于标签自定义的一些属性,比较特殊。

在html页面中,定义一个自定义属性

<div id="box" aa="bb"></div>

在对应的DOM对象中是不存在的,在DOM对象中只会存在固定的那些属性。

var box = document.getElementById("box");
console.log(box.aa);//undefined

1.3.1. attribute系列

attribute系列方法用于设置标签的属性,不管是自定义的还是固有的属性。

getAttribute(name);
setAttribute(name, value);
removeAttribute(name);

1.3.2. 排他思想

干掉所有人,复活我自己

 

1.4在原来的类名基础上  添加/删除类名(    IE678不兼容)

  btn.onclick = function () {
 
    box.classList.add("red");
  }
  btn1.onclick = function () {
    删除red类
    box.classList.remove("red");
  }

1. 克隆节点

语法:var newNode = node.cloneNode(deep)

功能:在内存中克隆一份节点

返回值:克隆出来的节点

参数:deep

  • false:默认值:是浅复制,只会复制标签,节点本身,不会复制节点的孩子。
  • true:深度复制,会复制标签,还会复制标签的所有内容 常用
  1. 克隆出来的节点跟原来的节点没有关系了,修改了也不会相互影响。
  2. 如果克隆的节点带了id,我们需要给id重新设置一个值,不让id冲突

2. 添加节点

2.1. appendChild

语法:parent.appendChild(newChild)

parent:调用者,父节点来调用

newChild:需要添加的那个孩子。

作用:把newChild添加到parent的孩子的最后面。

如果添加的是页面中本来就存在的元素,是一个剪切的效果,原来的就不在了。

var demo = document.getElementById("demo");
var box = document.getElementById("box");
box.appendChild(demo);

2.2. insertBefore

语法:parent.insertBefore(newChild, refChild);

parent:必须要父节点来调用

newChild:需要添加的那个节点

refChild:添加到哪一个节点的前面。

var ul = document.getElementById("list");
var li = document.createElement("li");
li.innerHTML = "骥骥";
//就是添加到子节点的最前面。
ul.insertBefore(li, ul.children[0]);

2.3. 双击事件

ondblclick:双击的时候触发

3. 创建节点

3.1. document.write(基本不用)

可以生成新的节点,但是不推荐使用。如果页面已经加载完成了,你还是用document.write写内容的话,会把之前的页面给覆盖掉

原理:页面从上往下加载的时候,会开启一个文档流,当页面加载完,文档流就会关闭。

document.write的本意就是在文档流上写入内容。如果页面没加载完成,文档流还是开着的,document.write直接在这个文档流上写东西

如果页面加载完成了,还是用document.write写东西,会重新开启一个新的文档流,往新的文档流上写东西,旧的文档流就被新的文档流覆盖了。

3.2. innerHTML

innerHTML也可以创建节点

innerHTML创建节点的时候有一个特点,如果原来有内容的话,使用innerHTML会把原先的内容给干掉。

慎用:很容易出现效率问题。

3.3. createElement

语法:var element = document.createElement("tagName");

作用:在内存里面创建了一个节点

返回:一个元素

用途非常的广泛。

4. 删除节点

语法:parent.removeChild(child);

功能:有父盒子调用,删除里面的一个子元素。

删除节点必须要父节点

 

 

 

 

1. 标签内容

innerText和innerHTML属性都是用来获取和设置标签的内容的。但是二者还是有区别的。

1.1. innerHTML

innerHTML可以用于获取和设置标签的所有内容,包括标签和文本内容

//innerHTML:内部的HTML
//  获取标签内容的时候,不管标签还是文本,都能获取到   标签+文本
//  innerHTML设置内容的时候,覆盖原来内容,标签也能生效,浏览器能解析这个标签。

1.2. innerText

innerText可以用于获取和设置标签的文本内容,会丢弃掉标签

//innerText:内部 文本
//  获取标签内容的时候,只会获取文本,标签扔掉了
//  设置标签内容的时候,覆盖原来内容,对标签进行转义(目的:把标签直接当文本来用)

二者的区别:

  • innerHTML是W3C的标准属性,而innerText是IE提出来的属性,存在兼容性问题。因此更加推荐大家使用innerHTML。
  • innerText的作用:防止xss攻击

1.3. innerText的兼容性问题

浏览器兼容性:指网页在各种浏览器上的显示效果不一致。或者是一些属性和方法在低版本的浏览器中不支持。

//1. innerText是IE提出来的属性,因此低版本的火狐浏览器不支持这个属性。
//2. 火狐有一个textContent属性,效果跟innerText一样,但是IE678不支持这个属性

解决浏览器兼容性的处理方式:

1. 能力检测(常用)
2. 代理检测
3. 怪癖检测

书写innerText的兼容性代码

//获取标签的innerText(兼容所有浏览器)
function getInnerText(element) {
    if (typeof element.innerText === "string") {
        return element.innerText;
    } else {
        return element.textContent;
    }
}

//设置标签的innerText(兼容所有浏览器)
function setInnerText(element, value) {
    //能力检测
    if (typeof element.innerText === "string") {
        element.innerText = value;
    } else {
        element.textContent = value;
    }
}

2. 节点操作

2.1. 节点的属性

节点分类:

元素节点、文本节点、属性节点、注释节点

节点常用的属性

nodeType: 节点类型:元素节点的nodeType = 1

nodeName: 节点名称

nodeValue: 节点值

 

  //  //      标签节点  属性节点   注释节点  文本节点
  //  //nodeType  1         2               8                3

 

2.2. 节点层次

2.2.1. 孩子节点

//childNodes:获取所有的孩子节点(包括了元素节点和其他很多类型的节点,基本不常用)
//children:获取所有的子元素(用途很广泛)
//firstChild //第一个节点
//firstElementChild //第一个子元素 有兼容性问题 可以封装一个兼容性方法
children[0];
//lastChild //最后一个节点
//lastElementChild //最后一个子元素 有兼容性问题 可以封装一个兼容性方法
children[children.length-1]

 

2.2.2. 兄弟节点

//1. nextSibling:下一个兄弟节点
//2. nextElementSibling:下一个兄弟元素(IE678不兼容)
//3. previousSibling//上一个兄弟节点
//4. previousElementSibling //上一个兄弟元素 有兼容性问题 可以封装一个兼容性方法

 

2.2.3. 父节点

//1. parentNode:父节点  没有兼容性问题

3. 样式操作

标签不仅可以通过class属性操作样式,还可以通过style属性操作样。同样的DOM对象可以通过className操作样式,也可以通过style属性操作样。

 

  //style适用于:单个样式   某一个样式一直在改变
  //class:使用于需要修改多个样式的时候。

 

//1 style属性是一个对象
//2 style这个对象中属性值都是字符串格式
//3 标签中style属性有哪些样式名,在style这个对象中就有对应的属性名。
//4 标签中有一些属性带了-,比如background-color,到了style对象中,变成了驼峰命名法,backgroundColor(因为-在js中不是一个合法的标识符)
//5 DOM中的style属性只能获取和设置行内样式,在类样式中定义的样式通过style获取不到。

 

   //onkeydown:  键盘按下时触发,获取的值是上一次的。
  //onkeyup:键盘弹起时触发,获取的值是对的

 

 

关于body:

//1. document.body  : body比较常用,并且在页面中时唯一的,因此可以使用document.body直接获取。

 

4.a标签的页面跳转

1.阻止a标签跳转(一个#是#top的缩写,跳转到顶部的意思):
<a href="#@">这是一个连接</a>   ==   <a href="##">这是一个连接</a>     ===<a href="###">这是一个连接</a>

2.<a href="javascript:void(0)">这是一个连接</a> 

javascript:void(0)的作用

//1. javascript:是伪协议,表示url的内容通过javascript执行。
//2. void(0)表示不作任何操作,这样会防止链接跳转到其他页面。
//3. 让页面不跳转,JavaScript:void(0)是最通用的方式。

 

 

 

2. BOM

BOM(Browser Object Model):浏览器对象模型,提供了一套操作浏览器功能的工具。

技术分享图片

BOM包含的内容很多,但是很多东西都不太常用,在BOM中需要大家掌握的就一个东西,那就是定时器 。

 

 BOM
    //1. window对象
        //window是老大,全局对象,所有的都是window
        //window可以省略。
        //我们定义的全局变量,声明的函数也是window
      //window.onload :会等待页面加载,图片加载,文件加载完成才会开始执行。
          //使用场景:如果需要获取图片的宽度和高度,就必须使用window.onload
 
      //window.open window.close  模态框
 
    //2. 定时器
        //延时定时器:setTimeout  clearTimeout
        //间歇定时器:setInterval clearInterval
 
      //function: 时间到了,window会自动去调用,只要不清楚,永远调用下去。
      //delay :延迟时间 间隔时间
 
      //返回值:唯一的定时器id  想要清除定时器,依赖这个id
      //setInterval(function, delay)
 
      //clearInterval(timeId);

 

2.1. window对象

  1. window对象是一个全局对象,也可以说是JavaScript中的顶级对象
  2. 像document、alert()、console.log()这些都是window的属性,其实BOM中基本所有的属性和方法都是属性window的
  3. 所有定义在全局作用域中的变量、函数都会变成window对象的属性和方法
  4. window对象下的属性和方法调用的时候可以省略window

重谈 this 关键字

1. this在普通函数中指的是window对象
2. this在方法中,指定的调用这个方法的对象(对象本身)
3. this在构造函数中,this指向新创建的对象
4. this在事件中,指向事件源,即触发事件的对象。

2.1.1. window.onload(掌握)

window.onload事件会在窗体加载完成后执行,通常我们称之为入口函数。

window.onload = function(){
    //里面的代码会在窗体加载完成后执行。
    //窗体加载完成包括文档树的加载、还有图片、文件的加载完成。
}

如果有图片加载,那么代码一定要写到window.onload里面,否则会出现图片没有加载完成,获取到的宽度和高度不对的情况。

浏览器会对页面的加载做优化,在加载图片的时候,图片的引入会延迟。

思考:一个页面能不能写两个window.onload?//会覆盖

2.1.2. window.open与window.close(了解)

window.open() 打开一个窗口

//语法:window.open(url, [name], [features]);
//参数1:需要载入的url地址
//参数2:新窗口的名称
    //_self:在当前窗口打开
    //_blank:在新的窗口打开
//参数3:窗口的属性,指定窗口的大小
//返回值:会返回刚刚创建的那个窗口,用于关闭
//示例:
var newWin = window.open("http://www.baidu.com","_blank", "width=300,height=300");

window.close 关闭窗口

newWin.close();//newWin是刚刚创建的那个窗口
window.close();//把当前窗口给关闭了
案列:var btn1 = document.getElementById("btn1");
  var btn2 = document.getElementById("btn2");
  
  var newWin = null;
  btn1.onclick = function () {
    newWin = window.open("http://web.itcast.cn", "_blank", "width=300,height=300");
  }
 
  btn2.onclick = function () {
    newWin.close();
  }

2.2. 定时器(重点)

2.2.1. 延时定时器

延时定时器可以让代码延迟一段时间之后才执行(定时炸弹)

设置延时定时器

//语法:setTimeOut(callback, time);
//参数1:回调函数,时间到了就会执行。
//参数2:延时的时间
技术分享图片//返回:定时器的id,用于清除
//示例:
var timer = setTimeOut(function(){
    //1秒后将执行的代码。
}, 1000);

清除延时定时器

//语法:clearTimeOut(timerId)
//参数:定时器id
//示例:
clearTimeOut(timer);//清除上面定义的定时器

2.2.2. 间歇定时器

间歇定时器让定时器每隔一段时间就会执行一次,并且会一直执行,直到清除定时器为止.

设置间歇定时器

//语法:var intervalID = setInterval(func, delay);
//参数1:重复执行的函数
//参数2:每次延迟的毫秒数
//返回:定时器的id,用于清除
//示例:
var timer = setInterval(function(){
    //重复执行的代码。
}, 1000);

清除间歇定时器

//语法:clearInterval(intervalID)
//参数:定时器id
//示例:
clearInterval(timer);//清除上面定义的定时器

2.3. location对象

location对象也是window的一个属性,location其实对应的就是浏览器中的地址栏。

2.3.1. 常用属性和方法

location.href:控制地址栏中的地址

location.href = “http://www.baidu.com”;//让页面跳转到百度首页

location.reload():让页面重新加载

location.reload(true);//强制刷新,相当于ctrl+F5
location.reload(false);//刷新,相当于F5

location的其他属性

console.log(window.location.hash);//哈希值 其实就是锚点
console.log(window.location.host);//服务器 服务器名+端口号
console.log(window.location.hostname);//服务器名
console.log(window.location.pathname);//路径名
console.log(window.location.port);//端口
console.log(window.location.protocol);//协议
console.log(window.location.search);//参数

2.4. 其他对象

window.navigator的一些属性可以获取客户端的一些信息

//navigator.userAgent:浏览器版本
//判断联网状态
  console.log(window.navigator.onLine);

history对象表示页面的历史

//后退:
history.back();
history.go(-1);
//前进:
history.forward();
history.go(1);

screen对象

console.log(screen.width);//屏幕的宽度 
console.log(screen.height);//屏幕的高度
console.log(screen.availWidth);//浏览器可占用的宽度
console.log(screen.availHeight);//浏览器可占用的高度
onsubmit 表单提交的时候触发
  
// document不是标签
  //document.bgColor = "red";
  //document.body.style.backgroundColor = "red";

 

 

编辑
 
 
 

onselectstart与onselect

这两个事件看起来很相似,事实上却非常的不同。

onselectstart

        onselectstart几乎可以用于所有对象,其触发时间为目标对象被开始选中时(即选中动作刚开始,尚未实质性被选中)。该事件常使用

于使目标对象“禁止变蓝”,比如在很多地方当用户双击时,一些元素会变成蓝色(选中状态),而当我们要避免这种情况时就可以使用该事

件,使用示例如下: 

  1. <div id="tmp" onselectstart="return false">flondon</div>  

或者

  1. <div id="tmp">flondon</div>  

  2. <script type="text/javascript">  

  3.         document.getElementById("tmp").onselectstart = function(){return false;};  

  4. </script>  

或者

  1. <div id="tmp">flondon</div>  

  2. <script type="text/javascript">  

  3.         if(document.addEventListener)  

  4.         {  

  5.                 document.getElementById("tmp").addEventListener("selectstart", function(){return false;}, false);  

  6.         }  

  7.         else  

  8.         {  

  9.                 document.getElementById("tmp").attachEvent("onselectstart", function(){return false;});  

  10.         }  

  11. </script>  

注:onselectstart事件不被input和textarea标签支持,而onselect事件只被input和textarea支持。

onselect

        onselect是在文本框(input、textarea)内的文本被选中时所触发的事件,其触发时间是在文本被选择以后(即文本已经被选择,已经

显式的表现出来)。该事件只被input和textarea标签支持。

 




以上是关于DOM,BOM的主要内容,如果未能解决你的问题,请参考以下文章

BOM DOM

JavaScript的BOM和DOM有啥区别

DOM和BOM

JavaScript操作Bom对象

DOM和BOM

js Bom Dom