DOM 与 BOM
DOM
Document Object Model 文档对象模型
一.节点
1.节点属性
//=======结构=======
<body>
aaaa
<div id="div1">
<span></span>
<span></span>
<span></span>
</div>
<div>
<span></span>
<span></span>
<span></span>
</div>
</body>
a.nodeName
节点名 如果是标签 节点名就是标签名,大写
var div=document.getElementById("div1");
console.log(div.nodeName);//-----DIV
b.nodeType 节点类型
1.元素 2.属性 3.文本 4.注释 5.文档
c.nodeValue 节点值
文本内容和注释内容,标签没有节点值null
2.获取DOM元素
//===通过id获取元素列表
document.getElementById("div1");
//===通过class获取元素列表 HTMLCollection
document.getElementsByClassName("div");
//===通过标签名获取列表 HTMLCollection
document.getElementsByTagName("div")
//===通过name获取元素 大多数用于表单 NodeList 必须使用document
console.log(document.getElementsByName("name"))
//===可以通过选择器获取元素 如果有多个div使用选择器div时只能获取到列表中的第一个
document.querySelector("div.div1");
document.querySelector("div[type~=a]");
//===可以通过选择器获取所有元素列表 NodeList
document.querySelectorAll("div")
var div=document.getElementById("div1");
var span=div.getElementsByTagName("span");
console.log(span)
3.节点遍历
var div=document.getElementById("div1");
console.log(div.parentNode); 父节点
console.log(div.parentElement); 父元素
console.log(div.childNodes); 子节点 NodeList
console.log(div.children); 子元素 HTMLCollection
console.log(div.firstChild) 第一个子节点
console.log(div.firstElementChild) 第一个子元素
console.log(div.lastChild) 最后一个子节点
console.log(div.lastElementChild) 最后一个子元素
console.log(div.previousSibling) 上一个兄弟节点
console.log(div.previousElementSibling) 上一个兄弟元素
console.log(div.nextSibling) 下一个兄弟节点
console.log(div.nextElementSibling) 下一个兄弟元素
4.创建元素
把子元素添加在父元素的尾部
//====创建元素====
var div=document.createElement("div");
//===把子元素添加在父元素的尾部===
document.body.appendChild(div);
给ul里拼接10个li
var ul=document.createElement("ul");
for(var i=0;i<10;i++){
var li=document.createElement("li");
ul.appendChild(li);
}
document.body.appendChild(ul);
//===创建文档碎片
var a=document.createDocumentFragment();
//===循环
for(var i=0;i<100;i++){
var div=document.createElement("div");
a.appendChild(div);
}
document.body.appendChild(a);
将子元素插入到父元素的尾部
父元素.appendChild(子元素);
将元素插入在父元素中某个子元素的前面
父元素.insertBefore(新元素,插入在谁的前面);
// var div=document.createElement("div");
// document.body.insertBefore(div,document.body.firstChild);
复制元素
需要复制的元素.cloneNode(是否深复制));
//====深复制(true)--复制子元素 浅复制(false)--不复制子元素
var bn=document.querySelector("button");
var bn1=bn.cloneNode(true);
document.body.appendChild(bn1);
深复制 将该元素的节点和所有子节点及后代节点全部复制
浅复制 只复制当前元素
删除元素
元素.remove(); 删除
// bn.remove();
父元素.removeChild(子元素);
// document.body.removeChild(bn);
替换
父元素.replaceChild(新元素,旧元素);
// var p=document.createElement("p");
// document.body.replaceChild(p,bn);
二.DOM属性
div.innerHTML
获取 HTML 内容
设置 HTML内容
div.innerText
获取 获取当前元素的文本及后代的所有文本组成的字符串
设置 当使用\n和\r 会自动补充<br>换行
div.textContent
获取 可以获取到当前元素的文本及后代所有文本组成字符串及格式
设置 当使用\n和\r 并不会换行
document.createTextNode(文本) 创建文本节点
var txt=document.createTextNode("3"); div.insertBefore(txt,div.firstElementChild);
如果标签属性时系统自带的该标签的属性,这时候我们可以通过DOM对象调用该属性(除class以外)
<input type="text" id="input" class="divs">
var input=document.querySelector("#input");
console.log(input.type);
class 属性使用className获取和设置
console.log(input.className)
所有可以不用赋值的属性(属性名和属性值相同的)
<input type="text" id="input" value="123" name="textInput" disabled>
<input type="checkbox" checked>
disabled 和 checked,在DOM 对象中使用布尔值来设置和取消
var input=document.querySelector("#input");
input.disabled=true;
div.a=10;
console.dir(div)获取div得所有属性
自定义的也包括对象属性和标签属性,这两种自定义的属性,不共通
设置和获取标签属性
div.setAttribute(标签属性名,标签属性值)
获取标签属性
div.getAttribute(标签属性名);
删除标签属性
div.removeAttribute(标签属性名)
标签属性的命名和赋值要注意 使用-连接,不要写大写字母
document.title
document.body
document.documentElement
document.head
document.URL //地址
document.domain //域名
console.log(document.URL)
console.log(document.domain)
三.DOM样式
样式
CSS样式 行内样式
console.log(div.style.width) 获取div的行内样式属性
获取计算后样式
var style=getComputedStyle(div);
console.log(style.color)
//兼容低版本
console.log(div.currentStyle.color)
try catch
var width;
try{
// 试试
width=getComputedStyle(div).width;
}catch(e){
// 如果上面试试出错,执行下面的内容
width=div.currentStyle.width;
}
console.log(width)
设置行内样式
div.style="width:50px;height:50px;color:blue;background-color:red";
div.style.width="50px";
div.style.height="50px";
div.style.color="blue";
div.style.backgroundColor="red"
function cloneObj(target,source){
for(var key in source){
target[key]=source[key];
}
}
var div=document.querySelector("div");
cloneObj(div.style,{
width:"50px",
height:"50px",
backgroundColor:"red"
})
Object.assign(div.style,{
width:"50px",
height:"50px",
backgroundColor:"blue",
} as CSSStyleDeclaration)
需要删掉
四.DOM的对象属性
client 客户的
offset 偏移的
scroll 滚动条的
clientWidth clientHeight 内容+padding-滚动条轨道宽度
offsetWidth offsetHeight 内容+padding+border 实际占位宽高
scrollWidth scrollHeight 实际内容宽高,如果实际内容宽高小于client宽高时,等于客户宽高
body
如果内容宽度不超过html宽度时,三个值相同
如果内容宽度超过了html宽度时,clientWidth等于offsetWidth都是html宽度-滚动条滑道宽度
三个高度是完全一样的,都是内容高度
console.log(document.body.clientWidth,document.body.clientHeight)
console.log(document.body.offsetWidth,document.body.offsetHeight)
console.log(document.body.scrollWidth,document.body.scrollHeight)
html
clientHeight 可视区域高度-滚动条轨道高度
offsetWidth clientWidth 可视区域宽度
offsetHeight scrollHeight 内容高度
scrollWidth 内容宽度
console.log(document.documentElement.clientWidth,document.documentElement.clientHeight)
console.log(document.documentElement.offsetWidth,document.documentElement.offsetHeight)
console.log(document.documentElement.scrollWidth,document.documentElement.scrollHeight)
console.log(div3.clientLeft,div3.clientTop);//元素的边线粗细
console.log(div3.offsetLeft,div3.offsetTop);//距离父元素的左上角距离(父元素定位)
console.log(div2.scrollLeft,div2.scrollTop);
div2.scrollTop=300; //容器的滚动条位置 这个值是可读可写,其他属性都不可写只能读
console.log(div3.scrollTop)
早期版本中滚动条属于body,现在是html的
html的滚动条必须在页面渲染完成后才可以设置的,如果是元素的滚动条可以直接设置
document.body
document.documentElement
BOM
Browser Object Model 浏览器对象模型
浏览器中JS可以控制所有对象 这些对象都是从属于window对象
document 文档
location 本地
history 历史
screen 屏幕
navigator 导航
一.历史记录
location history screen navigator document
open()
打开新的窗口
open(“http://www.163.com”,“网易”,“width=200,height=200”);
close()
关闭窗口
clientWidth 与 clientHeight ,innerWidth 与 nnerHeight
document.documentElement.clientWidth 与 document.documentElement.clientWidth
***
视口宽高==html的clientWidth和clientHeight
console.log(innerWidth,innerHeight);//不考虑滚动条
console.log(document.documentElement.clientWidth,document.documentElement.clientHeight);//会减去滚动条
视口宽高和控制面板的宽高之和
console.log(outerWidth,outerHeight)
这两个值是相同的,都是指当前窗口距离屏幕左上角的坐标位置
console.log(screenLeft,screenTop)
console.log(screenX,screenY)
location.reload()
页面的重载
location.href , location.assign() 与 location.replace() ***
当页面没有第一次渲染完成前,他们三个都是跳转页面的作用,功能一样
document.οnclick=function(){
console.log(location.href)
location.href="http://www.163.com"//会产生历史记录,可以获取当前页面的地址,可以设置跳转页面的地址
location.assign("http://www.163.com")//会产生历史记录,只能设置跳转页面的地址
location.replace("http://www.163.com")//不会产生历史记录
}
***
location.hash
地址栏中#后面的内容,会产生历史记录
location.search
地址栏中?后面的内容
如果有hash,hash必须写在search后面
console.log(location.hash)
console.log(location.search)
document.onclick=function(){
可以赋值产生新的历史记录的
location.hash="#a";
}
地址的组成
hostname post pretocol pathname
screen对象(当前屏幕)
screen avail
screenWidth ScreenHeight
navigator.userAgent 获取浏览器内核版本
history.go()
1.跳转历史记录
2.刷新页面 -1 向后(back) 1向前 (fround)
history.length
历史记录长度(数量)
history.pushState()
history.pushState({a:1},“data”,"#a")添加历史记录
window.onpopstate = function(){}
监听浏览器历史记录的跳转。如果历史记录改变时,触发这个事件
SSR与CSR
SSR:服务器端渲染 CSR:客户端渲染
----案件–色块历史记录操作
<button>红色</button>
<button>蓝色</button>
<button>绿色</button>
<div id="red">1</div>
<div id="blue">2</div>
<div id="green">3</div>
<script>
var prev;
var bns=Array.from(document.querySelectorAll("button"));
var divs=document.querySelectorAll("div");
history.replaceState({num:0},"0");
changePrev(0);
for(var i=0;i<bns.length;i++){
bns[i].onclick=clickHandler;
}
window.onpopstate=popStateHandler;
function clickHandler(){
var index=bns.indexOf(this);
history.pushState({num:index},index);
changePrev(index);
}
function changePrev(index){
if(prev){
prev.style.display="none";
}
prev=divs[index];
prev.style.display="block";
}
function popStateHandler(){
// console.log(history)
changePrev(history.state.num);
}
</script>
//=====window.onpopstate=popStateHandler; 触发历史记录 执行方法
//=====history.replaceState({num:0},"0") 设置历史及内容
//=====history.state.num 取到历史记录里的内容
分解地址栏中地址
console.log(location.hostname)//域名
console.log(location.port)//端口号
console.log(location.protocol)//协议
console.log(location.pathname)//路径
screen 屏幕
下面两个都是屏幕宽高
console.log(screen.availWidth,screen.availHeight);//去掉附件(任务栏)屏幕宽高
console.log(screen.width,screen.height);//屏幕宽高--常用
navigator
console.log(navigator.userAgent)//浏览器版本及内核
二.Event 事件
事件主要有两个部分构成,一个是事件侦听,一个是事件触发 事件侦听又分为两个部分,一个是听到什么,一个是做什么
1、先侦听后派发事件
2、事件对象和事件目标对象,事件对象就是Event,事件目标对象EventTarget
3、事件的声音实际上就是一个字符串,我们把这个字符串叫做type,事件类型
派发的事件类型必须和侦听的事件类型完全相同时才能触发事件
4、有时候某些事件是由系统自动派发,不许我们主动派发事件,这种叫做系统默认
事件,我们主动抛发叫做自定义事件。 onclick onpopstate oninput系统
默认事件
// 创建一个事件目标
var target=new EventTarget();
// 事件侦听对象
target.addEventListener("chifanle",chifanleHandler);
// 创建一个事件,这个事件里面记录了chifanle这个声音
var evt=new Event("chifanle");
evt.a=10;
// 事件派发(事件抛发)
target.dispatchEvent(evt);
// 事件侦听执行的函数中有且仅有一个参数,这个参数,就是被派发的事件对象
function chifanleHandler(e){
console.log(e===evt);
console.log(e)
}
----案例-click的监听执行
//
// HTMLDivElement-->HTMLElement-->Element-->Node-->EventTarget-->Object
document.addEventListener("click",clickHandler);
var evt=new Event("click");
document.dispatchEvent(evt);
function clickHandler(e){
console.log(e)
}
this的指向
this
1、对象方法中的this,谁调用该方法,this就是谁
2、全局中的this是window
3、对象属性中使用this,因为对象没有创建完成,因为this就是执行对象
外的this指向
----案例- this指向的对象判断
var obj={
a:1,
b:function(){
// 对象方法中this,就是谁调用该方法,this就是谁
// console.log(this===obj);
// this就是当前这个对象
this.c();
},
c:function(){
console.log("ccc")
}
}
obj.b(); //---输出 ccc
obj.c(); //---输出 ccc
var o=obj;
obj={b:10};
o.b(); //---输出 ccc
//虽然o,obj的引用地址被改变,但是原引用地址的变量并没有被销毁。所以o.b不会报错。
var a=2;
console.log(this.a); //===== 等同于window.a = 2
var o={
a:1,
b:this.a,//当前对象没有创建完成,所以this指向当前对象外的this指向
c:function(){
console.log(this.b);
}
}
o.c(); //====输出a=2
使用Event事件解耦
var o1={
a:1,
b:function(){
var evt=new Event("abc");
evt.a=this.a;
document.dispatchEvent(evt);
}
}
var o2={
c:2,
init:function(){
document.addEventListener("abc",this.d);
},
d:function(e){
console.log(e);
}
}
o2.init();
o1.b();