简述
本系列将持续更新Javascript基础部分的知识,谁都想掌握高端大气的技术,但是我觉得没有一个扎实的基础,我认为一切高阶技术对我来讲都是过眼云烟,要成为一名及格的前端工程师,必须把基础打扎实了。我也想展翅高飞,但前提我必须练就一双会飞的翅膀。
JavaScript(DOM)部分
了解 Javascript & DOM
DOM全称:文档对象模型DOM(Document Object Model)是定义访问和处理HTML文档的标准方法。DOM 将HTML文档呈现为带有元素、属性和文本的树结构(节点树)。
HTML文档可以说由节点构成的集合,DOM 节点有:
元素节点:html、body、p标签等都是元素节点(标签)。
文本节点:向用户展示的内容,如<li>...</li>中的文本。
属性节点:元素属性,如
<a href='http://edu.jobui.com'/>
标签所带的超链接属性。
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
整个文档是一个文档节点
每个 HTML 元素是元素节点
HTML 元素内的文本是文本节点
每个 HTML 属性是属性节点
注释是注释节点
虽然还是有点乱,但是我是这么理解DOM的:Javascript与Html文档元素的进行业务逻辑交互。
汤姆大叔是这么解释的:DOM(Document Object Model,文档对象模型)是一个通过和JavaScript进行内容交互的API。
window对象作为全局对象,也就是说你可以通过window来访问全局对象。
DOM为web文档创建带有层级的结果,这些层级是通过node节点组成,这里有几种DOM node类型,最重要的是Element, Text, Document。
每个引擎对DOM标准的实现有一些轻微的不同。例如,Firefox浏览器使用的Gecko引擎有着很好的实现(尽管没有完全遵守W3C规范),但IE浏览器使用的Trident引擎的实现却不完整而且还有bug,给开发人言带来了很多问题。
getElementsById()方法
通过节点的ID,可以准确获得需要的元素,是比较简单快捷的方法。语法:
<script type="text/javascript" charset="utf-8">var sID = document.getElementsById (sID);</script>
说明:根据指定的 id 属性值得到对象。返回 id 属性值等于 sID 的第一个对象的引用。假如对应的为一组对象,则返回该组对象中的第一个。 如果无符合条件的对象,则返回 null 。
注意:
document.getElementById()得到的是一个对象;
用alert显示得到的是object,而不是具体的值;
它有`value`和`length`等属性;
加上`.value`得到的才是具体的值。
注意:在 IE 中 getElementById()
只抓得到第一個出現的ID的事务。
getElementsByName()方法
返回带有指定名称的节点对象的集合。语法:
<script type="text/javascript" charset="utf-8">var nameArr = document.getElementsByName(name);</script>
与
getElementById()
方法不同的是,通过元素的name
属性查询元素,而不是通过id
属性。
注:
因为文档中的
name
属性可能不唯一,所有getElementsByName()
方法返回的是元素的数组,而不是一个元素。和数组类似也有
length
属性,可以和访问数组一样的方法来访问,从0开始。
getElementsByTagName()方法
返回带有指定标签名的节点对象的集合。返回元素的顺序是它们在文档中的顺序。 语法:
<script type="text/javascript" charset="utf-8">var tagnameArr = getElementsByTagName(Tagname);</script>
说明:
Tagname是标签的名称,如p、a、img等标签名。
和数组类似也有length属性,可以和访问数组一样的方法来访问,所以从0开始。
区别 getElementByID() , getElementsByName() , getElementsByTagName()
以人来举例来说:人有能标识身份的身份证,有姓名,有类别(大人、小孩、老人)等。
ID 是一个人的身份证号码,是唯一的。所以通过getElementById()获取的是指定的一个人。
Name 是他的名字,可以重复。所以通过getElementsByName()获取名字相同的人集合。
TagName可看似某类,getElementsByTagName()获取相同类的人集合。如获取小孩这类人:getElementsByTagName("小孩")。
下面有一个html代码片段:
<input type="checkbox" name="hobby" id="hobby1"> 音乐<input type="checkbox" name="hobby" id="hobby2"> 登山<input type="checkbox" name="hobby" id="hobby3"> 游泳<input type="checkbox" name="hobby" id="hobby4"> 阅读<input type="checkbox" name="hobby" id="hobby5"> 打球<input type="checkbox" name="hobby" id="hobby6"> 跑步 <input type="button" value = "全选" id="button1"><input type="button" value = "全不选" id="button1">
如果:
我们使用
document.getElementsByTagName("input")
,结果为获取所有标签为input的元素,共8个。我们使用
document.getElementsByName("hobby")
,结果为获取name
属性为hobby的元素,共6个。我们使用
document.getElementById("hobby6")
,结果为获取id
属性为hobby6的元素,只有一个。
getAttribute()方法
通过元素节点的属性名称获取属性的值。语法:
<script type="text/javascript" charset="utf-8">var name = elementNode.getAttribute(name);</script>
说明:
elementNode:使用getElementById()、getElementsByTagName()等方法,获取到的元素节点。
name:要想查询的元素节点的属性名字。
上图:实现获取h1标签的属性值。
运行结果:
h1标签的ID :alink
h1标签的title :getAttribute()获取标签的属值
getAttribute()方法是一个函数。它只有一个参数——你打算查询的属性的名字。
不过,getAttribute()方法不能通过document对象调用,它只能通过一个元素节点对象调用。
setAttribute()方法
setAttribute() 方法增加一个指定名称和值的新属性,或者把一个现有的属性设定为指定的值。语法:
<script type="text/javascript" charset="utf-8">elementNode.setAttribute(name,value);</script>
说明:
1.name: 要设置的属性名。
2.value: 要设置的属性值。
注意:
1.把指定的属性设置为指定的值。如果不存在具有指定名称的属性,该方法将创建一个新属性。
2.类似于getAttribute()方法,setAttribute()方法只能通过元素节点对象调用的函数。
setAttribute()方法允许我们对属性节点的值做出修改,这是一个很重要的特质。
通过setAttribute()方法对文档做出的修改,将使得文档在浏览器窗口里的显示效果和/或行为动作发生相应的变化,但我们在通过浏览器的view source(查看源代码)选项去查看文档的源代码时看到的仍将是原来的属性值。
也就是说,setAttribute()方法做出的修改不会反映在文档本身的源代码里。
这种“表里不一”的现象源自DOM的工作模式:先加载文档的静态内容、再以动态方式对它们进行刷新,动态刷新不影响文档的静态内容。这正是DOM的真正威力和诱人之处:对页面内容的刷新不需要最终用户在他们的浏览器里执行页面刷新操作就可以实现。
节点属性
在文档对象模型 (DOM) 中,每个节点都是一个对象。
DOM 节点有三个重要的属性 :
nodeName : 节点的名称
nodeValue :节点的值
nodeType :节点的类型
1、nodeName 属性: 节点的名称,是只读的。
元素节点的 nodeName 与标签名相同
属性节点的 nodeName 是属性的名称
文本节点的 nodeName 永远是 #text
文档节点的 nodeName 永远是 #document
2、nodeValue 属性:节点的值
元素节点的 nodeValue 是 undefined 或 null
文本节点的 nodeValue 是文本自身
属性节点的 nodeValue 是属性的值
3、nodeType 属性: 节点的类型,是只读的。以下常用的几种结点类型:
元素类型:节点类型
元素:1
属性:2
文本:3
注释:8
文档:9
访问子结点(childNodes)
访问选定元素节点下的所有子节点的列表,返回的值可以看作是一个数组,他具有length属性。语法:
<script type="text/javascript" charset="utf-8">var nodeName = elementNode.childNodes;</script>
结合案例说一下:
运行结果:
IE:UL子节点个数:3节点类型:1
其它浏览器:UL子节点个数:7节点类型:3
注意:
IE全系列、firefox、chrome、opera、safari兼容问题。
节点之间的空白符,在firefox、chrome、opera、safari浏览器是文本节点,所以IE是3,其它浏览器是7。
所以它就被看成了:
如果把代码改成这样:
<ul><li>javascript</li><li>jQuery</li><li>PHP</li></ul>
运行结果:(IE和其它浏览器结果是一样的)
UL子节点个数:3
节点类型:1
访问父节点(parentNode)
这个跟上面那个子节点都比较少用到,简单说一下就可以了,获取指定节点的父节点
语法:
<script type="text/javascript" charset="utf-8">var nodeName = elementNode.parentNode;</script>
注意:父节点只能有一个。
获取 P 节点的父节点的案例:
<div id="text"><p id="con"> parentNode 获取指点节点的父节点</p></div> <script type="text/javascript">var mynode= document.getElementById("con");document.write(mynode.parentNode.nodeName);</script>
运行结果:
parentNode 获取指点节点的父节点
DIV
访问祖节点:
<script type="text/javascript" charset="utf-8">var nodeName = elementNode.parentNode.parentNode;</script>
看看下面的代码:
<div id="text"> <p>parentNode <span id="con"> 获取指点节点的父节点</span></p></div> <script type="text/javascript">var mynode= document.getElementById("con");document.write(mynode.parentNode.parentNode.nodeName);</script>
运行结果:
parentNode获取指点节点的父节点
DIV
注意: 浏览器兼容问题,chrome、firefox等浏览器标签之间的空白也算是一个文本节点。
注:其实还有兄弟节点
nodeObject.nextSibling
,这里就不多说了,确实很少用到。
浏览器窗口可视区域大小
讲述获得浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)的方法
1、对于IE9+、Chrome、Firefox、Opera 以及 Safari:
window.innerHeight - 浏览器窗口的内部高度
window.innerWidth - 浏览器窗口的内部宽度
2、对于 IE 8、7、6、5:
document.documentElement.clientHeight表示HTML文档所在窗口的当前高度。
document.documentElement.clientWidth表示HTML文档所在窗口的当前宽度。
或者Document对象的body属性对应HTML文档的<body>标签
document.body.clientHeight
document.body.clientWidth
3、在不同浏览器都实用的 JavaScript 方案:
var w= document.documentElement.clientWidth || document.body.clientWidth;var h= document.documentElement.clientHeight || document.body.clientHeight;
网页卷去的距离与偏移量
先看一张图:
说明:
scrollLeft : 设置或获取位于给定对象左边界与窗口中目前可见内容的最左端之间的距离 ,即左边灰色的内容。
scrollTop : 设置或获取位于对象最顶端与窗口中可见内容的最顶端之间的距离 ,即上边灰色的内容。
offsetLeft : 获取指定对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置 。
offsetTop : 获取指定对象相对于版面或由 offsetParent 属性指定的父坐标的计算顶端位置 。
注意:
区分大小写
offsetParent:布局中设置postion属性(Relative、Absolute、fixed)的父容器,从最近的父节点开始,一层层向上找,直到HTML的body。
总结
最后附上一份福利吧:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>选项卡</title><style type="text/css">/* CSS样式制作 */ *{padding:0px;margin:0px;font:12px;normal "microsoft yahei";}#tabs{width:290px;padding:5px;height:150px;margin:30px;}#tabs ul{list-style:none;display:block;height:30px;line-height:30px;border-bottom:2px;saddlebrown solid;}#tabs ul li{background:#fff;cursor:pointer;float:left;list-style:none;height:28px;line-height:28px;margin:0px 3px;border:1px solid #aaa;}#tabs ul li.on{border:2px solid saddlebrown;border-bottom:2px solid #fff;}#tabs div{height:120px; line-height:25px;border:1px solid #336699;border-top:node;padding:5px;}.hide{display:none;} </style><script type="text/javascript"> // JS实现选项卡切换window.onload = function(){var oTab = document.getElementById("tabs");var oUl = oTab.getElementsByTagName("ul")[0];var oLis = oUl.getElementsByTagName("li");var oDivs = oTab.getElementsByTagName("div");for(var i=0, len=oLis.length; i<len;i++){oLis[i].index = i;oLis[i].onclick = function(){for(var n=0; n<len; n++){oLis[n].className = "";oDivs[n].className = "hide";}this.className = "on";oDivs[this.index].className = "";}};} </script></head><body><!-- HTML页面布局 --><div id="tabs"><ul><li>房产</li><li>家居</li><li>二手房</li></ul><div>275万购昌平邻铁三居 总价20万买一居<br>200万内购五环三居 140万安家东三环<br>北京首现零首付楼盘 53万购东5环50平<br>京楼盘直降5000 中信府 公园楼王现房<br></div><div>40平出租屋大改造 美少女的混搭小窝<br>经典清新简欧爱家 90平老房焕发新生<br>新中式的酷色温情 66平撞色活泼家居<br>瓷砖就像选好老婆 卫生间烟道的设计<br></div><div>通州豪华3居260万 二环稀缺2居250w甩<br>西3环通透2居290万 130万2居限量抢购<br>黄城根小学学区仅260万 121平70万抛!<br>独家别墅280万 苏州桥2居优惠价248万<br></div></div></body></html>
代码说明:这段代码能实现选项卡切换的效果
1、HTML页面布局
选项卡标题使用ul..li
选项卡内容使用div
2、CSS样式制作
整个选项卡的样式设置
选项卡标题的样式设置
选项卡内容的样式设置
一开始只显示一个选项卡内容,其它选项卡内容隐藏。
3、JS实现选项卡切换
获取选项卡标题和选项卡内容
选项卡内容多个,需要循环遍历来操作,得知哪个选项卡和哪个选项内容匹配
通过改变DOM的css类名称,当前点击的选项卡显示,其它隐藏。