a标签点击不跳转
一旦给a标签添加点击事件
那么点击事件会执行的的同时 a标签也会实现跳转效果
这样用户体验很不好
如何解决a标签点击跳转问题:
1.把a标签的href改成 javaScript:;(不知道链接该写什么时 可以写这个)
<a href="javaScript:;">点击切换图片</a>
2.在a标签的点击事件里面 return false;(推荐使用的)
var alink=document.getElementsByTagName("a")[0];
var img=document.getElementsByTagName("img")[0];
alink.onclick=function () {
img.src="image/ww.jpg"
return false; //控制a标签的点击事件 是否跳转
}
innerHTML和innerText 属性
都是能够设置和获取标签内部内容的
但是使用上有一定的区别
元素.innerHTML:
获取:
获取当前标签内部所有的内容 以字符串返回
btnArr[0].onclick=function () {
console.log(box.innerHTML);
}
设置:
能替换当前标签内部所有内容 变成新设置的内容
如果新内容内部包含标签 则直接会渲染到页面上显示
btnArr[2].onclick=function () {
// box.innerHTML="我是新来innerHTML的内容";
box.innerHTML="<h1>我是新来innerHTML的内容</h1>";
}
元素.innerText:
获取:
获取当前标签内部所有的文本内容(不包括标签本身)(包括所有后代的文本)
btnArr[1].onclick=function () {
console.log(box.innerText);
}
设置:
能替换当前标签内部所有内容 变成新设置的内容
如果新内容内部包含标签 也不会渲染出标签效果
而是 原封不动的直接渲染文本到页面上
btnArr[3].onclick=function () {
box.innerText="<h1>我是新来的innerText内容</h1>";
}
标签的属性操作
通过className为元素设置 类名
但是 这个并不是真正的 修改标签上面的class
真正操作标签上面跟class等同的属性 是 setAttribute()方法
所以想要真正获取页面标签上面那个属性 就是 getAttribute()方法
所以标签属性操作的方法有:
标签对象.getAttribute("属性名")
根据标签属性名 获取标签属性值
标签对象.setAttribute("属性名","属性值")
为标签新增一个属性 属性名和属性值自定义
如果该属性名不存在 则增加
如果属性名存在 则在原有基础上修改为新值
btnArr[0].onclick=function () {
// box.className="pox";
// console.log(box.title);//我是一个盒子
/* console.log(box.id);//box
console.log(box.class);//undefined
console.log(box.className);//pox*/
// console.log(box.aaa);//undefined
/* console.log(box.getAttribute("aaa"));//哈哈
console.log(box.getAttribute("class"));//pox*/
box.setAttribute("qqq","自己新增的,虽然没什么用");
box.setAttribute("aaa","修改值");
// 别忘记原来还有一个类名 可以一起带上 防止丢类名
bo
标签对象.removeAttribute("属性名")
根据标签的属性名 删除一个标签属性
btnArr[1].onclick=function () {
box.removeAttribute("qqq");
}
修改操作
btnArr[2].onclick=function () {
box.setAttribute("qqq","我把qqq修改了")
}
标签属性操作和对象直接点调用属性操作有什么区别?
例如:
对象.getAttribute("属性名")
和
对象.属性名
有什么区别
如果该属性名是 这个标签本身自带的 (比如: id title style)
那么 这两个都能获取到
如果该属性名不是 这个标签本身自带的 (比如: aaa haha 自定义那些)
那么 只有对象.getAttribute能获取
节点访问关系
就是指通过 其中一两个节点 然后经过节点之间的关系找到其他节点
比如:
父节点 子节点 兄弟节点
所谓节点就是页面组成dom的那些标签和标签之间的文本
节点都有那些类型:
文本节点:
标签和标签之间的回车换行 或者标签内部的文本
元素节点:
标签本身就是一个元素节点
属性节点:
标签上面的属性 就叫属性节点
节点访问关系:
获取父节点 获取子节点 获取兄弟节点
获取父节点: 没有兼容问题
var 父节点= 节点对象.parentNode;
获取兄弟节点:
var 上一个兄弟=节点对象.previousSibling;
在谷歌/火狐/IE9+
获取上一个兄弟节点(包括文本节点)
在IE8及以下
直接获取上一个兄弟元素节点(不包括文本节点)
var 上一个兄弟=节点对象.previousElementSibling
在谷歌/火狐/IE9+
直接获取上一个兄弟元素节点(不包括文本节点)
在IE8及以下
返回undefined
// 兼容性写法
var previous=ele.previousElementSibling || ele.previousSibling
获取下一个兄弟节点:
效果跟上面的一毛一样
var next=ele.nextElementSibling || ele.nextSibling
获取单个子节点:
获取第一个子节点
var 第一个子节点=父节点.firstChild;
谷歌/火狐/IE9+
获取第一个子节点(包含文本节点)
IE8及以下
直接获取第一个元素子节点(不包含文本节点)
var 第一个子节点=父节点.firstElementChild;
谷歌/火狐/IE9+
直接获取第一个元素子节点(不包含文本节点)
IE8及以下
返回undefined
兼容性写法:
var 第一个子节点=父节点.firstElementChild || 父节点.firstChild;
获取最后一个子节点:
效果同上 一毛一样
兼容性写法
var 最后一个子节点=父节点.lastElementChild || 父节点.lastChild;
获取所有子节点:
var 伪数组= 父节点.childNodes;(W3C亲儿子 官方推荐使用的属性)
childNodes属性返回所有子节点 (包含文本节点)
在谷歌/火狐/IE9+
获取所有子节点(包含文本节点)
在IE8及以下
直接获取所有的元素子节点
var 伪数组=父节点.children;(不是官方推荐的)
直接返回所有的元素子节点
注意:
在IE8及以下 如果子节点中有注释节点 也能够获取到
获取任意兄弟节点
节点自己.parentNode.children[索引值]
var pinner=document.getElementById("inner");
var pox=document.getElementById("pox");
var box=pox.parentNode;
// 获取父节点
// var box=pinner.parentNode;
// console.log(box);
// var ul=pox.previousSibling;
// var ul=pox.previousElementSibling;
// var ul=pox.previousElementSibling || pox.previousSibling;
// console.log(ul);
// var ol=pox.nextElementSibling || pox.nextSibling;
// console.log(ol);
/*var first=box.firstElementChild || box.firstChild;
console.log(first);*/
// var last=box.lastElementChild || box.lastChild;
// console.log(last);
/*var childArr=box.childNodes;
// console.log(childArr);
for(var i=0;i<childArr.length;i++){
console.log(childArr[i]);
// childArr[i].style.color="hotpink";// Cannot set property 'color' of undefined
//Cannot set property 'color' of undefined 不能为undefined绑定color属性
// if(childArr[i].nodeType==1){
==1 表示当前节点是元素节点
// childArr[i].style.color="hotpink";
// }
}*/
/* var per;
console.log(per);
console.log(per.name);// Cannot read property 'name' of undefined*/
/*var childArr=box.children;
for(var i=0;i<childArr.length;i++){
console.log(childArr[i]);
}*/
console.log(pox.parentNode.children[0]);
console.log(pox.parentNode.children[1]);
获取父节点
var pp=document.getElementById("pp");
var box=pp.parentNode;
获取上一个兄弟节点
节点对象.previousElementSibling
获取下一个兄弟节点
节点对象.nextElementSibling
获取第一个子节点对象
父节点.firstElementChild
获取最后一个子节点对象
父节点.lastElementChild
获取所有子节点对象 返回一个伪数组 可以取任意的子节点
父节点.children;
获取任意子节点:
父节点.children[index];
获取所有兄弟节点的封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul id="box">
<li>外面的熊孩子真多</li>
<li>真的好吵</li>
<li id="inner">没变声真的很可怕</li>
<li>算了忍一忍把</li>
<li>就这样把</li>
</ul>
<script>
var inner=document.getElementById("inner");
console.log(getAllSiblings(inner));
function getAllSiblings(ele) {
// 获取当前元素的父元素的所有子元素
var allChild=ele.parentNode.children;
var siblingsArr=[];
for(var i=0;i<allChild.length;i++){
if(allChild[i]!=ele){
// 如果遍历到的子元素 不是自己 就表示 是 兄弟
//那么就放入数组中
siblingsArr.push(allChild[i]);
}
}
return siblingsArr;
}
</script>
</body>
</html>
Dom的增删改查
dom操作都是获取(查询)dom
1.获取页面元素的5种方式(获取dom)
2.节点访问关系(查询dom)
所以这两个操作都算是 dom节点增删改查中的查
那么接下来 讲解 增删改操作:
1.增加节点:
创建节点对象:
var 新节点对象= document.createElement("标签名")
方法调用者 只能是document
拼接节点对象
父节点.appendChild(新节点对象);
将新节点拼接到父节点的最后一个子元素后面
父节点.insertBefore(新节点对象,参考的老节点对象)
在老节点对象之前拼接一个新节点
var btnArr=document.getElementsByTagName("button");
var box=document.getElementById("box");
var ul=box.lastElementChild;
var num=0;
btnArr[0].onclick=function () {
// 创建节点对象
var newH1=document.createElement("h1");
// console.log(newH1);//没有内容的空h1
newH1.innerHTML="我是新来的-->"+(++num);
// console.log(newH1);
// 把h1拼接到页面上
// box.appendChild(newH1);
// 拼接到ul之前
box.insertBefore(newH1,ul);
}
2.删除节点:
父节点.removeChild(子节点对象)
将子节点从当前父节点中删除
var btnArr=document.getElementsByTagName("button");
var box=document.getElementById("box");
var ul=box.lastElementChild;
var num=0;
tnArr[1].onclick=function () {
// 删除节点
// box.removeChild(ul);
// 每次点击都删除最后一个子节点
box.removeChild(box.lastElementChild)
}
3.修改节点:
节点替换:
父节点.replaceChild(新节点对象,被替换的老节点)
把老节点替换成新节点对象
box.replaceChild(newOl,ul);
}
节点克隆
节点自己.cloneNode(布尔值) 布尔值默认false
拷贝一个节点对象
布尔值是false时: 只克隆标签本身 不包含内部内容(浅克隆)
布尔值是true时: 克隆标签本身和内容所有内容(深克隆)
btnArr[3].onclick=function () {
var cloneUl=ul.cloneNode(true);
// console.log(cloneUl);
box.appendChild(cloneUl)
}
元素的属性节点操作:
点对象.nodeType==1 表示当前节点是元素节点
节点对象.nodeType==2 表示当前节点是属性节点
节点对象.nodeType==3 表示当前节点是文本节点
获取一个元素节点中指定的属性节点
元素节点对象.getAttributeNode("属性名");
增加或修改一个属性节点的值
元素节点对象.setAttribute("属性名","属性值")
如果该属性不存在 则增加该属性
如果该属性存在 则修改该属性的值
删除一个属性节点
元素节点对象.removeAttribute("属性名")
获取属性节点的值:
元素节点对象.getAttribute("属性名")
如果属性节点不存在 则返回null
var box=document.getElementById("box");
var btn=document.getElementsByTagName("button")[0];
var btn1=document.getElementsByTagName("button")[1];
var firstTextNode=box.firstChild;
/*// 文本节点
console.log(firstTextNode.nodeType);
// 元素节点
console.log(box.nodeType);
// 返回当前元素节点中指定的属性节点(根据属性名获取)
var titleNode=box.getAttributeNode("title");
console.log(titleNode.nodeType);*/
btn.onclick=function () {
/* box.setAttribute("title","改成新的提示");
box.setAttribute("hahaa","呵呵")*/
// box.removeAttribute("title");
/* console.log(box.getAttribute("title"));
//
console.log(box.getAttribute("class"));*/
// box.setAttribute("location","底商37号")
// box.setAttribute("title","底商37号")
// box.setAttribute("class","haha")
// console.log(box.getAttribute("age"));
// box.setAttribute("qq","hehe")
// box.setAttribute("class","box")
}
btn1.onclick=function () {
// console.log(typeof box);
/*box.name="小强";
box.age=16;
box.show=function () {
console.log("请不要秀");
}
console.log(box.name);
console.log(box.age);
box.show();*/
// console.log(box.location);
// console.log(box.title);
// console.log(box.className);
// box.age=16;
box.qqq="哈哈";
}
关于对象属性和节点属性
* 关于对象属性和节点属性: * * * 对象就是对象的 * * * 节点就是节点 * * 完全没有半毛钱关系 * * * * box本身是一个内存中普普通通的一个对象 * 可以绑定属性 可以绑定方法 该怎么调用就怎么调用 * 跟原来我们一直操作的那个per 差不多 * * * 但是box还有一层身份 是一个页面的元素节点 * 那么作为元素节点 可以调用 dom那些属性 * 也就是元素节点带的那些属性 box.style * box.setAttribute * box.getAttribute * * 所以对象的操作就是对象的方式获取和设置 * * 元素节点的操作就用元素节点的方式获取和设置 * * 完全没有关系 * * * 但是 一些特殊的属性 是系统自动很好心的帮助我们获取了 * * 比如: box.title box.style box.id
nodeType nodeName nodeValue
元素节点 console.log("元素节点的nodeType:",box.nodeType); console.log("元素节点的nodeName:",box.nodeName); console.log("元素节点的nodeValue:",box.nodeValue); /* * nodeType是1 表示节点 * nodeName 返回当前元素节点标签名大写(有用!) * nodeValue 没用
文本节点 var textNode=box.firstChild; console.log("文本节点的nodeType:",textNode.nodeType); console.log("文本节点的nodeName:",textNode.nodeName); console.log("文本节点的nodeValue:",textNode.nodeValue); 文本节点的nodeType: 3 文本节点的nodeName: #text 文本节点的nodeValue: 都没用
属性节点 var attrNode=box.getAttributeNode("title"); console.log("属性节点的nodeType:",attrNode.nodeType); console.log("属性节点的nodeName:",attrNode.nodeName); console.log("属性节点的nodeValue:",attrNode.nodeValue); 属性节点的 nodeType是2 属性节点的nodeName是当前属性名 属性节点的nodeValue是当前属性值 所以nodeName和nodeValue是专门给属性节点用的