DOM
- 什么是window? window是一个全局对象 指浏览器中的每个窗口就是window对象
-
什么是document? document是window的一个属性,也是一个对象,通过document可以操作页面上的内容,是指浏览器显示内容的区域
什么是DOM?
DOM定义了操作和访问html文档的标准方法
DOM全称: Document Object Model, 即文档模型对象
所以学习DOM就是学习如何通过document对象操作网页上的内容
获取DOM元素
document.getElementById() ; 通过Id获取指定元素
由于id不可以重复, 所以找到了就会将找到的标签包装成一个对象返回给我们, 找不到就返回Null
注意点: DOM操作返回的是一个对象, 这个对象是宿主类型对象(浏览器提供的对象)document.getElementsByClassName(); 通过类名获取指定元素
由于class可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组document.getElementsByTagName(); 通过标签名获取指定元素
由于class可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组document.getElementsByName();通过name名获取指定元素
由于name可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
注意点:
getElementsByName 在不同的浏览器其中工作方式不同。在IE和Opera中, getElementsByName() 方法还会返回那些 id 为指定值的元素。
重点掌握
- document.querySelector(); 通过选择器获取(会根据指定选择器拿到第一个元素)
- document.querySelectorAll(); 通过选择器获取(根据指定选择器获取所有的元素)
- 获取指定元素的所有子元素
两种属性可以获取: 1. children(拿到所有子元素标签) 2.childNodes(拿到所有节点)
<div class="box" id="div1">
<p>box1</p>
<form action="">
<input type="text" name="sex">
<input type="text" name="sex">
</form>
</div>
let odiv = doucument.querySelector(".box");//将返回的对象放在oDiv中
console.log(oDiv.children); //打印出所有子元素
什么是节点?
DOM对象,通过树的形式保存了页面上所有的内容
HTML页面上的每一个部分都是一个节点(属性,标签,文本)。
节点
let odiv = doucument.querySelector(".box");
console.log(oDiv.childNodes);// 拿出所有节点
如果只要拿出标签怎么办
for(let node of oDiv.childNodes) {//node 中有个nodeType属性
//console.log(oDiv.childNodes); //标签对应的nodeType为1,文本为3
//if( node.nodeType ===1) {
if(node.nodeNodes === Node.ELEMENT_NODE){ //专业写法
console.log(node); //拿到标签
)
- 获取指定节点中的第一个子节点
let odiv = doucument.querySelector(".box"); //拿到指定子节点
console.log(oDiv.firstChild);// 拿出第一个节点 - 获取指定节点中的第一个子标签
console.log(oDiv.firstElementChild);// 拿出第一个标签 - 获取指定节点中的第一个子节点
console.log(oDiv.lastChild);// 拿出最后一个节点 - 获取指定节点中的第一个子标签
console.log(oDiv.lastElementChild);// 拿出最后一个标签 - 通过子元素获取父元素/ 父节点
console.log(oDiv.parentElement); // 返回父元素(火狐低版本不支持)
console.log(oDiv.parentNode); //火狐支持
let parentEle = oDiv.parentElement || oDiv.parentNode //兼容性处理(通过子元素获取父元素) - 获取相邻上一个节点
console.log(oDiv.previousSibling);
获取相邻上一个元素(标签)
console.log(oDiv.previousElementSibling); - 获取相邻下一个节点
console.log(oDiv.nextSibling);
获取相邻下一个元素(标签)
console.log(oDiv.nextElementSibling);
节点增删改查
- 创建节点
let Ospan = document.createElement("span"); - 添加节点
注意点: appendChild方法会将指定的元素添加到最后
let Ospan = document.createElement("span");
let oDiv = document.querySelector("div");
oDiv.appendChild(oSpan); //将span添加到选中的div中,默认添加到最后 - 插入节点
let oSpan = document.createElement("span");
let oDiv = document.querySelector("div");
let oH1 = document.querySelector("h1");
oDiv.insertBefore(oSpan,oH1); // 将span添加到h1之前 - 删除节点
只能通过父节点删除(不能自己删除自己);removeChild(); //删除指定节点
let oSpan = document.querySelector("span");
console.log(oSpan.parentNode); //拿到span的父节点
oSpan.parentNode.removeChild(oSpan); 通过span的父元素删除span - 克隆节点
注意:cloneNode方法默认不会克隆子元素,如果需要克隆子元素,则需要传入一个参数 true
let oDiv = document.querySelector("div");
//oDiv.cloneNode(); //不会克隆子元素
let newDiv = oDiv.cloneNode(true); //克隆子元素
console.log(newDiv);
属性增删改查
<div class="box" id="div1" wj="666">
</div>
- 获取元素属性
let oDiv = document.querySelector("div");
console.log(oDiv.id); // div1
console.log(oDiv.getAttribute("wj")); // 666
oDiv.id与oDiv.getAttribute("wj")的区别 前者不能获取自定义的属性,后者可以
- 如何修改元素属性
let oDiv = document.querySelector("div");
oDiv.id = "box" ; //将id的值改为box
oDiv.setAttribute("wj","888"); //将“wj”的值改为888(第一个参数为需要更改的属性,第二个参数为修改的值)
两种方式的区别: 前者不能更改自定义属性,而后者可以 - 如何新增元素属性
let oDiv = document.querySelector("div");
oDiv.setAttribute("ww","9527"); //只有这一种方法
setAttribute方法如果属性不存在就是新增, 如果属性存在就是修改 - 如何删除元素属性
let oDiv = document.querySelector("div");
oDiv.id = "" ; //将id的值清空 ,但会保留属性名称
oDiv.removeAttribute("wj"); //会将属性名称也删掉
前者不能删除自定义属性,而后者可以
元素内容操作
- 获取元素内容(3种方式)
- innerHTML // 获取的内容包含标签和空格
- innerText //只获取内容不包含标签和空格
- textContent //获取内容包含空格但不包含空格
let oDiv = document.querySelector("div");
console.log(oDiv.innerHTML);
console.log(oDiv.innerText);
console.log(oDiv.textContent);
- 设置元素内容
用innerHTML/innerText /textContent 设置内容,都会将原有的内容覆盖
innerHTML设置内容,内容中包含标签,会转化成标签再添加
innerText /textContent 设置内容,会将标签当做字符串直接设置
let oDiv = document.querySelector("div");
oDiv.innerHTML = "123";
oDiv.innerText = "wfwf";
oDiv.textContent = "wj666";
兼容性处理 可以定义一个函数来解决
let oDiv = document.querySelector("div");
function setContent(obj,text) {
if("innerText" in obj){ //判断obj对象中是否存在innerText属性
obj.innerText = text;
}
else{
obj.textContent = text;
}
}
操作元素样式
-
设置元素样式
第一种方式 通过绑定类名
<style>
.box {
width: 300px;
height: 300px;
background: #000;
}
</style>
let oDiv = document.querySelector("div");
// 注意点: 由于class在JS中是一个关键字, 所以叫做className
// oDiv.className = "box";
第二种方式
// 注意点: 过去CSS中通过-连接的样式, 在JS中都是驼峰命名
// 注意点: 通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式
let oDiv = document.querySelector("div");
oDiv.style.width = "200px";
oDiv.style.height = "200px";
oDiv.style.backgroundColor = "red";
-
获取元素样式
let oDiv = document.querySelector("div");
oDiv.style.width = "300px";
console.log(oDiv.style.width);
通过style属性只能过去到行内样式的属性值, 获取不到CSS设置的属性值
如果想获取到CSS设置的属性值, 必须通过getComputedStyle方法来获取
etComputedStyle方法返回一个对象, 这个对象中就保存了CSS设置的样式和属性值let style = window.getComputedStyle(oDiv);
console.log(style.width); //获取css设置的属性值
事件
什么是事件? 是指用户和浏览器之间的交互行为 比如鼠标单击 移入移出 等
在JavaScript中所有的标签都可以绑定事件
如何给标签绑定事件
格式 : 元素.事件名 = function(){
事件被触发需要执行的内容
}
当事件被触发时,就会执行function中的代码
有些标签系统默认会绑定事件,如a标签 就绑有点击事件
如果再给a标签绑定点击事件,不会覆盖系统绑定的事件,运行时会先执行我们绑定的事件,然后再执行系统执行的事件
let oA = document.querySelector("a");
oA.onclick = function (){
alert("我先执行");
//return false ; //会覆盖系统绑定的事件
}
如果需要覆盖系统绑定的事件,只要在函数的最后写上 return false 即可
定时器
定时器的作用就是隔一段时间再执行(和定时关机效果一样)
定时器分为 重复执行的定时器 和 只执行一次的定时器
定时器的用法
重复执行的定时器
window.setInterval(function () {} , 1000);
//第一个参数是需要执行的内容,第二参数是间隔时间,单位是毫秒
定时器会返回一个值,将这个值清空定时器就会停止
let oBtn = document.querySelector(".start");
let id = null; //定义一个变量接收定时器返回的数值
oBtn.onclick = function () {
id = window.setInterval(function(){
console.log(123); },1000)// 等待1000ms然后打印123
}
let oBtn1 = document.querySelector(".close");
oBtn1.onclick = function() {
clearInterval(id); //清空id的值,停止定时器
}
只执行一次的定时器
let oBtn = document.querySelector(".start");
let id = null; //定义一个变量接收定时器返回的数值
oBtn.onclick = function () {
id = window.setTimeout(function(){
console.log(123); },1000)// 等待1000ms然后打印123
}
let oBtn1 = document.querySelector(".close");
oBtn1.onclick = function() {
clearTimeout(id); //清空id的值,停止定时器
}
ES6箭头函数和普通函数的区别
ES6箭头函数中this指向的是他父作用域的this(并不是调用他的函数)
普通函数中this指向的调用函数的对象
let obj = {
name : "wj" ,
say : function() {
console.log(this);
},
speak : () => {console.log(this);}
}
obj.say();// 结果 obj对象
obj.speak();// 结果 window
普通函数中this的指向可以通过call等方法改变
箭头函数中this的指向无法改变
class Person{
constructor(){
this.name = "wj";
}
say(){
console.log(this);
}
speak = () => {
console.log(this);
}
}
class Son{
constructor(){
this.name = "wj666";
}
say(){
console.log(this);
}
speak = () => {
console.log(this);
}
}
let obj = new Person();
let objj =new Son();
obj.say(); // Person
obj.say.call(objj); // Son (使用call方法改变了this)
obj.speak.call(objj);// Person (使用call并没有改变this的指向)
闭包
- 闭包也是一种函数
- 如何实现闭包: 两个要求:(1)、函数嵌套 (2)、内部的函数要引用外部函数的数据
- 闭包的特点: 延长了局部变量的生命周期
- 注意: 如果后期不使用闭包,要手动设置闭包为null 否则会出现内存泄漏
- ES6中{}是一个块级作用域,在这个块级作用域定义了一个函数并且引用了外部块级作用域的数据,这个函数就是一个闭包。
for( let i = 0;i<10;i++){
function f() { //闭包
console.log(i + 1);
}
}
f(); //10 (后面的父f()将前面的f覆盖了)