梗概
这节课程是铺垫的课,等下节课程再详细讲,从基础开始一点点剖析dom,主要通过这节课有一个最基本的认知和了解
1.对象概念
js中的所有对象
DOM -> Document Object Model 文档对象模型
DOM 对象 -> 宿主对象
宿主对象:寄宿到别人旅馆,用旅馆提供的洗漱用具,吃旅馆提供的饭菜,而不是用自己的,是别人提供的。浏览器提供给js的方法,而不是ecma提供的了。js在每个浏览器启动时需要这个宿主,也就是浏览器提供一系列跟dom相关的方法。
3种对象 : ECMAScript
1.本地对象:Native Object
Object Function Array String Number Boolean Error EvalError SyntaxError RangeError ReferenceError TypeError URIError
Data RegExp
要背的
2.内置对象 Built-in Object
Global Math
global在js中并没有这个对象,它代表了一类对象,是一类对象的全称,但没有这个关键字。
ECMA -> isNaN() parseInt() Number decodeURI encodeURI
以下方法都是global下的方法
global下的属性
Infinity NaN undefined
本地对象和内置对象都是ES(ECMA)的内部对象
3.宿主对象 Host Object
执行JS脚本的环境提供的对象,浏览器对象,兼容性问题
解释
js代码在哪里执行,在浏览器中执行,所以又称浏览器对象,浏览器有很多,不同的浏览器提供不同的宿主对象的方法,也就是说浏览器提供的实现相同功能的方法,他们有可能不同,可能方法名称不同,功能一样的方法,在不同的浏览器中可能叫不同的名字,方法名命名不同,可能方法实现不同。即便是相同,他们实现的方法也有可能不一样。所以浏览器与浏览器之间执行js脚本的时候,在用到宿主对象的时候,用到宿主对象里面的方法的时候,就有可能造成兼容性问题。
命名规范:即使规范的不同的库,它们命名规范,但可能名称会有区别,没有绝对正确的命名,有正确的命名规范,这个不同的公司,有不同的内部文档,可能稍有差别,但意思都是一样的,好的规范可能稍有差别,但意思一样,不可能每一句话、每个变量命名都一样。不要过于纠结命名规范,等之后写多了就熟了,就会命名了。关注点放在思路上面,专注在思路上面。
所以在写dom、bom时要注意兼容性
为什么不要提前去学一些东西,因为我们写的那些东西都不是企业用的东西,都不适合企业用。可能面试时,面试官的问题,你给出的代码,有99.99%的可能并不是面试官所要的、想要的。
兼容性封装
因为bom、dom存在兼容性问题,所以我们写dom、bom代码时都会写很多很多关于兼容性的代码,任何把它们封装成一个又一个的工具函数,或者工具方法,之后直接调用,而不是写在外面直接来用的,放在一个utils的文件中。
dom、bom不算特别难,比ecma轻松些,但兼容性问题有点绕
浏览器对象windows(BOM)和document(DOM)-> w3c
浏览器对象有windows(BOM),bom在windows对象下,是window对象,document(DOM),dom在document对象下,是document对象
dom其实是Bom下面的内容,document对象是windows,只不过把他们拆分了出来,为什么拆分?
因为w3c对dom这一块是有详细的规范,而bom没有,为什么没有?因为浏览器与浏览器之间运行js的方式,与实现某一些方法的方式是不同的,所以它们之间存在不同的Bom的对象的方法,所以没有办法给标准,就不给标准了,开发者就做兼容性。
doucument其实是存放在window对象下面的,这个dom课与之前所学的不一样,这里要剖析的是原理,用法说实话太简单了,但是原理就不一定能那么容易把它弄懂,做好心理准备
宿主对象其实就是浏览器对象,因为js脚本是寄放在浏览器上边的运行的,宿主对象本身就是浏览器提供的,浏览器是宿主,浏览器对象就是宿主对象。
模型是什么?
模型指的是一个封装好了的有结构的一套方法,能够处理我们相对应的这些事,比如dom就是操作html、xml的,dom这个模型,我建立了一套完整的方法集合,这个方法集合就是一套模型,我们在使用一些框架时也是,问什么叫模型层,模型层是什么?模型层就是提供了一套完整的方法去操作xxx的,比如操作数据,后端模型层。
制定了一套规范,一套方法的集合,有序的排列起来,让开发者可以从中找到相适应的方法去解决某一些问题
DOM不同的浏览器不同
DOM用处
DOM:通过浏览器对象提供的这一套方法表示或者操作HTML和xml,dom是让开发者用js操作html和xml的,里面封装、提供了操作html的方法,比如要获取标签、获取标签里面的内容
之前学的东西,ecma都操作不了dom,操作html、xml需要提供方法,提供模型,是浏览器对象提供的,浏览器之间存在纷争,比如实现一个获取html标签,不同的浏览器可能代码不同,这是因为浏览器厂商之间存在纷争,我就不和你一样,不想和你一样,都想自己的东西成为标准,自己造的轮子成为标准,不会去刻意兼容别的浏览器的代码,故意弄得和其它浏览器不兼容,区别大。
现在想要统一dom很难,因为提供方依然是浏览器厂商。
DOM操作:xml、html,不能操作css。
xml
<person><name>张三</name><sex>男</sex><age>18</age></person>
xml是可以自定义标签的,html提供了一套标签的规范,用的所有标签,都是html提供给的,是html内部自己定义好的,不是自己定义的。
历史演变
XML->XHTML->HTML
从xml演变成xhtml,xhtml是一个过渡,是xml演变成html的过渡时期,html时期标签再像xml一样标签可以自定义,现在自己内部定义了可以被浏览器直接解析的一套,比如h1、h2、li,它们从浏览器中解析有默认的样式,有一定的样式,这是html规定下来的,而xml没有,没有这些规定好的样式等。
xml为html奠定了一个基础的规范,之后逐步去掉了xml的一些劣势,保留了一些优势,再增加一些好的东西,慢慢演变,成为了现在所使用的html。
html不可以自定义标签,自定义标签就没有规范了,没有规范,想怎么写就怎么写,就没有样式
<person><name>张三</name><sex>男</sex><age>18</age></person>XML -> XHML ->HTML<h1>李四</h1><h2>男</h2><h3>18</h3>

