梗概
这节课程是铺垫的课,等下节课程再详细讲,从基础开始一点点剖析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;
})();