DOM的基本操作
文章目录
什么是DOM
DOM是一套方法和集合的统称
1.DOM—> Document Object Model
DOM、BOM等一切系统生成的成组的方式,基本上全是类数组。
2.DOM定义了表示和修改文档所需的方法。
DOM对象即为宿主对象,由浏览器厂商定义,用来操作html和xml功能的一类对象的集合(DOM不能操作css)。也有人称DOM是对HTML以及XML的标准编程接口。
xml是html之前的版本 xml ---- xhtml ---- html
xml中可以自定义标签,以前传数据都是xml,现在被json替代了。
// 自定义标签可以作为属性名 内容就是属性值
<student>
<name>老邓</name>
<age>100</age>
</student>
1.对节点的增删改查
查看元素节点
document代表整个文档
// document单独写就代表整个文档的js显示形式
//整个文档啥意思呢 可以理解为html标签的上一级 包含所有内容
document.getElementByld()
元素id在ie8以下的浏览器,不区分id大小写,而且也返回匹配name属性的元素,所以ie8以下的浏览器写name="only"也会被选出来。用得很少!!!id选择器尽量不用。
// 通过id查找元素 选出的是整个id对应的内容部分
<div id="only"></div>
<script type="text/javascript">
// id和元素是一一对应的 所以一个id只能选一个元素 所以这里element是单数
var div = document.getElementById('only');
</script>
getElementsByTagName()
通过标签名选择元素,最主流的用法。
// 通过标签名把标签选出来,选出来之后封装到一个类数组中,所有的标签通过类数组的索引位排序
<div id="only"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div');
// 拿出div后是一个数组 可以随意操作
// div.length;
// div[1].innerHTML=123;
</script>
// 选div中的p标签
<div>
<p></p>
</div>
<p></p>
<script type="text/javascript">
var p = document.getElementsByTagName('p')[0]; //0就是第一个p标签
</script>
var div = document.getElementsByTagName('div')[0]; // 选出第一个div
// 通过DOM修改div属性
div.style.width = "100px";
div.style.height = "100px";
div.style.backgroundcolor = "red";
// 点击次数为奇数时绿色 偶数时红色
var conut = 0;
div.onclick = function () { // 一旦发生点击事件,将会执行后面的函数
count ++;
if(count % 2 == 1) {
this.style.backgroundcolor = "green"; // 谁调用的this,this就指向谁
}else {
this.style.backgroundcolor = "red";
}
}
getElementsByName()
需注意,只有部分标签name可生效(表单,表单元素,img,iframe)
// 但凡是elements的都是选出后封装成类数组(除了id之外其他都是)
<input name="fruit"></input>
<script type="text/javascript">
var div = document.getElementsByName('fruit');
</script>
getElementsByClassName()
类名->ie8和ie8以下的ie版本中没有,可以多个class一起
// 注意 页面中哪怕只有一个demo 但是选出来的只有一个也是以数组的形式展示 所以要拿某个特定的demo还是需要加下标
<div>
<p class="demo"></p>
</div>
<p></p>
<script type="text/javascript">
var p = document.getElementsByTagName('demo')[0];
</script>
querySelector()
css选择器在ie7和ie7以下的版本中没有,querySelector不常用,因为它选出的数据不是实时的。
<div>
<strong></strong>
<div>
<span>
<strong class="demo">123</strong>
</span>
</div>
<script type="text/javascript">
// css中怎么选择元素这里就怎么选 因为它识别的就是css > 是直接下级元素
// 注意这里选出的是一个 不是一组
var strong = document.querySelector('div > span strong.demo');
</script>
querySelectorAll()
css选择器在ie7和ie7以下的版本中没有,querySelectorAll不常用,因为它选出的数据不是实时的
<div>
<strong></strong>
<div>
<span>
<strong class="demo">123</strong>
</span>
</div>
<script type="text/javascript">
// 注意这里选出的是一组 只有一个也是以数组的形式展示
var strong1 = document.querySelectorAll('div > span strong.demo');
</script>
// querySelectorAll()是静态的
<div></div>
<div class="demo"></div>
<div></div>
<script type="text/javascript">
// 一开始选择三个标签之后就不改了 哪怕div.remove()把那个元素删了也还是存在这个div中 就好比当时拷贝了一个副本 但是后来更新也不会发生改变
var div = document.querySelectorAll('div');
</script>
遍历节点树:
<div>
<span></span>
<div>
<p></p>
</div>
</div>
div(父节点)
span(左孩子) div(右孩子)
p(叶子结点)
parentNode —–>父节点
最顶端的parentNode为#document,一个元素只有一个父节点。
<div>
<strong></strong>
<span></span>
<em></em>
</div>
<script type="text/ javascript">
// 通过parentNode可以查找到当前元素的父节点
// 一直找上去会发现顶层是document 而document没爹
var strong = document.getElementsByTagName('strong')[0];
</script>
childNodes —–>子节点们
一个元素的子节点有若干个
<div>
<strong>
<span>1</span>
</strong>
<span></span>
<em></em>
</div>
<script type="text/ javascript">
// 通过childNodes可以查找到当前元素的子节点
// 注意:strong中的span节点时孙子节点 子节点是下一层节点
var strong = document.getElementsByTagName('div')[0];
// div.childNodes.length 返回长度是7 因为空白文本节点也算(标签与标签之间的空格 div和strong之间 strong和span之间 span和em之间 em和div之间)
</script>
<div>
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.childNodes.length 返回长度是7 也就是div.childNodes类数组中有七个元素四个文本节点 一个注释节点 一个strong节点 一个span节点
</script>
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.childNodes.length 返回长度还是7 123也是文本 只不过之前是空文本 现在有内容
</script>
firstChild —–>第一个子节点
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.firstChild 返回第一个子节点 文本节点“ 123 ”
</script>
lastChild —–>最后一个子节点
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.lastChild 返回最后一个子节点 空文本节点#text
</script>
nextSibling —–>后一个兄弟节点
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var strong = document.getElementsByTagName('strong')[0];
// div.nextSibling 返回后一个兄弟节点 空文本节点#text
</script>
previousSibling —–>前一个兄弟节点
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var strong = document.getElementsByTagName('strong')[0];
// div.previousSibling 返回前一个兄弟节点 空文本节点#text
</script>
基于元素节点树的遍历
不包含文本节点和注释节点。除了children以外,都是ie9以下不兼容。
parentElement —–>返回当前元素的父元素节点
(IE不兼容)
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.parentElement 返回当前元素的父元素节点body
</script>
html的元素父节点是null 因为document不是元素节点,是文本节点。
children —–>只返回当前元素的元素子节点
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.children 返回当前元素的元素子节点 strong、span
</script>
node.childElementCount === node.children.length
当前元素节点的子元素节点个数(IE不兼容)
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.childElementCount 返回当前元素的元素子节点个数 和div.children.length一样
</script>
firstElementChild —–>返回的是第一个元素节点
(IE不兼容)
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.firstElementChild 返回当前元素的第一个子节点 strong
</script>
lastElementChild —–>返回的是最后一个元素节点
(IE不兼容)
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// div.firstElementChild 返回当前元素的最后一个子节点 span
</script>
nextElementSibling—–>返回后一个兄弟元素节点
(IE不兼容)
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
<em></em>
<i></i>
<b></b>
</div>
<script type="text/javascript">
var strong = document.getElementsByTagName('strong')[0];
// div.nextElementSibling 返回后一个兄弟元素节点span
</script>
previousElementSibling –>返回前一个兄弟元素节点
(IE不兼容)
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
<em></em>
<i></i>
<b></b>
</div>
<script type="text/javascript">
var span = document.getElementsByTagName('span')[0];
// div.previousElementSibling 返回前一个兄弟元素节点span
</script>
节点的四个属性
nodeName
元素的标签名,以大写形式表示(非注释和文本元素节点),只读不可写
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
<em></em>
<i></i>
<b></b>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div');
</script>
// 上面代码访问div.firstChild.nodeName第一个子元素的标签名
// 返回"#text"
// 访问div.ChildNodes[1].nodeName 返回第2个子元素的标签名
// 返回“#comment”
// 访问div.ChildNodes[3].nodeName 返回第4个子元素的标签名
// 返回“STRONG”
nodeValue
Text节点或Comment节点的文本内容,可读写
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
<em></em>
<i></i>
<b></b>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div');
</script>
// 可以修改注释或文本节点的内容
nodeType 获取节点类型
该节点的类型,只读不可写,每一个节点都有一个nodeType属性
节点的类型 |
---|
元素节点——1 |
属性节点——2 |
文本节点——3 |
注释节点——8 |
document——9 |
DocumentFragment——11 |
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
<em></em>
<i></i>
<b></b>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div');
</script>
// 访问document.nodeType 返回9
// div.childNodes[1].nodeType 第二个子元素节点是注释节点
// 返回8
// div.childNodes[0].nodeType 第一个子元素节点是文本节点
// 返回3
// div.childNodes[3].nodeType 第四个子元素节点是strong节点
// 返回1 元素节点
// 把div下面的元素节点全挑出来放到数组中返回
<div>
123
<!-- This is comment -->
<strong></strong>
<span></span>
<em></em>
<i></i>
<b></b>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div');
// 封装方法 传一个node就把对应的子元素全返回(不能用children)
// 思路:全部遍历一遍 把nodeType为1(元素节点)的全部放进数组中
function retElementChild(node) {
var arr =[];
child = node.childNodes;
len = child.length;
for( var i = 0; i < len, i ++) {
// 返回类型为1的部分放进数组中
if(child[i].nodeType === 1) {
arr.push(child[i]);
}
}
return arr; // 返回数组
}
</script>
// 高级写法
function retElementChild(node) {
var temp ={
length :0;
push : Array.prototype.push,
// 加上这个属性 让对象变得像数组
splice : Array.prototype.splice
};
child = node.childNodes;
len = child.length;
for( var i = 0; i < len, i ++) {
if(child[i].nodeType === 1) {
temp.push(child[i]);
}
}
return temp;
}
temp对象形式展示
temp数组形式展示
attributes
Element节点的属性集合,属性名不可以改,属性值可以改。基本不用!
// 属性节点结合 d="only" class="demo"这两个是属性
<div id="only" class="demo"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div');
// 访问div.attributes 返回对应元素的属性集合
</script>
节点的一个方法Node.hasChildNodes();
<div id="only" class="demo">
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
// hasChildNodes() 判断是否有子节点(包含注释和文本) 返回true和false div中span删除了也还有子节点(文本分割字节) 除非<div></div> 这样两个div挨着 没有文本字节了就返回false
</script>
DOM结构树
代表一系列继承关系!!!
Document应该还有一个分支XMLDocument,Element也应该还有一个分支XMLElement
Node也是一个构造函数,是结构树的最顶端。
document和Document的区别
document返回的是整个文档,大的Document返回的是构造函数(因为构造函数的函数名才要求首字母大写),但是这个构造函数比较特殊,不能new它,这是系统留给自己的!
document、Document和HTMLDocument的联系
大的Document是小的document的构造函数的原型,所以大的Document加一个abc属性,通过小的document能访问出来。
document --> HTMLDocument document的构造函数是HTMLDocument
原型继承关系:
document --> HTMLDocument.prototype --> Document.prototype
// 因为document的构造函数时HTMLDocument
// 所以document的原型是 HTMLDocument.prototype
// 而HTMLDocument的原型又是Document.prototype
HTMLDocument.prototype = {
__proto__ : Document.prototype;
}
继承遵循就近原则
HTMLElement
如果在HTMLElement上定义方法,那所有下级的元素都可以使用
HTMLHeadElement
head标签能使用 HTMLHeadElement上定义的方法
HTMLHeadElement.prototype.abc='demo';
var head = document.getElementsByTagName ('head')[0];
head.abc;
HTMLBodyElement
body标签能使用 HTMLBodyElement上定义的方法
HTMLBodyElement.prototype.abc='demo';
var body = document.getElementsByTagName ('body')[0];
body.abc;
找原型最顶端
document.__proto__ // 返回HTMLDocument{...}
document.__proto__.__proto__ // 返回Document{...}
document.__proto__.__proto__.__proto__ // Node{...}
document.__proto__.__proto__.__proto__.__proto__ // 事件
document.__proto__.__proto__.__proto__.__proto__.__proto__ // 返回Object.prototype
document.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__ // 返回null
DOM基本结构
1.getElementByld方法定义在Document.prototype上,即Element节点上不能使用。
getElementByld --> Document.prototype
// 所以无论是XMLDocument还是HTMLDocument上都能用 所以跟Document并行的节点(Element等)不能使用
2.getElementsByName方法定义在HTMLDocument.prototype上,即非html中的document不能使用(XMLDocument,Element)
getElementsByName --> HTMLDocument.prototype
// 所以XMLDocument(平级)或者Element等不相干的节点不可使用
3.getElementsByTagName方法定义在Document.prototype和Element.prototype上
getElementsByTagName --> Document.prototype
getElementsByTagName --> Element.prototype
// 所以无论是XMLDocument还是HTMLDocument上以及Element包含的部分HTMLElement/XMLElement以及包含的部分都能用 所以getElementsByTagName比较灵活
<div>
<span>1</span>
</div>
<span></span>
<script type="text/javascript">
// div和span都属于element 所以都可以调用getElementsByTagName这个方法
var div = document.getElementsByTagName('div')[0];
var span = div.getElementsByTagName('span')[0];
// 写*就是把所有的标签都选出来了
var div = document.getElementsByTagName('*')[0];
</script>
4.HTMLDocument.prototype定义了一些常用的属性,body,head,分别指代HTML文档中的<body><head>标签。
document.body --> body // document中的body就是body标签
document.head --> head // document中的head就是head标签
5.Document.prototype上定义了documentElement属性,指代文档的根元素,在HTML文档中,他总是指代<html>元素
// document中的documentElement就是html标签
document.documentElement --> html
6.getElementsByClassName、querySelectorAll、querySelector在Document.prototype,Element.prototype类中均有定义
getElementsByClassName、querySelectorAll、querySelector --> Document.prototype
getElementsByClassName、querySelectorAll、querySelector --> Element.prototype
// 所以无论是XMLDocument还是HTMLDocument上以及Element包含的部分HTMLElement/XMLElement以及包含的部分都能用
课堂练习
1.遍历元素节点树(在原型链上编程)
// 方法一:给你一个父节点 然后遍历所有子节点
// 已知树形结构,把层级结构打印出来(分层打印出来)
<div>
<p></p>
<span>
<strong></strong>
<b></b>
</span>
</div>
2.封装函数,返回元素e的第n层祖先元素节点
<div>
<strong>
<span>
<i></i>
</span>
</strong>
</div>
<script type="text/javascript">
var i = document.getElementsByTagName('i')[0];
// 第一个参数是元素 第二个是num(也就是第几个父级)
function retParent(elem, n) {
// 加elem是因为null没父级 所以elem为null时退出循环
while(elem && n) {
// 把elem的父级赋值给elem
elem = elem.paentElement;
n--; // n(父级)有多少个就循环多少圈
}
return elem;
}
</script>
// 访问retParent(i,1) 返回span
// 访问retParent(i,2) 返回strong
// 访问retParent(i,3) 返回div
// 访问retParent(i,10) 报错 没那么多父级 所以条件加elem
3.封装函数,返回元素e的第n个兄弟元素节点,n为正,返回后面的兄弟元素节点,n为负,返回前面的,n为0,返回自己。
<div>
<span></span>
<p></p>
<strong></ strong>
<i></i>
<address></ address>
</div>
<script type="text/javascript">
var strong = document.getElementsByTagName('strong')[0];
// 第一个参数是元素 第二个是num(也就是第几个兄弟)
function retSibling(e, n) {
// 加e是因为null没兄弟 所以e为null时退出循环
while(e && n) {
// 把e的兄弟赋值给elem
if(n > 0) {
e = e.nextElementSibling;
// n --是因为返回后面的兄弟节点了 所以-1
n --;
}else {
e = e.priviousElementSibling;
// n ++是因为返回前面的兄弟节点了 所以+1
n ++;
}
}
// n为0,返回自己。不用处理
return e;
}
</script>
// 不通过nextElementSibling和priviousElementSibling方法
function retSibling(e, n) {
while(e && n) {
if(n > 0) {
if(e.nextElementSibling) { // 还能用就用
e = e.nextElementSibling;
else {
// for循环可以不加执行体 一直到下个节点时元素节点 e为nu会报错ll 所以e也加入判断条件
for(e = e.nextSibling;e && e.nodeType != 1; e = e.nextSibling;)
}
}
n --;
}else {
if(e = e.priviousElementSibling;) {
e = e.priviousElementSibling;
}else {
for(e = e.priviousSibling;e && e.nodeType != 1; e = e.priviousSibling;)
}
n ++;
}
}
return e;
}
4.编辑函数,封装myChildren功能,解决以前部分浏览器的兼容性问题
<div>
<b></b>
abc
<!-- this is comment -->
<strong>
<span>
<i></i>
</span>
</strong>
</div>
<script type="text/javascript">
// 考点就是怎么区分元素节点和非元素节点
Element.prototype.myChildren = function () {
var child = this.childNodes;
var len = child.length;
var arr = [];
for(var i =0; i< len; i ++){
if(child[i].nodeType == 1){
arr. push(child[i]) ;
}
}
return arr;
}
var div = document.getElementsByTagName('div')[0];
</script>
// 访问div.myCildren() 返回[b, strong]
5.自己封装hasChildren()方法,不可用children属性
// 判断有没有子元素(空文本和注释不算的那种)
<div>
<b></b>
abc
<!-- this is comment -->
<strong>
<span>
<i></i>
</span>
</strong>
</div>
<script type="text/javascript">
function hasChildren() {
var child = this.childNodes;
var len = child.length;
for(var i =0; i< len; i ++){
if(child[i].nodeType == 1){
return true;
}
}
return false;
}
var div = document.getElementsByTagName('div')[0];
</script>
增加元素节点
document.createElement();常见
创建元素节点
// 创建一个div标签 并且返回到div变量中(也就是代表div标签)
var div = document.caeateElement('div');
// 创建好之后 往容器中加入创建的div
document.body,appendChild(div)
// 修改div
div.innerHTML = 123
document.createTextNode();
创建文本节点
var text = document.createTextNode('张杰很帅!!!');
document.createComment();
创建注释节点
var comment = document.createComment('This is comment!');
document.createDocumentFragment();
插入元素节点
ParentNode.appendChild();常见
任何一个元素节点都有appendChild()方法,可以直接理解成push
创建完的东西插入已知的东西
<div></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
var text = document.createTextNode('张杰很帅!!!');
var span = document.caeateElement('span');
// div调用appendChild方法把text放入div中
div.appendChild(text);
// span出现在text后面
div.appendChild(span);
var text1 = document.createTextNode('demo');
// 往span中添加text1
span.appendChild(text1);
</script>
把已知的,已经在页面中的东西插入到另一个东西中,没问题,所以说明appendChild相当于剪切操作。
<div></div>
<script type="text/javascript">
// 试试就会发现没毛病,所以appendChild相当于剪切操作。
span.appendChild(text);
</script>
<div></div>
<span></span>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
var span = document.getElementsByTagName('span')[0];
div.appendChild(span); // 把span标签插入div标签中
</script>
ParentNode.insertBefore(a, b);常见
一定要父级调用,往父级自己内部插入东西,可以理解为在b之前插入a。
<div>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
var span = document.getElementsByTagName('span')[0];
var strong = document.caeateElement('strong');
var i = document.caeateElement('i');
// 在span之前往div中插入strong标签
div.insertBefore(strong, span);
// 把i标签插入strong之前
div.insertBefore(i, strong)
</script>
删除元素节点
parent.removeChild();
谋杀:父节点删除自己的子节点,removeChild是剪切操作。
<div>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
var span = document.getElementsByTagName('span')[0];
var strong = document.caeateElement('strong');
var i = document.caeateElement('i');
div.insertBefore(strong, span);
div.insertBefore(i, strong)
</script>
// 父节点很删除子节点i标签
div.removeChild(i);
// i标签赋值给ii
var ii = div.removeChild(i);
// 访问ii 返回<i></i> 说明remove是剪切操作
父节点删除i标签
删除后的i标签赋值给ii (证明removeChild是剪切操作)
child.remove();常见
自杀:子节点自己调用remove()方法自尽,remove直接删除。
<div>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
var span = document.getElementsByTagName('span')[0];
var strong = document.caeateElement('strong');
var i = document.caeateElement('i');
div.insertBefore(strong, span);
div.insertBefore(i, strong)
</script>
// 子节点自己删除i标签
i.remove();
替换
parent.replaceChild(new, origin);
拿新的元素去替换老的元素。
<div>
<span></span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
var span = document.getElementsByTagName('span')[0];
var strong = document.caeateElement('strong');
var i = document.caeateElement('i');
div.insertBefore(strong, span);
div.insertBefore(i, strong);
var p = document.caeateElement('p');
</script>
// 用p替换strong
div.replaceChild(p, strong)
替换前的div
p替换strong后
Element节点的一些属性
innerHTML
改变标签内的内容,inner操作赋值都会覆盖内容 除了用+=
<div>
<span>123</span>
<strong>234</strong>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
</script>
// div.innerHTML 这样写是获取div中的内容
// div.innerHTML = '123' 这样写是覆盖div中的内容(这里把div内的span和strong都覆盖了)
// div.innerHTML += '456' // 在123后追加456
div.innerHTML内容获取和覆盖
div.innerHTML += 操作
往innerHTML中写html结构都是可以识别的
innerText(火狐不兼容)/ textContent(老版本IE不好使)
<div>
<span>123</span>
<strong>234</strong>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
</script>
div.innerText 获取所有标签文本内容。因为火狐不兼容innerText,所以火狐有一个功能一样的方法textContent。
div.innerText = '123'赋值会把div中的内容全部覆盖
div.textContent获取内容
Element节点的一些方法
ele.setAttribute()
给元素设置行间属性,前面是属性名,后面是属性值。列如:div.setAttribute('class','demo');
<div>
<span>123</span>
<strong>234</strong>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
</script>
div.setAttribute('class','demo');
div.setAttribute('id','only');
ele.getAttribute();
获取元素属性值:div.getAttribute('id') 获取id的属性值only
<div>
<span>123</span>
<strong>234</strong>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
</script>
练习:取data-log(打点)
// 记录一个a标签被点击了多少次
<div>
<a href="#"data-log="0">hehe</a>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
var a = document.getElementsByTagName('a')[0];
a.onclick = function () {
// 点击一次就会打印一次
console.log(this.getAttribute('data-log'));
}
</script>
练习: 给所有标签分别加上属性和属性值
<div></div>
<span></span>
<strong></strong>
<script type="text/javascript">
var all = document.getElementsByTagName('*');
for(var i = 0; i < all.length; i ++) {
all[i].setAttribute('this-name',all[i].nodeName);
}
</script>
课堂练习
请编写一段JavaScript脚本生成下面这段DOM结构,并且插入到页面中去。要求:使用标准的DOM方法或属性。
<div class="example">
<p class="slogan">最帅!</p>
</div>
<script type="text/javascript">
var div = document.caeateElement('div');
var p = document.caeateElement('p');
div.setAttribute('class', 'example');
p.setAttribute('class', 'slogan');
//p.innerText += '张杰最帅!'; 这个和下面的都可以插文本
var text = document.createTextNode('最帅!')
// appendChild插入元素节点
p.appendChild(text); // 在p中插入text
div.appendChild(p); // 往div中插入p标签
// 把div插入到body中,也就是写入到页面中去
document.body.appendChild(div);
</script>
提示 dom.className可以读写class
dom.className = '';
dom.id = '';
课后作业
1.封装函数insertAfter();功能类似insertBefore()
提示:可忽略老版本浏览器,直接在Element.prototype上编程
直接在原型链上变成的好处是this可以指代任何一个想调用的对象!!!
// 假如要放一个元素到b标签之后 其实就是span标签之前 也就是下一个兄弟元素标签之前 如果是最后一位 直接appendChild
<div>
<i></i>
<b></b>
<span></span>
</div>
<script type="text/javascript">
Element.prototype.insertAfter = function (targetNode, afterNode) {
// 定义afterNode的下一个兄弟元素之前就是要放入的位置
var beforeNode = afterNode.nextElementsiling;
if(beforeNode == null) {
// 没有兄弟节点时直接插入targetNode this指待插入元素
this.appendChild(targetNode);
}else {
// 在beforeNode之前插入targetNode
this.inserBefore(targetNode, beforeNode)
}
}
var div = document.getElementsByTagName('div')[0];
var b = document.getElementsByTagName('b')[0];
var span = document.getElementsByTagName('span')[0];
var p = document.createElement('p');
</script>
div.insertAfter(p, b); 在b标签之后加入p标签。
2.将目标节点内部的节点顺序逆序。
例如:
<div><a></a><em></em></div>
<div><em></em><a></a></div>
// 把b标签剪切到span标签之后 再把i标签剪切到b标签之后
<div>
<i></i>
<b></b>
<span></span>
</div>
<script type="text/javascript">
Element.prototype.nx = function () {
var div = document.getElementsByTagName('div')[0];
var children = div.children;
var len = children.length;
for(i = 0; i < len; i ++) {
if(children[i] !== div.lastElementSibling) {
div.appendChild(this.previousElementSibling);
}else {
}
}
</script>
获取窗口属性
查看滚动条的滚动距离
window.pageXoffset/page.Yoffset
IE8及IE8以下不兼容(下面的那种方法就是IE8及以下的版本用来查看滚动条滚动距离的)
// window.pageXoffset 求x轴滚动距离
// window.pageYoffset 求y轴滚动距离
document.body/documentElement.scrollLeft/scrollTop
兼容性比较混乱,用时取两个值相加,因为不可能存在两个同时有值。
// document.body.scrollLeft
// document.body.scrollTop
// documentElement.scrollLeft
// documentElement.scrollTop
document.body方法如果有值ocumentElement就会没值,ocumentElement方法如果有值ocumentElement就会没值document.body,所以用的时候取两个值相加。
封装兼容性方法,求滚动轮滚动离getScrollOffset()
function getScroll0ffset() {
if (window.pageXoffset) {
return {
x : window.pageXoffset,
y : window.pageYoffset
}
}else{
return {
x : document.body.scrollLeft + document.doc
umentElement.scrollLeft,
y : document.body.scrollTop + document.doc
umentElement.scrollTop
}
}
}
查看视口的尺寸
编写的网页的可见部分宽高,不包含浏览器头部地址栏和标签栏!
window.innerWidth/innerHeight
// window.innerWidth 1440是标准宽度
// window.innerHeight
IE8及IE8以下不兼容
document.documentElement.clientWidth/clientHeight
标准模式下,任意浏览器都兼容
// html第一行加了<!DOCTYPE html>就是标准模式
// document.documentElement.clientWidth
// document.documentElement.clientHeight
document.body.clientWidth/clientHeight
适用于怪异/混杂模式下的浏览器,可以兼容老版本的代码
// html第一行没有<!DOCTYPE html>就是怪异模式
// document.body.clientWidth
// document.body.clientHeight
封装兼容性方法,返回浏览器视口尺寸getViewportOffset()
document.compatMode查模式
标准模式返回CSS1Compat
怪异模式返回BackCompat 向后兼容
function getViewportOffset(){
if(window.innerWidth) {
return {
w : window.innerwidth,
h : window.innerHeight
}
}else{
if(document.compatMode === "BackCompat") {
return {
w : document.body.clientwidth,
h : document.body.clientHeight
}
}else{
return {
w : document.documentElement.clientwidth,
h : document.documentElement.clientHeight
}
}
}
获取Dom尺寸
查看元素的几何尺寸
domEle.getBoundingClientRect();
// domEle.getBoundingClientRect();
<div style="width : 100px; height : 100px; background-
color:red ; position:absolute; left:100px;top:100px">
</div>
var div = document.getElementsByTagName('div')[0];
// left/right/top/bottom是左右上下四个点的坐标
div.getBoundingClientRect()
兼容性很好
该方法返回一个对象,对象里面有left,top,right,bottom等属性。left和top代表该元素左上角的X和Y坐标, right和bottom代表元素右下角的X和Y坐标
height和width属性老版本IE并未实现
返回的结果并不是“实时的"
查看元素的尺寸
dom.offsetWidth,dom.offsetlleight
// dom.offsetWidth 获取元素宽度(盒子宽度 所以还要看padding和border)
// dom.offsetlleight 获取元素高度(盒子高度 所以还要看padding和border)
查看元素的位置
dom.offsetLeft, dom.offsetTop
注意:offsetLeft求的是元素距离他有定位的父级的距离。不管是left、right还是margin隔出来的距离都是返回这个距离。没有有定位的父级时才是相对文档的距离。
// dom.offsetLeft
// dom.offsetTop
特点:对于无定位父级的元素,返回相对文档的坐标。对于有定位父级的元素,返回相对于最近的有定位的父级的坐标。
dom.offsetParent
返回最近的有定位的父级,如无,返回body,body.offsetParent返回null
让滚动条滚动
window上有三个方法
scroll(),scrollTo() scrollBy();
scroll(), scrollTo()功能一模一样,但是这个滚动距离只会滚动一次,到位置就停了
// scroll(0,100) 第一个是x坐标 第二个是y坐标 y轴滚动条移到100px处
// scrollTo(0,100) 第一个是x坐标 第二个是y坐标 y轴滚动条移到100px处
scrollBy()是累加滚动
// scrollBy(0,100) 执行一次滑动100像素 再执行一次 继续滑动
三个方法功能类似,用法都是将x,y坐标传入。即实现让滚动轮滚动到当前位置。
区别:scrollBy()会在之前的数据基础之上做累加。
eg:利用scrollBy()快速阅读的功能
<div style="width:100px;height:100px;background-color:orange;color:#fff; font-size:40px; font-weight:bold;text-align: center;line-height: 100px; position:fixed ; bottom:200px; right: 50px; border-radius :50%;opacity:0.5;">start
</div>
<div style="width: 100px; height :100px; background-color:#0f0;color:#fff; font-size:40px;font-weight: bold;textalign: center;line-height : 100px;position:fixed ; bottom:50px; right:50px; border-radius :50%;opacity:0.5; ">stop
</div>
<script type="text/javascript">
var start = document.getElementsByTagName('div'[0];
var stop = document.getElementsByTagName('div'[1];
var timer = 0;
var key = true;
start.onclick = function () {// 0.1秒滚动10像素
// 这里速度会累加 因为产生了多个定时器 所以要加锁key
if(key) {
timer = setInterval( function () {
// 100可以写成变量 自定义速度
window.scrollBy(0,100);
clearInterval(timer);
},100);
key = false;
}
}
stop.onclick = function () { // 暂停
clearInterval(timer);
key = true;
}
}
</script>
脚本化CSS
Dom不能直接操作css,但是可以间接操作css
读写元素css属性
dom.style.prop
<div style="float:left;width:100px;height:100px; background-color:red;"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
</script>
// div.style 会展示所有这个div能用的css属性 标红的是我们使用的
// 属性名是数字(索引位)的属性和其他正常的属性在同一个对象中就是类数组
间接的修改css属性
可读写行间样式(行间样式就是定义在标签中的style=“width:100px”),没有兼容性问题,碰到float这样的保留字属性,前面应加css
// 假如把行间样式中的width去掉 style中定义 那宽度也是200 但是dom.style.width会打印空 因为这不是行间样式 无法读写
// 再添加dom.style.width=“200px"时 width就更改了
<style type="text/ css">
div{
width: 200px;
}
</style>
eg:float — > cssFloat
// 直接写float也行 但是因为是保留字 所以最好加css
复合属性必须拆解
// border:"1px solid #ccc"; // 这种复合属性最好拆解
组合单词变成小驼峰式写法
// 比如background-color 因为js无法识别- 只认数字字符下划线和$
// background-color --> backgroundColor
写入的值必须是字符串格式
// backgroundColor:yellow --> backgroundColr = "yellow"
没值的属性也可以添加值
div.style.borderRadius = "50%"
查询计算样式
window.getComputedStyle(ele,null);
获取伪元素
null是获取伪元素的
/*给div添加伪类*/
div::after {
content: "";
width: 50px;
height: 50px;
background-color: green;
display: inline-block;
}
/*获取伪类宽度*/
window.getComputedStyle(div,"after").width
点击红色方块时 伪元素(绿色部分)变黄色
// 点击时更换样式
<div class="green" style="float:left;width:10em;height:100px; background-color:red;">
</div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
div.onclick = function () {
div.className = "yellow"
}
</script>
<style>
.green::after {
content: "";
width: 50px;
height: 50px;
background-color: green;
display: inline-block;
}
.yellow::after {
content: "";
width: 50px;
height: 50px;
background-color: yellow;
}
</style>
获取当前元素展示出的一切css属性值(包括默认值)
// window.getComputedStyle(div,null);
对象就可以.属性,这里获取的是所有的属性 不只是行间样式 也包含style中定义的属性 这个比div.style更准一些 因为这个是所有的样式
计算样式只读
写入报错,样式是计算过的,就好比系统默认背景色是灰色 你定义背景黄色 最后出来的是混合之后的绿色 或者在行间和非行间中定义两个权重一样的宽度 一个200 一个300 最后计算出来就是250
返回的计算样式的值都是绝对值,没有相对单位
比如把width改成相对单位,会返回计算后的值,颜色返回rgba展示形式
<div style="float:left;width:10em;height:100px; background-color:red;">
</div>
IE8及 IE8以下不兼容,所以用以下方法
查询样式(了解就好 都淘汰了)
- ele.currenStyle
- 计算样式只读
- 返回的计算样式的值不是经过转换的绝对值
- IE独有的属性
封装兼容性方法getStyle(elem,prop);
function getstyle(elem, prop) {
if(window.getComputedStyle) {
return window.getComputedStyle(elem,null)[prop];
}else{
return elem.currentStyle[prop];
}
}
通过点击改变div的宽高并修改背景色
div {
width: 100px;
height: 100px;
background-color: red;
}
.active {
width: 200px;
height: 200px;
background-color: green;
}
.green::after {
content: "";
width: 50px;
height: 50px;
background-color: green;
display: inline-block;
}
.yellow::after {
content: "";
width: 50px;
height: 50px;
background-color: yellow;
}
var div = document.getElementsByTagName('div')[0];
div.onclick = function () {
// 方法一 改类(效率高、好维护)
div.className = "active";
// 方法二 直接修改(效率低、不好维护)
div.style.width = "200px";
div.style.height = "200px";
div.style.backgroundColor = "green";
}
小练习:让方块儿移动
<div style="width: 100px;height:100px ; background-color: red ; position:absolute;left:0;top:0;"></div>
<script type="text/javascript">
function getStyle(elem, prop) {
if(window.getComputedStyle) {
return window.getComputedStyle(elem,null)[prop];
}else{
return elem.currentStyle[prop];
}
}
var div = document.getElementsByTagName('div ')[0];
var speed = 2;
var timer = setInterval (function() {
speed += speed/7;
div.style.left = parseInt(getstyle(div,'left')) + speed + ' px ';
},10 );
if(parseInt(getstyle(div,'left') > 500) {
clearInterval(timer);
}
</script>
兼容,所以用以下方法`
查询样式(了解就好 都淘汰了)
- ele.currenStyle
- 计算样式只读
- 返回的计算样式的值不是经过转换的绝对值
- IE独有的属性
[外链图片转存中…(img-pqZWtLxN-1665755178158)]
封装兼容性方法getStyle(elem,prop);
function getstyle(elem, prop) {
if(window.getComputedStyle) {
return window.getComputedStyle(elem,null)[prop];
}else{
return elem.currentStyle[prop];
}
}
通过点击改变div的宽高并修改背景色
div {
width: 100px;
height: 100px;
background-color: red;
}
.active {
width: 200px;
height: 200px;
background-color: green;
}
.green::after {
content: "";
width: 50px;
height: 50px;
background-color: green;
display: inline-block;
}
.yellow::after {
content: "";
width: 50px;
height: 50px;
background-color: yellow;
}
var div = document.getElementsByTagName('div')[0];
div.onclick = function () {
// 方法一 改类(效率高、好维护)
div.className = "active";
// 方法二 直接修改(效率低、不好维护)
div.style.width = "200px";
div.style.height = "200px";
div.style.backgroundColor = "green";
}
小练习:让方块儿移动
<div style="width: 100px;height:100px ; background-color: red ; position:absolute;left:0;top:0;"></div>
<script type="text/javascript">
function getStyle(elem, prop) {
if(window.getComputedStyle) {
return window.getComputedStyle(elem,null)[prop];
}else{
return elem.currentStyle[prop];
}
}
var div = document.getElementsByTagName('div ')[0];
var speed = 2;
var timer = setInterval (function() {
speed += speed/7;
div.style.left = parseInt(getstyle(div,'left')) + speed + ' px ';
},10 );
if(parseInt(getstyle(div,'left') > 500) {
clearInterval(timer);
}
</script>