h1、h2有一定的样式,独占一行,字体文字不一样,而xml的文字,与写在html中的文字XML -> XHML ->HTML样式是一样的。
<person><name>张三</name><sex>男</sex><age>18</age></person><person><name>李四</name><sex>女人</sex><age>23</age></person>XML -> XHML ->HTML<script type="text/javascript">var person = document.getElementsByTagName('person')[0];console.log(person);</script>

获取结果是类数组,是一个集合
<person><name>张三</name><sex>男</sex><age>18</age></person><person><name>李四</name><sex>女人</sex><age>23</age></person>XML -> XHML ->HTML<script type="text/javascript">//类数组加[数字]获取var person = document.getElementsByTagName('person')[0];console.log(person);</script>

标签和元素
person单个是标签
<person></person>
这个是元素,多个标签组成元素,标签及标签内部的文本加到一起,叫做一个元素
<person><name>张三</name><sex>男</sex><age>18</age></person>
这是一个标签
<name></name>
如果算上张三,它就是一个元素了
<name>张三</name>
getElementsByTagName:得到元素通过标签,通过标签得到元素。get得到Elements元素By通过TagName标签,得到打印的是元素
<person><username>张三</username><sex>男</sex><age>18</age></person><script type="text/javascript">var person = document.getElementsByTagName('person')[0];// var username=person.getElementsByTagName('username');//HTMLCollection[username]var username=person.getElementsByTagName('username')[0];//[object HTMLCollection]console.log(person);console.log(username);</script>

需改成username,如果用name会出现错误
<person><name>张三</name><sex>男</sex><age>18</age></person><script type="text/javascript">var person = document.getElementsByTagName('person')[0];// var name=person.getElementsByTagName('name');//[object HTMLUnknownElement]var name = person.getElementsByTagName('name')[0];//[object HTMLUnknownElement]// console.log(person);console.log(name);</script>
<form id="myFrom"><input type="text" id="id"></form><script !src="">console.log(document.getElementsByTagName('form')[0]);</script>

<form id="myFrom"><input type="text" id="id"></form><script !src="">var form=document.getElementsByTagName('form')[0];console.log(form.id);//<input type="text" id="id"></script>

复制元素,可以复制元素文本
打印form.id,打印的不是myFrom,而是
id是一个属性,会覆盖掉,input的id把form的id覆盖掉了,子元素把父元素id覆盖掉了,因为form有id的属性,input也有id的属性,如果在input上设置一个id的属性,这个id会向上传递,把form的id覆盖掉
<form id="myFrom"><input type="text" id="id"></form><script !src="">var form=document.getElementsByTagName('form');console.log(form);</script>

<form id="myFrom"><input type="text" id="myInput"></form><script !src="">var form=document.getElementsByTagName('form')[0];console.log(form.myInput);//<input type="text" id="myInput"></script>

