一月已经过半了,得加紧脚步,2018年充满挑战、紧张和刺激,虽然迷茫但会走得精彩。
零、文档对象模型DOM
当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。
一、文档:DOM中的“D”
当创建了一个网页并把它加载到web浏览器中时,DOM便根据这个网页创建出一个文档对象。
二、对象:DOM中的“O”
与某个特定对象相关联的变量被称为这个对象的属性,只能通过某个特定对象去调用的函数被称为这个对象的方法。
1. 用户自定义对象:由程序员自行创建的对象。
2. 内建对象:内建在JavaScript语言里的对象。
3. 宿主对象(host Object):由浏览器提供的对象。
- window对象对应着浏览器窗口本身,这个对象的属性和方法通常统称为BOM(浏览器对象模型)
- document对象主要功能是处理网页内容。
三、模型:DOM中的“M”
文档对象的树状模型,在这个树状模型中,网页中的元素与内容表现为一个个相互连接的节点。
四、节点(node)
DOM中的结点类型包括元素节点、文本节点及属性节点。
1.元素结点
诸如<body>,<p>,<li>
等一系列标签,元素结点组成了文档模型的语义逻辑结构,
- 标签的名字就是元素的名字,
- 元素可以包含其他的的元素,
- <html>
是整个节点树的根元素
2.文本结点
包含在元素节点中的内容部分,如<p>
标签中的内容。
3.属性节点
元素节点的属性,用来对元素做出更具体的描述,所有的属性都被元素包含,如<a>
标签的 href 属性与 title 属性等。
五、获取元素
DOM可通过元素id、标签名、类名来获取元素节点。
1.getElementById
该方法将返回一个与那个有着给定id属性值的元素节点对应的对象,是document对象特有的函数。
document.getElementById(id)
getElementById方法只有一个参数,要获得元素的id属性的值,这个id值必须放在单引号或双引号里:
document.getElementById("purchases");
这个调用将返回一个对象,这个对象对应着document对象里的一个独一无二的元素,该元素的html id属性值为purchases
。
typeof操作符可以告诉我们它的操作数是一个字符串、数值、函数、布尔值还是对象:
alert(typeof document.getElementById("purchases"));
2.getElementsByTagName
文档中的每一个元素都是一个对象,利用DOM提供的方法可以得到任何一个对象,getElemnetByTagName 方法返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素,它的参数是标签的名字:
document.getElementsByTagName("li");
以上调用将返回一个对象数组,可以利用length属性查看这个数组的元素个数:
alert(document.getElementsByTagName("li").length);
这个数组里的每个元素都是一个对象,可通过循环语句和typeof操作符遍历该数组验证:
for (var i=0; i<document.getElementsByTagName("li").length; i++){
alert(typeof document.getElementsByTagName("li")[i]);
}
可以把document.getElementsByTagName("li")
赋值给一个变量:
var items = document.getElementsByTagName("li");
for (var i=0; i<items.length; i++){
alert(typeof items[i]);
}
通配符("*")
:getElementsByTagName允许把一个通配符作为它的参数,为了与乘法操作符有所区别,通配符必须放在引号内,下面代码将返回某份文档里共有多少个元素:
alert(document.getElementsByTagName("*").length);
下面代码返回id属性值是purchases的元素里的子元素个数:
var shopping = document.getElementById("purchases");
var items = shopping.getElementsByTagName("*");
alert(items.length);
3.getElementsByClassName
该方法让我们能通过class属性中的类名来访问元素,下面代码将返回一个数组,包含类名为“sale”的所有元素:
document.getElementsByClassName("sale");
该方法还可以查找带有多个类名的元素,在字符串参数中用空格分隔类名,下面代码将匹配包含类名为important 和sale的所有元素:
alert(document.getElementsByClassName("important sale").length);
下面函数可使getElementsByClassName适应新老浏览器:
// getElementsByClassName函数接收两个参数,node表示DOM树中的搜索起点,classname为要搜索的类名
function getElementsByClassName(node, classname) {
if (node.getElementsByClassName) {
//使用现有方法
return node.getElementsByClassName(classname);
} else {
var results = new Array();
var elems = node.getElementsByTagName("*");
for (var i=0; i<elems.length; i++){
if(elems[i].className.indexOf(classname) != -1){
results[results.length] = elems[i];
}
}
return results;
}
}
如下面代码将获得id属性为purchases的元素下包含class属性“sale”的所有元素:
var shopping = document.getElementById("purchases");
var sales = shopping.getElementsByClassName(shopping, "sale");
alert(items.length);
六、获取和设置属性
得到需要的元素后,getAttribute方法可以获取它的各个属性,setAttribute方法则可以更改属性节点的值。
1.getAttribute
该方法只有一个参数——要查询的属性名字:
object.getAttribute(attribute)
该方法不属于document对象,只能通过元素节点对象调用,以下代码获取每个p元素的title属性:
var paras = document.getElementsByTagName("p");
for (var i=0; i<paras.length; i++) {
alert(paras[i].getAttribute("title"));
}
运行结果:
有几个p元素就弹出几个包含title属性值的对话框,p元素里没有title属性则显示null或空白,可以使用if语句来提高可读性:
var paras = document.getElementsByTagName("p");
for (var i=0; i<paras.length; i++) {
var title_text = paras[i].getAttribute("title");
if (title_text !=null) {
alert(title_text);
}
}
if(something)与if(something !=ull)完全等价:
var paras = document.getElementsByTagName("p");
for (var i=0; i<paras.length; i++) {
var title_text = paras[i].getAttribute("title");
if (title_text) alert(title_text);
}
2.setAttribute
该方法允许对属性节点的值做出修改,也只能用于元素节点:
object.setAttribute(attribute,value)
下面代码把id是purchase的元素的title属性值设置为 a list of goods:
var shopping = document.getElementById("purchases");
shopping.setAttribute("title", "a list of goods");
可以利用getAttribute来证明是否发生变化:
var shopping = document.getElementById("purchases");
alert(shopping.getAttribute("title"));
shopping.setAttribute("title", "a list of goods");
alert(shopping.getAttribute("title"));
setAttribute做出的修改不会反映在文档本身的源代码里,这种表里不一的现象源自DOM的工作模式:
先加载文档的静态内容,再动态刷新,动态刷新不影响文档的静态内容,也就是说DOM对页面内容进行刷新却不需要在浏览器里刷新页面。