七 DOM对象
DOM对象:针对HTML和XML文档的一个API,DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。
1 节点层次:
DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构。节点存在不同的类型,每种类型分别表示文档中不用的信息及标记。每个节点都拥有各自的特性、数据与方法,与其他节点间也存在某种关系。节点间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的树形结构。
文档节点是每个文档的根节点。文档节点只有一个子节点,如<html>元素,称为文档元素。文档元素是文档的最外层元素,文档中的其他元素都包含在文档元素中。每个文档只能有一个文档元素。
每一段标记都可以通过树中的一个节点来表示,HTML元素通过元素节点表示,特性通过特性节点表示,文档类型通过文档类型节点表示,注释通过注释节点表示。。。。
(1) Node类型
DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现。这个Node节点在JavaScript中是通过Node类型实现的。JavaScript中所有节点类型都继承自Node类型,即所有节点类型都共享着相同的基本属性与方法。
每个节点都有nodeType属性,用于表明节点类型,节点类型由在node类型中定义的12个数值常量表示,即1表示元素节点、2表示属性节点、3表示文本节点、4表示CDATASection节点、、、
[1] 节点属性:nodeName、nodeValue
[2] 节点关系:父子关系(childNodes、parentNode)、兄弟关系(previousSibling、nextSibling)
hasChildNodes():判断节点是否含有子节点
ownerDocument,所有节点的最后一个属性,表示任何节点都属于它所在的文档,任何节点都不能同时存在于两个或更多文档中。
每个节点都有一个childNodes属性,保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。其是通过DOM结构动态执行查询的结果。
访问NodeList中节点的方法:方括号形式、item()方法
var value1=someNode.childNodes[0]; var value2=someNode.childNodes.item(1);
[3] 操作节点
appendChild(要添加的节点):用于向chiildNodes列表末尾插入一个节点,返回新插入的节点。
insertBefore(要插入的节点,作为参照位置的节点):向某个固定位置插入节点,返回新插入的节点。
replaceChild(要插入的节点,要替换的节点):替换节点,返回被替换掉的节点(已删除的)。
removeChild(要移除的节点):移除节点,返回移除的节点。
cloneNode(布尔值):用于创建调用这个方法的节点的副本,参数为true表示深复制,复制节点及其整个子节点树;参数为false表示浅复制,仅复制节点本身。
normalize():处理文档中的文本节点。
(2) Document类型
表示文档。在浏览器中,document对象是HTMLDocument的一个实例,表示整个HTML页面。且document对象是window对象的一个属性,可将其作为全局对象进行访问。
[1] 文档子节点:DocumentType、Element、ProcessingInstruction、Commet
documentElement属性,始终指向HTML页面中的<html>元素;childNodes列表访问文档元素。
var body=document.body;//取得对<body>的引用 var html=document.documentElement;//取得对<html>的引用 var doctype=document.doctype;//取得对<!DOCTYPE>的引用
[2] 文档信息:title(浏览器窗口的标题栏)、URL(页面地址栏显示的URL)、domain(页面的域名)、referer(链接到当前页面的那个页面的URL)
Ps:在没有来源页面时,referrer属性可能包含空字符串。所有这些信息存在于请求的http头部。
var URL=document.URL;//取得完整的URL var domain=document.domain;//取得域名 var referrer=document.referrer;//取得来源页面的URL
[3] 查找元素
document.getElementById()、document.getElementsByTagName()、document.getElementsByClassName()、document.getElementsByName()、document.anchors()、document.forms()、document.images()、document.links()、
getElementsByTagName()、getElementsByClassName()返回的是HTMLCollection对象,可以通过方括号或者item()方法来访问HTMLCollection对象的元素。通过方括号可以传入数值或者字符串形式的索引,当传入的是数值型索引时会调用item()方法,而对字符串型索引则会调用namedItem()方法。
var myEle=eles[0]; <=> var myElm=eles.item(0); var myEle=eles["myele"]; <=> var myEle=eles.namedItem("myele");
[4] 文档写入
write()、writeln()、open()、close()、前两个都是接受一个字符串参数,即要写入到输出流中的文本,第一个会原样写入,而第二个则会在字符串末尾添加一个换行符。在页面被加载过程中,可以使用前两个方法向页面中动态添加内容。后面两种方法分别用于打开和关闭网页的输出流。若在页面加载期间使用了前两种方法,则不需要用到后两种方法。
(3) Element类型
用于表现XML或HTML元素,提供了对元素签名、子节点及特性的访问。nodeType值为1。访问元素的标签名,可以选择nodeName或tagName属性。
[1] HTML元素
所有HTML元素都由HTMLElement类型表示,不是直接通过这个类型,也是通过它的子类型来表示。HTML元素中的特性:id、title、className、dir、lang
[2] 操作元素属性方法
getAttribute()、setAttribute()、removeAttribute()
[3] attributes属性
Element类型是使用attributes属性的唯一一个DOM节点类型。Attributes属性中包含一个NamedNodeMap,一个集合。元素的每一个特性都由一个Attr节点表示,每个节点都保存在NamedNMapode对象中。NamedNMapode对象方法:getNamedItem(name)、removeNamedItem(name)、setNamedItem(node)、items(pos)
var id=element.attributes.getNamedItem("id").nodeValue; ó var id=element.attributes["id"].nodeValue;
[4] 创建元素
document.createElement() var div=document.createElement("div"); div.id="myDiv"; div.className="box"; ó var div=document.createElement("<div id="myDiv" class="box"></div> ");
(4) Text类型
文本节点由Text类型表示。nodeType值为3.
可以通过nodeValue或data属性访问Text节点包含的文本。操作节点中文本的方法:appendData(text)、deleteData(offset,count)、insertData(offset,text)、 replaceData(offset,count,text)、splitText(offset)、substringData(offset,count)
属性:nodeValue.length、data.length
[1] 创建文本节点
document.createTextNode()
[2]规范化文本节点
normalize(),若有两个或多个文本节点的父元素调用normalize()方法,则会将所有文本节点合并成一个节点,结果节点的nodeValue值等于合并前每个文本节点的nodeValue值拼接起来的值。
[3]分割文本节点
splitText(),将一个文本节点分成俩那个过文本节点,即按指定位置分割nodeValue值。原来的文本节点将包含从开始到指定位置之前的内容,新文本节点将包含剩下的文本。返回一个新的文本节点。
分割文本节点是从文本节点中提取数据的一种常用DOM解析技术。
(5) Commet类型
(6) CDATASection类型
(7) DocumentFragment类型
(8) Attr类型
2 DOM操作技术:
(1) 动态脚本
使用<script>元素可以向页面中插入JavaScript代码:法1即通过src属性包含外部文件,法2即利用这个元素本身来包含代码。
创建动态脚本方法:法1即插入外部文件,法2即直接插入JavaScript代码
法1: //引入外部文件 <script type="text/javascript" src="client.js"></script> var script=document.createElement("script"); script.type="text/javascript"; script.src="client.js"; document.body.appendChild(script);//在这里之前是不会下载外部文件的 //封装 function loadScript(url){ var script=document.createElement("script"); script.type="text/javascript"; script.src=url; document.body.appendChild(script); } loadScript("client.js"); 法2: //行内方式 <script type="text/javascript"> function sayHi(){ alert("hi"); } </script> var script=document.createElement("script"); script.type="text/javascript"; script.appendChild(document.createTextNode("function sayHi(){ alert('hi');}")); document.body.appendChild(script); //IE var script=document.createElement("script"); script.type="text/javascript"; script.text="function sayHi(){ alert('hi');}"; document.body.appendChild(script); //封装 function loadScriptString(code){ var script=document.createElement("script"); script.type="text/javascript"; try{ script.appendChild(document.createTextNode(code)); }catch(ex){ script.text=code; } document.body.appendChild(script); } loadScriptString("function sayHi(){alert('hi');}"); //这种方式加载的代码会在全局作用域中执行,且当脚本执行后立即执行
(2) 动态样式
法1即<link>元素用于包含来自外部的文件,法2即<style>元素用于指定嵌入的样式。
//法1:外部文件 <link rel="stylesheet" type="text/css" href="style.css"> var link=document.createElement("link"); link.rel="stylesheet"; link.type="text/css"; link.href="style.css"; var head=document.getElementsByTagName("head")[0]; head.appendChild(link); //封装 function loadStyle(url){ var link=document.createElement("link"); link.rel="stylesheet"; link.type="text/css"; link.href="style.css"; var head=document.getElementsByTagName("head")[0]; head.appendChild(link); } loadStyle("style.css"); //法2:嵌入式css <style type="text/css"> body { background-color: red; } </style> var style=document.createElement("style"); style.type="text/css"; try{ style.appendChild(document.createTextNode("body{ background-color:red}")); }catch(ex){ style.styleSheet.cssText="body{background-color:red;}"; } var head=document.getElementsByTagName("head")[0]; head.appendChild(style); //封装 function loadStyleString(css){ var style=document.createElement("style"); style.type="text/css"; try{ style.appendChild(document.createTextNode("body{ background-color:red}")); }catch(ex){ style.styleSheet.cssText="body{background-color:red;}"; } var head=document.getElementsByTagName("head")[0]; head.appendChild(style) loadStyleString("body{background-color:red;}"); } loadStyleString("body{background-color:red;}")
八 JS DOM 基本操作
1 获取节点:
document.getElementById() :(通过元素id获取节点)
document.getElementsByName() :(通过元素name属性获取节点)
document.getElementsByTagName() :(通过元素标签获取节点)
节点指针:
firstChild:(获取父元素的首个节点)、
lastChild:(获取父元素的最后一个子节点)、
childNodes:(获取元素的子节点列表)、
previousSibling:(获取已知节点的前一个节点)、
nextSibling:(获取已知节点的后一个节点)、
parentNode:(获取已知节点的父节点)
2 节点操作
创建节点:
createElement:(创建元素节点)
createAttribute:(创建属性节点)
createTextNode:(创建文本节点)
插入节点:
appendChild:(向节点的子节点列表的末尾添加新的子节点)
insertBefore:(在已知的子节点前插入一个新的子节点)
替换节点:
replaceChild:(将某个子节点替换为另一个)
复制节点:
cloneNode:(创建指定节点的副本)
删除节点:
removeChild:(删除指定的节点)
3 属性操作
获取属性:getAttrribute
设置属性:setAttribute
删除属性:removeAttribute
4 文本操作
insertData(offset,string):(从offset指定的位置插入string)
appendData(string):(将string插入到文本节点的末尾处)
deleteData(offset,count):(从offset起删除count个字符)
replaceData(offset,count,string):(从offset将count个字符用string替代)
splitData(offset):(从offset起将文本节点分成两个节点)
substring(offset,count):(返回由offset起的count个节点)
九 BOM对象(浏览器对象)
BOM:浏览器对象模型,其核心对象为window ,它表示浏览器的一个实例。
1 window对象
Window对象既是通过JavaScript访问浏览器窗口的一个接口, 又是ECMAScript规定的Global对象。è在网页中定义的任何一个对象、变量、函数,都以window作为其Global对象,有权访问parseInt()等方法。
[1] 全局作用域
在全局作用域中声明的变量、函数都会变成window对象的属性和方法。定义全局变量:var age=26; 在window对象上定义属性:window.color=”red”; 二者区别:全局变量不能通过delete操作符删除,而window对象上定义的属性可通过delete删除。因为通过var添加的window属性有一个名为[[confugurable]]的特性,其值被设置为false,这样定义的属性不能通过delete操作符删除。
Ps:尝试访问未声明的变量会抛出错误,但通过查询window对象,可知道某个可能未声明的变量是否存在。
var newVal=oldVal;//这里会抛出错误,因为oldVal没有定义 var newValue=window.oldValue;//这里不会抛出错误,这是数学查询,undefined
[2] 窗口关系及框架
如页面中包含框架,则每个框架都会拥有自己的window对象,且保存在frames集合中。在frames集合中,可通过数值索引或框架名称来访问相应的window对象。每个window对象都有一个name属性,其包含框架的名称。<frameset></frameset>与<body></body>不能同时出现。
[3] 窗口位置
用来确定与修改window对象位置的属性与方法有很多:
(IE、Safari、Opera、chrome):screenLeft、screenTop表示窗口相对于屏幕左边与上边的位置。
(Firefox、Safari、Chrome):screenX、screenY表示窗口相对于屏幕左边与上边的位置。
var leftPos=(typeof window.screenLeft == "number") ? window.screenLeft : window.screenX; var topPos=(typeof window.screenTop == "number" ) ? window.screenTop : window.screenY ;
ps:(1)IE、Opera中,screenLeft、screenTop中保存的是从屏幕左边和上边到由window对象表示的页面可见区域的距离。即window对象是最外层对象,且浏览器窗口紧贴屏幕最上端:y轴坐标为0,那screenTop的值是位于页面可见区域上方的浏览器工具栏的像素高度。(2)chrome、firefox、Safari中,screenY或screenX中保存的是整个浏览器窗口中相对于屏幕的坐标值,即在窗口的y轴坐标为0时返回0。
moveTo(x,y)、moveBy(x,y)将窗口位置移动到一个新位置,moveTo(x,y)中x,y是新位置的坐标,moveBy(x,y)中x,y是水平与垂直方向上移动的像素数。
[4] 窗口大小
innerWidth、innerHeight、outerWidth、outerHeight
IE9+、firefox、Safari:outerWidth、outerHeight返回浏览器窗口本身的尺寸。
Opera:outerWidth、outerHeight表示页面视图容器的大小,而innerWidth、innerHeight则表示该容器中页面视图区的大小。
Chrome:outerWidth、outerHeight、innerWidth、innerHeight返回相同的值,即视口大小而非浏览器窗口大小。
IE、firefox、Safari、chrome:document.documentElement.clientWidth与document.documentElement.clientHeight中保存了页面视口的信息。IE6中这些属性在标准模式下才有效;混杂模式则必须通过document.body.clientWidth与document.body.clientHeight,取得相同信息。混杂模式下的chrome,两种方式都可以取得视口大小。
[5] 导航和打开窗口
window.open(要加载的URL,窗口目标,一个特性字符串,一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值)可以导航到一个特定的URL,也可以打开一个新的浏览器窗口。通常只需传递第一个参数,最后一个参数只在不打开新窗口的情况下使用。二参可以为_self、_parent、_top、_blank
close()关闭新打开的窗口
[6] 间歇调用与超时调用
JavaScript,单线程语言,但允许通过设置超时值(setTimeout())与间歇时间(setInterval())来调度代码在特定时刻执行。其中,setTimeout()在指定的时间过后执行代码。setInterval()每隔一定时间执行一次代码。setTimeout()第一个参数,可以是可执行的字符串,也可以是函数(推荐);第二个参数表示等待多长时间的毫秒数,但经过该时间后,代码不一定能执行。
JavaScript是单线程的解释器,一段时间内只能执行一段代码。为了控制要执行的代码,就有一个JavaScript任务列。这些任务会按照它们添加到任务队列里的顺序执行。setTimeout的第二个参数告诉JavaScript再过多长时间把当前任务加到队列中,若队列是空的,则代码会立即执行,若队列非空,则需等待前面任务执行完了再执行。
调用setTimeout后,会返回一个数值ID,表示超时调用。该id是计划执行代码的唯一标识符,可以通过它实现取消超时调用。要取消尚未执行的超时调用计划,可以调用clearTimeout()方法将相应的超时调用ID作为参数传递给它。
var timeoutId=setTimeout(function(){ alert("hi"); },1000); clearTimeout(timeoutId);
ps:只要在指定的实际尚未过去之前调用clearTimeout()都可以完全取消超时调用。
setInterval(),按照指定的时间间隔重复执行代码,直至间歇调用被取消或页面被卸载。参数及返回值与setTimeout类似。
var num=0; var max=10; var intervalId=null; function incrementNumber(){ num++; if(num==max){ clearInterval(intervalId); alert("done"); } } intervalId=setInterval(incrementNumber,500);
[7] 系统对话框
alert()、confirm()、prompt() =>用于调用系统对话框向用户显示消息
alert():接收一个字符串并将其显示给用户,其执行结果包含一个指定的文本与一个OK按钮。
confirm():同alert(),区别在于其执行结果包含一个指定文本、一个OK按钮、一个cancle按钮。
prompt():提示框,用于提示永辉输入一些文本,提示框除了显示ok、cancle外,还会显示一个文本输入域。其接收两个参数,要显示给用户的文本提示及文本输入域的默认值。
alert("hello"); if(confirm("are you sure?")){ alert("I'm so glad"); }else{ alert("so bad"); } var res=prompt("what is your name?"," "); if(res!==null){ alert("welcome"+res); }
2 location对象
location,提供与当前窗口加载的文档有关的信息,还提供了一些导航功能。其既是window对象属性,也是document对象属性。即window.location和document.location引用的是同一个对象。location对象的用途不止表现在保存着当前文档的信息,还表现在它将URL解析为独立的片段,开发人员可通过不同的属性访问这些片段。
location对象的属性:
location.hash:返回URL中的hash(#号跟0或多个字符),如果URL中不包含散列,则返回空字符串。
location.host:返回服务器名称和端口号。
location.hostname:返回不带端口号的服务器名称
location.href:返回当前加载页面的完整URL。(同location对象toString方法)
location.pathname:返回URL中的目录和文件名
location.port:返回URL中指定的端口号
location.protocol:返回页面使用的协议
location.search:返回URL的查询字符串,该字符串以?开头
[1] 查询字符串参数
function getQueryStringArgs(){ //取得字符串,并去掉开头的问号 var qs=(location.search.length > 0 ?location.search.substring(1) : " "), args={ }, //保存数据的对象 items=qs.length ? qs.split("&") : [], //取得每一项 item=null, name=null, value=null, i= 0, len=items.length; for(i = 0;i < len; i++){ //逐个将每一项添加到args对象中 item=items[i].split(" = "); name=decodeURIComponent(item[0]); value=decodeURIComponent(item[1]); if(name.length){ args[name]=value; } } return args; }
[2] 位置操作
使用location对象可以通过很多方式来改变浏览器的位置,最常用的是使用assign()方法并为其传递一个URL。
location.assign("http://www.baidu.com"); window.location="http://www.baidu.com"; location.href="http://www.baidu.com"; //修改location对象的其他属性也可以改变当前加载的页面 location.hash="#section1"; //修改后为:http://www.baidu.com/#section1 location.search="?q=javascript"; //修改后:http://www.baidu.com/q=javascript location.hostname="www.yahoo.com";//修改后为:http://www. yahoo.com/ location.pathname="mydir";//修改后为:http://www. yahoo.com/ mydir/ location.port=8080;// 修改后为:http://www. yahoo.com:8080/
ps:通过上述任何一种方式修改URL后,浏览器的历史记录中就会生成一条新记录,因此当用户通过单击后退按钮都会导航到前一个页面。可以利用replace(要导航到的URL)方法来禁
用这种行为。
reload():重新加载当前显示的页面。若该方法无参数则页面以最有效的方式重新加载,即:若页面自上次请求以来没有改变过,则页面之间从浏览器缓存中重新加载;若强制从服务
器重新加载则需传递参数true
3 navigator对象
[1] 检测插件
检测浏览器中是否安装了特定的插件
[2] 注册处理程序
registerContentHandler()、registerProtocolHandler()都可以让一个站点指明它可以处理特定类型的信息。
registerContentHandler(要处理的MIME类型,可以处理该MIME类型的页面的URL,应用程序的名称)
registerProtocolHandler(要处理的协议,处理该协议的页面的URL,应用程序的名称)
4 screen对象
用来表明客户端的能力,其中包括浏览器窗口外部的显示器的信息,如像素宽度,也可用来调整浏览器窗口大小
5 history对象
history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。
go():可以在用户的历史记录中任意跳转,参数为负表示向后跳转,参数为正表示向前跳转。参数为字符串时,浏览器会跳转到历史记录中包含该字符串的第一个位置,后退或前进,具体看哪个位置更近。
history.go(-1); //后退一页 history.go(1);//前进一页
back():模仿浏览器后退按钮
forward():模仿浏览器前进按钮
history对象的length属性,保存着历史记录的数量。对于加载到窗口、标签页
参考资料:
《JavaScript高级程序设计》、《JavaScript权威指南》