DOM概念:Document Object Model
提供了专门用于操作HTML文档的API
DHTML:动态的HTML,一切实现网页动态效果的技术的统称,并不是什么新技术、新概念,仅仅只是一个统称
HTML+CSS+JS(DOM)
面试/鄙视题:HTML/XHTML/DHTML/XML:
HTML:网页
XHTML:更严格的网页
DHTML:动态的网页
XML:数据格式
BOM:Browser Object Model
提供专门用于操作浏览器的API
没有标准,但是大部分浏览器厂商已经统一的实现了,除了老IE,具有大量的兼容性问题,使用的较少(重点:定时器、event事件)
DOM:本来是可以操作一切结构化文档(HTML/XML)的:3部分
1、核心DOM:万能!但是API比较繁琐:elem.setAttribute("属性名","属性值")
2、HTML DOM:只能操作HTML文档,API非常的简单:elem.属性名=值;
3、XML DOM:XML基本已经淘汰很多年了
建议:以后优先使用HTML DOM,HTML DOM实现不了,在用核心DOM补充
2、***DOM树:保存所有网页内容的树状结构:树根:document,不需要创建,由浏览器的js解释器自动创建,一个页面只有一个树根
DOM节点/对象/元素:一个标签、文本、属性、注释等等
每个DOM节点/对象/元素都有三大属性:
1、xx.nodeType:获取xx的节点类型
document:9
元素标签:1
文本节点:3
属性节点:2
对于现在的开发者,没用
2、属性节点.nodeValue:获取属性节点的节点值
现在依然没用:我们现在用getAttribute("")能直接获取到属性的值
3、***xx.nodeName:获取属性节点的名称:
我直接找儿子的话,可能找到多种标签,但是我们希望对不同的标签执行不同的操作
特殊:获取出来的标签都是全大写
3、通过 节点之间关系 获取元素:
1、父:elem.parentNode;
2、子:elem.children; - 集合:只能找到儿子级
3、第一个儿子:elem.firstElementChild;
4、最后一个儿子:elem.lastElementChild;
5、前一个兄弟:elem.previousElementSibling;
6、后一个兄弟:elem.nextElementSibling;
4、*****递归:函数中,再一次调用函数自己
作用:专门用于【遍历层级不明确的树状结构】
如何实现:
1、创建函数,传入实参树根,形参接住,直接做第一层要做的操作
function f1(root){
直接做第一层要做的操作
//判断自己有没有下一级,如果有再次调用此方法,但传入的实参已经变成了你的下一级
}
2、调用函数
f1(实际的根元素)
算法:深度优先!优先遍历当前节点的子节点
子节点遍历完,才会跳到兄弟节点
递归:优点:直观,易用
缺点:效率较低,同时开启的函数很多,占用内存空间,不是任何时候都要使用 - 几乎不担心(【遍历层级不明确的树状结构】)
循环:优点:效率较高
缺点:难度极大!
5、遍历API:专门用于【遍历层级不明确的树状结构】
1、创建treewalker对象
var tw=document.createTreeWalker(root,NodeFilter.SHOW_ALL/SHOW_ELEMENT);
2、反复调用nextNode方法:
while((node=tw.nextNode())!=null){
node;//当前节点做什么操作
}
深度优先算法
注意:此方法必须跳过起点
6、纯循环遍历层级不明确的树状结构 - 别用
总结:以后不用遍历API(只能遍历页面元素),也不用纯循环(难度大),遇到层级不明确的时候,使用递归(不仅遍历元素,还能遍历数据)
7、***查找元素:
1、按照HTML的特点去查找元素:
var elem=document.getElementById("id");
找到了是单个元素,没找到一定是null
var elem=document.getElementsByTagName/ClassName/Name("标签/class名/name值")
找到了是个集合,没找到一定是一个空集合[]
2、按照CSS选择器进行查找:
1、单个元素,没找到一定是null,如果有多个,也只会找到第一个
var elem=document.querySelector("任意css选择器")
2、多个元素:找到的是一个集合,没找到空集合
var elem=document.querySelectorAll("任意css选择器")
面试题:getXXX和querySelectXXX的区别?
1、返回结果不同:
getXXX - 返回是一个动态集合(每次DOM树修改,都会悄悄的再次查找)
querySelectXXX - 返回是一个静态集合 (每次DOM树修改,不会再次查找,只管第一次找到的结果)
2、动态集合,不支持forEach
静态集合,支持forEach
3、复杂查找时,尽量使用var elem=document.querySelectorAll("任意css选择器")
操作元素
内容:
1、innerHTML:支持标签,并且没有兼容性问题
获取:elem.innerHTML;
设置:elem.innerHTML="新值";
2、textContent:不支持标签,并且有兼容性问题,老IE:innerText,只不过小三上位(老IE不支持textContent,主流浏览器都支持innerText)
获取:elem.innerText;
设置:elem.innerText="新值";
3、value:转为input、select准备的
获取:elem.value;
设置:elem.value="新值";
2、*属性:
获取属性值:
核心DOM:万能的,可以操作一切属性
elem.getAttribute("属性名");
HTML DOM:只能操作标准属性,并且class需要写出className
elem.属性名;
设置属性值:
核心DOM:万能的,可以操作一切属性
elem.setAttribute("属性名","值");
HTML DOM:只能操作标准属性,并且class需要写出className
elem.属性名="新值";
删除属性:
*核心DOM:elem.removeAttribute("属性名"); - 删干净整个属性节点
HTML DOM:elem.属性名=""; - 赋值为空,删不干净,属性值确实没了,但属性名还在,有的属性只需要属性名也具有效果(href、disabled、readonly)
判断属性:只能判断有没有
核心DOM:elem.hasAttribute("属性名");
个人更推荐:if(a1.getAttribute("属性名")=="属性值"){
console.log("有并且是");
}
3、样式:
内联:优先级最高,只会操作某个元素,不会牵一发动全身
获取:elem.style.css属性名;
设置:elem.style.css属性名="css属性值";
css属性名如果有横线,去掉横线写为小驼峰命名法
样式表:
//获取哪一个样式表
var sheet=document.styleSheets[1];
//获取所有的样式规则
var rules=sheet.cssRules;
//获取到了我想要操作的样式规则
var rule=rules[36];
//修改或获取样式
console.log(rule.style.background);
rule.style.background="purple";
一切的获取都是为了判断比较
一切的设置都是在做修改操作
创建元素&渲染页面&删除元素:
创建元素:
1、var 空标签=document.createElement("标签名");
2、设置必要的属性或事件
空标签.属性名="值"
空标签.on事件名=function(){
操作
}
3、渲染页面元素:
*父元素.appendChild(新元素);//新元素会插入到父元素里面的末尾
父元素.insertBefore(新元素,已有子元素);//新元素会插入到父元素里面的已有子元素之前 - 不推荐:修改其他的下标
父元素.replaceChild(新元素,已有子元素);//新元素会替换掉父元素里面的已有子元素
4、删除元素:
元素.remove();
核心DOM学习完毕: - 增 删 改 查:元素、内容、属性、样式
2、HTML DOM提供了一些常用对象:简化了核心DOM的操作:但是不是人人都能简化
1、image:简化了创建
var img=new Image();
强调:在DOM中,不是人人都具有构造函数创建方式
2、form:简化了查找
查找form元素:var form=document.forms[i];
查找表单控件:var input=form.elements[i];
专属事件:onsubmit事件 -> 提交的一瞬间会执行,也可以阻止提交return false;
3、*select:
属性:2个
1、options === children:获取到select下面的所有的option
2、*selectedIndex - 获取到当前选中项的下标,只要是做联动,必不可少
方法:
1、*select.add(option) - 完全等效于appendChild,追加元素
2、select.remove(i); - 删除select中的第i个option
专属事件:onchange-> 选中项发生改变时触发
4、*option:简化了创建
var opt=new Option("innerHTML","value");
5、str.trim();//去掉字符串的开头结尾的空白字符
6、var bool=confirm("提示文字");//用户确认框
用户点击确定->true
用户点击取消->false
BOM:Browser Object Model
浏览器 对象 模型
提供了专门用于操作浏览器的API - 没有标准,使用的较少,但大部分浏览器厂商已经统一实现了(老IE)
BOM对象:*window(定时器)、history、*location、navigator、*****event、screen...
window对象:扮演了2个角色:
1、浏览器中,window代替了ES的Global充当全局作用域
包含了所有的全局对象、变量、函数
2、指代当前浏览器的窗口
*网页打开新链接的方式
提升用户的体验感:
1、替换当前页面,可以后退:
HTML:<a href="url">文字</a>
JS:open("url","_self");
2、替换当前页面,禁止后退:使用场景:电商网页:结账完毕后,不允许用户后退
history对象:保存了当前窗口的历史记录,功能:前进后退
location:保存了当前窗口正在打开的url
location.replace("新url");//替换当前网址、不会产生历史记录
3、在新窗口打开,可以打开多个:
HTML:<a href="url" target="_blank">文字</a>
JS:open("url","_blank");
4、在新窗口打开,只能打开一个:使用场景:电商网页:跳转到 支付结账页面,只允许用户打开一个
HTML:<a href="url" target="自定义">文字</a>
JS:open("url","自定义");
自定义:窗口的底层都有一个名字,如果出现重复的名字则新窗口会替换掉原来的旧窗口
扩展:a标签可以做的事?
1、跳转
2、锚点
3、下载:<a href="xx.rar/zip/exe">文字</a>
4、打开图片、txt:<a href="xx.图片后缀/txt">文字</a>
5、直接书写js:<a href="javascript:js代码;">文字</a>
2、window对象:属性和方法:
属性:
获取浏览器窗口的大小:
文档显示区域的大小:body部分
innerWidth/innerHeight
完整的浏览器大小:
outerWidth/outerHeight
屏幕的大小:没用 - 桌面应用才用的
screen.width/height
方法:
1、打开新窗口:var newW=open("url","自定义name","width=,height=,left=,top=");
特殊:如果没传入第三个参数,新窗口会和浏览器并为一体
如果传入第三个参数,新窗口会脱离浏览器
建议宽高不小于200
有可能会被浏览器拦截
2、关闭窗口:窗口.close();
3、修改窗口的大小:新窗口.resizeTo(newW,newH);
4、修改窗口的位置:新窗口.moveTo(x,y);
获取鼠标的坐标:
1、事件中传入一个形参e->获得到事件对象event(其中一个作用获取鼠标的坐标)
2、获取:
e.screenX/Y;//相对于屏幕
e.clientX/Y;//相对于浏览器客户端
*e.pageX/Y;//相对于网页的
鼠标跟随效果:关键点:
1、绑定事件:window.onmousemove
2、图片位置一定和鼠标位置一起
3、图片的加载速度比js的执行速度要慢,img.onload=function(){
//最后才会执行
}
*****定时器:2种
1、周期性定时器:先等待,在执行一次,在等待,在执行一次...
开启:timer=setInterval(callback,间隔毫秒数);
停止:clearInterval(timer);
2、一次性定时器:先等待,在执行一次,结束
开启:timer=setTimeout(callback,间隔毫秒数);
停止:clearTimeout(timer);
两种定时器底层相同,可以互换