名字改成myInput也一样,结果一样
避免使用:有些东西要避免使用,像name、id,这一些变量名、标签名这一类东西,尽可能去避免,因为js中有内置的属性,有id、name的,保不准哪个地方就有冲突,尽可能的回避这一些属性。尽量避免可能会起冲突的命名方式。
dom操作css
<style>div {width: 200px;height: 200px;background-color: red;}</style><div></div><script !src="">var div = document.getElementsByTagName('div')[0];console.log(div);/*小驼峰,第一个单词首字母小写,第二个单词首字母大写,大驼峰,首字母大写*/div.style.backgroundColor='green'</script>


它操作的是每一个元素里面有一个style属性,给这个属性增加了内联样式,就是给style里面的内容赋值,这里面给style属性的backgroundColor属性赋值。给style对象里的backgroundColor属性。属性也可以是对象,属性也可以是引用值,也可以是原始值。
因为内联样式的优先级最高,内联样式把css覆盖了。
jquery也一样
<style>div {width: 200px;height: 200px;background-color: red;}</style><div></div><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script><script !src="">var div = $('div');console.log(div);div.css('background-color', 'green');</script>

获取元素
<style>div {width: 200px;height: 200px;background-color: red;}</style><div id="box"></div><div id="box2"></div><script !src="">var box = document.getElementById('box');//<div id="box"></div>console.log(box);var boxes=document.getElementsByTagName('div');console.log(boxes);//HTMLCollection(2)[div#box, div#box2, box: div#box, box2: div#box2]</script>
<style>/* #box{color: red;}*/div{color: green;}</style><div id="box">123</div><div id="box2">123</div><script !src="">var box = document.getElementById('box');//<div id="box"></div>console.log(box);var boxes=document.getElementsByTagName('div');console.log(boxes);//HTMLCollection(2)[div#box, div#box2, box: div#box, box2: div#box2]</script>

getElementsByTagName标签选择器很像,都是选择多个标签,选择一组,不管是有一个两个还是三个,返回的都是一个类数组。就算只有一个div也是一个数组。
getElementById因为一个html中,每个元素的id都不能重名,所以id是惟一的,通过id获取的东西都是唯一的,确定的,确定个数确定哪个,结果确定。id一样会报错。
getElementsByTagName:比如div是不唯一的,有多个,可以这样一个标签,可能有多个,可能只有一个,不能确定明确的结果,所以给返回的是一个类数组,如果想打印,就给它后面加上相应的番号,下标。
div{color: green;}
通过class依然返回一个类数组
<style>/* #box{color: red;}*/div{color: green;}</style><div id="box" class="box">123</div><div id="box2" class="box">123</div><script !src="">var boxes=document.getElementsByClassName('box');console.log(boxes);//HTMLCollection[div#box.box, div#box2.box, box: div#box.box, box2: div#box2.box]</script>

