WebApi
API(Application Programming Interface,应用程序编程接口),API是一些预先定义的方法,这些方法能够实现某些特定的功能,我们无须知道这些API的实现方式,但是我们需要知道这些API如何使用。
- 任何开发语言都会提供自己的API
- API的特征输入和输出(参数/返回值)
通俗的讲,API就是编程语言给我提供的一些工具,通过这些工具,我们可以非常轻易的完成一些功能。
DOM
DOM(Document Object Model)文档对象模型,是W3C组织推荐的一套用于处理HTML的标准编程接口。
DOM又称为文档树模型,因为整个HTML文档是一个树形的结构
DOM会把整个页面看成一个对象,我们需要操作文档,只需要操作对象;
DOM:把页面中所有的东西都看成对象
Document 对象
- 每个载入浏览器的 HTML 文档都会成为 Document 对象。
- Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
- 提示:Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。
document
返回整个网页页面,包含html
document.documentElement
返回html dom中的root 节点 即 <html>
document.body
返回html dom中的body节点 即 <body>
DOM的初体验
console.log();
打印一个元素的时候,是以标签的形式进行展示的
console.dir();
打印一个元素的时候,是以对象的形式进行展示的
标签中的属性和对象中的属性是一一对应的,可以通过操作DOM对象来改变标签的属性
获取元素
通过ID获取元素
var 变量名 = document.getElementById('元素ID');
返回值是一个元素
<script></script>
要写在html的内容后面,才能保证页面加载完成后获取到这个对象。
通过ID来获取这个对象,如果存在这个ID,返回值是一个元素;
如果没有这个ID,返回值是null
在JS中直接使用ID来获取对象,而不是通声明获取返回值 ;
这个方法只有 document.getElementById("元素的id");
在早期,是ie提出来,id在页面中是唯一的,所以呢,在js中可以直接使用id,仅仅是ie提出来,不是规范,其他浏览器也支持。不推荐这么写
通过标签名获取元素
参数:标签名
返回值:一个伪数组,伪数组不是数组,不能使用属性的方法,但是可以跟数组一样进行遍历和使用下标进行操作。
注意:返回值有没有获取到元素,都是一个伪数组,即便元素只有一个;如果没有这个标签返回的是一个空的伪数组
【伪数组不能直接注册,需要通过下标来操作这个伪数组注册。】
var 变量名s = document.getElementsByTagName("标签名");
返回值是一个伪数组
var 变量名s = box.getElementsByTagName("标签名");
返回值是一个伪数组
通过类名获取元素:
var 变量名s = document.getElementsByClassName("class");
参数:字符串类型的类名
返回值:伪数组
注意:这个方法ie678不支持
根据name获取:只适用表单
只适用于表单元素
var ps = document.getElementsByName("aa");
根据css选择器获取
var 对象名 = document.querySelector();
参数:是一个css选择器, 如果是类选择器 .demo;如果是id选择器:#aa
返回值:只会返回一个对象,如果有很多个,会返回第一个
var 变量名 = document.querySelectorAll();
参数:是一个css选择器
返回值:会匹配到所有满足条件的,返回一个伪数组,0~n个,都会返回伪数组
this
- 给某个对象注册事件的时候,在事件内的this表示就是这个对象
- 伪数组使用this的必要性
- 当获取的对象返回的是伪数组时候,这个时候给每个元素注册事件使用for循环,但是for循环在被触发前就已经结束,再使用触发事件的时候调用的function的时候,内部使用了 伪数组.[i]=值; i的值在for循环结束的时候就已经改变了,触发的也不是当前的对象值了。
- 所以这个时候就必须使用this了
- 为了避免某些问题,极力推荐使用this来表示当前对象
- 函数内部的this是window
- 方法内部的this,指向当前的对象
- 构造函数内部的this,新创建的对象
- 事件里面的this,当前对象
阻止a标签的跳转
return false
- 对a注册事件,事件处理程序的函数代码: return false;
return false;
写在function内部最后,return后面的代码不会被执行
javascript:void(0);
- href:如果写了javascript:表示a标签不执行跳转,执行js代码
javascript:;
a标签不跳转
#
一般用在以后需要实现页面跳转的时候先用#代替
标签操作
修改标签属性
标签中的 alt title width src href
class在js中是一个保留字, 标签中class对应了对象中的className
1 | selector.alt = 值 |
标签自定义属性
- 我们之前讨论的属性,都是HTML规范中,标签本来就有的属性,对于标签自定义的一些属性,比较特殊。
- JS获取到html页面的对象后,是以对象的方式来存储标签的固有属性;
- 这个时候我们在DOM中操作为这个标签添加一些原本没有的属性,是不能够显示的,但是会存在这个对象中,在DOM中可以调用这些属性。
attribute方法:attribute方法设置的标签自定义属性可以显示在标签中,也可以设置原本就存在的属性的值
1 | selector.getAttribute(name)//获取标签的属性 |
标签的内容属性
innerText:内部的文本
innerHTML:内部的html
获取的时候:
innerHTML:会获取到内部的标签和内容,获取标签内容的时候,不管标签还是文本,都能获取到
innerText:只会获取文本,获取标签内容的时候,只会获取文本,标签扔掉了
1 | var box = document.getElementById("box"); |
设置的时候:
如果是innerHTML,标签会生效,innerHTML设置内容的时候,覆盖原来内容,标签也能生效,浏览器能解析这个标签。
如果使用innerText:标签不会生效,innerText对标签转义了。设置标签内容的时候,覆盖原来内容,对标签进行转义(目的:把标签直接当文本来用)
innerText和innerHTML设置的时候,都会覆盖原来的内容;
1 | box.innerHTML = "<h3>呵呵</h3>"; |
innerHTML和innerText用哪个?
innerHTML:能够识别html标签,标签能生效
innerText:不识别标签,对标签转义,当成文本
设置标签的内容,推荐使用 innerText,防止xss攻击,保证标签不生效
innerHTML:所有浏览器都支持
innerText:是IE提出来,IE浏览器是支持这个属性, 低版本的火狐不支持
textContent: 火狐推出来,低版本的IE678不支持
所有的浏览器基本都支持innerText和textContent
1 | var box = document.getElementById("box"); |
思路:以前的时候,怎么办?
如何处理兼容性问题? you can you up
先使用innerText去获取值,如果能获取到,直接用,如果获取不到,换成textContent
1 | function getInnerText(element) { |
表单的属性
所有的表单元素想要获取文本值,都要用value来获取
- 常见的表单属性有:disabled、type、value、checked、selected;
- 对于disabled、checked、selected三个属性来说,比较特殊。
- 在标签中,只要指定了disabled属性,无论有值没值,都代表这个input是被禁用的。注意,标签的disabled仅仅是默认值。
- 在DOM对象中,disabled的属性是一个布尔类型的属性,值只有true或者false
样式操作(className添加类)
div.className = "box";
给div添加一个类,类名是box,需要注意的是通过className添加类的时候会把原来class的所有类名覆盖掉,所以添加的时候要特别注意,原先样式有哪些类,一般不推荐使用
样式操作(style属性)
标签不仅可以通过class属性操作样式,还可以通过style属性操作样。同样的DOM对象可以通过className操作样式,也可以通过style属性操作样。
style设置的样式是行内样式,因此优先级要高于className设置的样式
- style在DOM中是一个对象,在对象里通过键值对的形式存储了行内样式属性。
- style的属性中如果带了-(会被当做减号)的在JS中应该用驼峰命名法来使用。
- style只能获取到标签内的行内样式属性,在类样式中定义的属性是获取不到的。
- 关于cssText;可以一次性设置style多个值,但是会覆盖掉原本存在的所有属性
1 | //优点:可以一次性设置多个值 |
html的几个特殊标签
document.body
: body比较常用,并且在页面中时唯一的,因此可以使用document.body
直接获取。document.documentElement
: 可以获取html元素document.head
: 可以直接获取head元素document.title
: 可以直接获取title的文本
排他思想
排他思想就是,通过遍历来干掉所有的人,然后通过this来复活自己,重新赋值;
tab案例中的li对应div;可以通过设置自定义属性的值来定义下标,在通过这个值下标来对应this需要的下标
tab案例
lis[i].setAttribute("index", i);
这个设置的属性会存储到DOM对象中,也会显示在标签中,
lis[i].index = i;
在外循环注册事件的时候就将值存储,只是将这个属性存到了DOM的对象中,但是标签没有这个原有属性,所以标签不会显示;
通过什么样的方法来存值,就用什么方法来获取;
tab案例中li对应的div可以通过直接赋值
假设成立法
假设某种结果成立,设置一个标记来判断;
通过设置一个变量值来判断,最好是布尔类型的,好判断,如果满足了某个条件而对这个变量进行改变值,那就说明假设没有成立。
节点操作
子女节点child
childNodes
获取所有的孩子节点(包括了元素节点和其他很多类型的节点,基本不常用)children
获取所有的子元素(用途很广泛),兼容性:IE678会把注释节点算上。children
是一个只读属性,不能修改他- 动态变化会随着页面内的子元素实时变化的,比如伪数组的长度
firstChild
第一个子节点firstElementChild
第一个子元素 有兼容性问题(IE678)lastChild
最后一个节点lastElementChild
最后一个子元素 有兼容性问题(IE678)
兄弟姐妹节点Sibling
nextSibling
下一个兄弟节点nextElementSibling
下一个兄弟元素(IE678不兼容)previousSibling
上一个兄弟节点previousElementSibling
上一个兄弟元素 有兼容性问题 可以封装一个兼容性方法
父母节点parent
parentNode
父节点,没有兼容性问题
克隆节点clone
会在内存中克隆一个节点, 这个节点克隆出来之后,就不会影响到原来的节点了。
语法:var newNode = node.cloneNode(deep)
- node:需要克隆的节点名
- deep:参数
- 默认false, 表示浅复制,只会复制一个标签,并不会复制内容
- true, 表示深复制,会复制所有的内容
- 注意
- 克隆出来的节点跟原来的节点没有关系了,修改了也不会相互影响。
- 如果克隆的节点带了id,我们需要给id重新设置一个值,不让id冲突
添加节点
appendChild
语法:parent.appendChild(newChild)
- parent:调用者,父节点来调用
- newChild:需要添加的那个孩子。
- 作用:把newChild添加到parent的孩子的最后面。
- 如果添加的是页面中本来就存在的元素,是一个剪切的效果,原来的就不在了。
insertBefore
语法:parent.insertBefore(newChild, refChild);
- parent:必须要父节点来调用
- newChild:需要添加的那个节点
- refChild:添加到哪一个节点的前面。
parent.insertBefor(newChild, null);
添加到父元素的最后一个子元素的后面parent.insertBefor(newChild, paren.firstElementChild);
添加到父元素的第一个子元素前面
创建节点
document.write
直接往页面添加节点,但是如果在页面加载完后,再使用 document.write
添加元素会覆盖掉所有加载完成的内容;
【不推荐使用,基本不用;】
可以生成新的节点,但是不推荐使用。如果页面已经加载完成了,你还是用 document.write
写内容的话,会把之前的页面给覆盖掉;
原理:页面从上往下加载的时候,会开启一个文档流,当页面加载完,文档流就会关闭。
document.write
的本意就是在文档流上写入内容。如果页面没加载完成,文档流还是开着的,document.write
直接在这个文档流上写东西;
如果页面加载完成了,还是用 document.write
写东西,会重新开启一个新的文档流,往新的文档流上写东西,旧的文档流就被新的文档流覆盖了。
innerHTML
innerHTML
创建新的节点会把原有的内容都覆盖掉,想要保留原有内容使用+=
,但是会出现效率问题
慎用:很容易出现效率问题
innerHTML
不要频繁的使用,用字符串把结构拼接好,一次性使用 innerHTML
添加节点
createElement
语法:var element = document.createElement("tagName");
作用:在内存中创建一个新的节点;
参数:”tagName”字符串新元素名,支持识别标签;
返回一个元素
用途广泛
删除节点
语法:parent.removeChild(child)
功能:由父盒子调用,删除里面的元素
参数:可以是找到的其他节点或者直接元素名(不能是伪数组)
替换节点
语法:parentNode.replaceChild(newChild, oldChild);
newChild
用来替换 oldChild
的新节点,如果 newChild
已经存在于DOM树中,则它会被从原始位置删除。