不用关注box、box2,看0、1这是得到的元素
点击事件
<style>/* #box{color: red;}*/div {color: green;}</style><div>123</div><div>234</div><div>345</div><script !src="">var boxes = document.getElementsByTagName('div');/* box.onclick=function() {console.log(1);}*/for (var i = 0; i < boxes.length; i++) {boxes[i].onclick = function () {console.log(this.innerText);}}</script>
循环添加点击事件
事件监听器
3.幻灯片展示demo
js认为操作的一部分html叫做dom结构
搭建dom结构,就是写一下html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="./index.css"></head><body><div class="slider-wrap"><div class="slider"><ul class="slider-list"><li class="slider-item active"><a href=""></a><img src="./1.jpg" alt=""></li><li class="slider-item"><a href=""></a><img src="./2.jpg" alt=""></li><li class="slider-item"><a href=""></a><img src="./3.jpg" alt=""></li><li class="slider-item"><a href=""></a><img src="./4.jpg" alt=""></li><li class="slider-item"><a href=""></a><img src="./5.jpg" alt=""></li><li class="slider-item"><a href=""></a><img src="./6.jpg" alt=""></li></ul></div><div class="thumbs"><ul class="thumbs-list"><li class="thumb-item cur"><a href="javascript:;"><img src="./1.jpg" alt=""></a></li><li class="thumb-item"><a href="javascript:;"><img src="./2.jpg" alt=""></a></li><li class="thumb-item"><a href="javascript:;"><img src="./3.jpg" alt=""></a></li><li class="thumb-item"><a href="javascript:;"><img src="./4.jpg" alt=""></a></li><li class="thumb-item"><a href="javascript:;"><img src="./5.jpg" alt=""></a></li><li class="thumb-item"><a href="javascript:;"><img src="./6.jpg" alt=""></a></li></ul></div></div></body><script src="./index.js"></script><script type="text/javascript">var slider = new Slider({sliderItem:'slider-item',thumbItem:'thumb-item'})</script></html>
*{margin: 0px;padding: 0px;text-decoration: none;list-style: none;}img{width: 100%;height: 100%;}.slider-wrap{width: 996px;height: 480px;margin: 50px auto;border: 1px solid #000;}.slider{float: left;position: relative;width: 853px;height: 480px;}.slider .slider-item{display: none;position: absolute;top:0;left: 0;height: 480px;}.slider .slider-item.active{display: block;}.thumbs{float: left;width: 142px;height: 480px;}.thumb-item{height: 80px;opacity: .5;}.thumb-item.cur{opacity: 1;}
// var thumbItem = document.getElementsByClassName('thumb-item'),// sliderItem = document.getElementsByClassName('slider-item');// console.log(thumbItem);// console.log(sliderItem);// for(var i = 0;i<thumbItem.length;i++){// (function(j){// thumbItem[j].onclick = function () {// // console.log(i);// for(var k=0;k<thumbItem.length;k++){// thumbItem[k].className = 'thumb-item';// sliderItem[k].className = 'slider-item';// }// sliderItem[j].className +=' active';// this.className += ' cur';// }// })(i)// };(function(){var Slider = function(opt){this.sliderItem = document.getElementsByClassName(opt.sliderItem);this.thumbItem = document.getElementsByClassName(opt.thumbItem);this.bindClick();}Slider.prototype = {bindClick: function(){var slider = this.sliderItem,thumbs = this.thumbItem;for(var i = 0;i<thumbs.length;i++){(function(j){thumbs[j].onclick = function(){for(var k =0;k<thumbs.length;k++){/*给所有设置默认状态*/thumbs[k].className= 'thumb-item';slider[k].className= 'slider-item';}// 给点击的图片单独设置this.className += ' cur';slider[j].className+=' active';}})(i)}}}window.Slider = Slider;})();
思路
css写好,点击图片,通过在元素上删除类,添加类,从而改变元素上的css代码
小图设置透明度0.5|1,大图设置display:none|block
html、css布局思路
float左右布局,左面的大div中有六张大图片,让它们重合,通过absolute,把li都设置成absolute,就可以让其重合
<div id="box" class="num num1"></div><script >var div=document.getElementById("box");div.className='num';</script>

通过给className命名来清空之前的class类
作业 选项卡demo
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="./indexdemo.css"></head><body><div class="tab-wrap"><div class="tab clearfix"><div class="tab-item cur"><a href="javascript:;">选项卡1</a></div><div class="tab-item"><a href="javascript:;">选项卡2</a></div><div class="tab-item"><a href="javascript:;">选项卡3</a></div></div><div class="page"><div class="page-item active">1</div><div class="page-item">2</div><div class="page-item">3</div></div></div></body><script src="./indexdemo.js"></script><script>var tab = new Tab({tabItem: 'tab-item',pageItem: 'page-item',cur: 'cur',active : 'active'})</script></html>
*{margin: 0px;padding: 0px;list-style: none;text-decoration: none;}.clearfix::after,.clearfix::before{content: '';display: table;clear: both;}/* 19 22 */.tab-wrap{width: 500px;margin: 50px auto;}.tab .tab-item{float: left;width: 100px;height: 50px;line-height: 50px;}.tab .tab-item.cur{background-color: #000;/* color: #fff; */}.tab .tab-item a{display: block;height: 100%;text-align: center;color: #000;}.tab .tab-item.cur a{color: #fff;}.page{position: relative;height: 450px;border: 1px solid #000;}.page .page-item{display: none;position: absolute;top: 0;left: 0;width: 100%;height: 100%;text-align: center;line-height: 450px;font-size: 100px;}.page .page-item.active{display: block;}
// var tabsItem = document.getElementsByClassName('tab-item'),// pageItem = document.getElementsByClassName('page-item');// console.log(tabsItem,pageItem);// for (var i = 0; i < tabsItem.length; i++) {// (function(j) {// tabsItem[j].onclick = function() {// for (var k = 0; k < tabsItem.length; k++) {// tabsItem[k].className = 'tab-item';// pageItem[k].className = 'page-item';// }// pageItem[j].className += ' active';// this.className += ' cur';// }// })(i);// };(function () {var Tab = function (opt) {this.tabs = document.getElementsByClassName(opt.tabItem);this.pages = document.getElementsByClassName(opt.pageItem);this.bindClick(opt.tabItem, opt.pageItem, opt.cur, opt.active);}Tab.prototype = {bindClick: function (tabItem, pageItem, cur, active) {var tabs = this.tabs;var pages = this.pages;for (var i = 0; i < tabs.length; i++) {(function (j) {tabs[j].onclick = function () {for (var k = 0; k < tabs.length; k++) {tabs[k].className = tabItem;pages[k].className = pageItem;}this.className = tabItem + ' ' + cur;pages[j].className = pageItem + ' ' + active;}})(i);}}}window.Tab = Tab;})();
