js知识点梳理-DOM+BOM

201 阅读5分钟

DOM树:把html结构看作是一个倒挂的树状结构,树根则为document对象(有属性和方法)

document对象不需要创建,由浏览器的js解释器自动创建,且一个页面只有一个document

Document Object Model 提供了专门操作HTML文档的API

DOM

1.概念

DHTML:动态的HTML,一切实现网页动态效果的技术的统称。DHTML=HTML+CSS+JS(DOM)

HTML/XHTML/DHTML/XML
HTML:超文本标记语言,网页
XHTML:可扩展超文本标记语言,更严格的网页
DHTML:动态网页
XML:数据格式

DOM:本来可以操作一切结构化文档(XHTML/XML),分为三部分:

  • 核心DOM:万能,但API繁琐
  • HTML DOM:只能操作HTML文档,API简单
  • XML DOM

2.DOM树

保存所有网页内容的树状结构,树根(document)不需要创建,由浏览器的js解释器自动创建

DOM节点/对象/元素:一个标签、文本、属性、注释等

每个阶段都有三大属性:

  1. xx.nodeType 获取xx的节点类型

document(9)、文本节点(3)、属性节点(2)、元素标签(1)

  1. xx.nodeValue 获取属性节点的节点值
  2. xx.nodeName 获取属性节点的名字
  • 应用:直接找自带可能找到多个标签,但想对不同标签做对应操作
  • 注意:获取到的标签名都是大写

3.通过节点关系获取元素

  • 子元素找父元素: xx.parentNode(单个元素)
  • 父元素找子元素: xx.children(集合)
  • 父元素找第一个子元素: xx.firstElementChild(单个元素)
  • 父元素找最后一个子元素: xx.lastElementChild(单个元素)
  • 前一个兄弟元素 xx.previousElementSibling(单个元素)
  • 后一个兄弟元素 xx.nextElementSibling(单个元素)

4.递归

函数中,再次调用自己,但会让它停下来

  • 作用:专门用于遍历层级不明确的树状结构
  • 步骤:
    1. 创建函数,传入实参树根,形参接住,直接做第一层的操作 function f1(root){第一层操作}

    2. 调用函数 f1(实际的根元素)

//例:给表格添加边框
function getChildren(root){
    root.style.border="solid 1px #000";
    for(var i=0;i<root.children.length;i++){
        getChildren(root.children[i]);
    }
}
  • 算法:深度优先,优先遍历当前节点的子节点,子节点遍历完才会跳到兄弟节点
  • 递归优点:直观易用
  • 递归缺点:效率低,占内存空间。用于遍历层级不明确的DOM

5.遍历API

用于遍历层级不明确的树状结构,步骤:

  1. 创建treewalker对象 var tw=document.createTreeWalker(root,NodeFilter.SHOW_ALL)

var tw=document.createTreeWalker(root,NodeFilter.SHOW_ELEMENT)找元素

  1. 反复调用nextNode方法 while((var node=tw.nextNode())!=null){node;//当前节点做什么操作}

注意:深度优先算法,此方法必须跳过起点

6.纯循环遍历层次不明确的树状结构

不用遍历API(只能遍历页面元素);也不用纯循环遍历(难度大);遇到层级不明确时,使用递归(不仅遍历元素,还遍历数据)

7.获取元素

通过html的属性获取元素

  • id: var elem=document.getElementById("id");
    • 返回的是DOM对象,可直接操作
    • 若id重复,只返回第一个
    • 若未找到id,返回null
  • 标签名: var elems=document.getElementsByClassName("标签名");
  • class: var elems=document.getElementsByClassName("class");
    • 返回的时DOM集合,不可以直接操作:添加下标可以得到某个对象/遍历 则可以操作
    • 若未找到,返回空集合
    • 该方法可以使用parent(已找到的某个父元素)
  • namevar elems=document.getElementsByName("name");

通过节点之间的关系获取元素

前提:先找到一个元素,才能找到对应关系

  • 子元素找父元素: xx.parentNode(单个元素)
  • 父元素找子元素: xx.children(集合)
  • 父元素找第一个子元素: xx.firstElementChild(单个元素)
  • 父元素找最后一个子元素: xx.lastElementChild(单个元素)
  • 前一个兄弟元素 xx.previousElementSibling(单个元素)
  • 后一个兄弟元素 xx.nextElementSibling(单个元素)

按css选择器进行查找

  • 单个元素:未找到时null,多个元素只会找到第一个 var elem=document.querySelector("任意css选择器");
  • 多个元素:找到是一个集合,未找到时一个空集合 var elems=document.querySlectorAll("任意css选择器");

getxx和querySelectorxx的区别:

  1. 返回结果不同
    • get:返回的时一个动态集合(DOM树每次被修改,都会再次查找)
    • querySelector:返回的是一个静态集合(DOM树每次被修改,不会再次查找,只管第一次找到的结果)
  2. 动态集合:不支持forEach;静态集合:支持forEach(类数组)
  3. 复杂查找时,使用querySelectorAll

8.操作元素

一切的获取都是为了判断,一切的设置都是为了修改

内容

  • innerHTML 用于操作双标签,能识别标签
    • 获取:elem.innerHTML
    • 设置:elem.innerHTML="新内容";
  • innerText 用于操作双标签,不能识别标签value
    • 获取:elem.innerText
    • 设置:elem.innerText="新内 容";
  • value 用于操作input
    • 获取:elem.value
    • 设置:elem.value="新内容";

属性

  • 获取:
    • 核心DOM:elem.getAttribute("属性名");
    • HTML DOM:elem.属性名
  • 设置:
    • 核心DOM:elem.getAttribute("属性名","属性值");
    • HTML DOM:elem.属性名="属性值";
  • 删除属性值:会删除整个属性节点
    • 核心DOM:elem.removeAttribute("属性名");
    • elem.属性名="";赋值为空,但未删除。有的属性仅有属性名也具有效果(disable、href)
  • 判断属性值:只能判断有无属性
    • 核心DOM:elem.hasAttribute"属性名"
    • if(elem.getAttribute("属性名")==值){}
  • 注意:
    • class在js里面是关键字,所以要写成className
    • 自定义属性只能用DOM操作

样式

  • 内联样式表
    • 获取:elem.style.css属性名;
    • 设置:elem.style.css属性名="css属性值";
    • 注意:
      • 优点:1.优先级最高,保证了用户触发一定会生效;2.只会操作当前元素
      • 缺点:获取样式时,一定要保证此样式在内联样式表里面
      • css属性名中若有横线需要去掉,改为小驼峰命名法
  • 内部/外部样式表:document.styleSheet[i].cssRules[i].style.background
    • 获取样式表 var sheet=document.styleSheet[i];
    • 获取样式规则 var rules=sheet.cssRules;
    • 获取想要的操作 var rule=rules[i];
    • 获取或修改样式 rule.style.background="pink";

9.创建元素&渲染页面&删除元素

  • 创建元素
    • var 空标签=document.createElement("标签名");
    • 设置必要属性和方法
      • 空标签.属性名="属性值";
      • 空标签.on方法=function(){}
  • 渲染页面
    • 添加:父元素.appendChild(新元素);新元素会插入到父元素最后
    • 插入:父元素.insertBefore(新元素,已有子元素);新元素会插入到已有子元素之前
    • 替换:父元素.replaceChild(新元素,已有子元素);新元素会替换已有子元素
  • 删除元素 元素.remove

10.HTML DOM 提供的对象

简化部分核心DOM操作

image

简化创建var img=new Image();

  • 在DOM中,不是人人都有构造函数创建方式

form

  • 简化查找元素 var form=document.forms[i];
  • 简化查找表单控件 var input=form.elements[i]
  • 专属事件 onsubmit提交时触发,可阻止提交return false

select

  • 专属事件 onchange选中项发生改变时触发
  • 属性
    • options===children 获取到select下所有option
    • selectedIndex 获取到当前选中项下标
  • 方法
    • select.add(option) 获取到select下所有option
    • select.remove(i) 删除select中第i个option

option

  • 简化创建 var opt=new Option("innerHTML","value");

select.add(new Option("innerHTML","value"))

BOM

Browser Object Model 浏览器对象模型:提供了专门用于操作浏览器的API(没有标准,且使用较少。大部分浏览器厂商已统一实现,除老IE)

BOM对象:window、history、location、navigator、event、screen...

1.window对象

  • 浏览器中,window代替了ES的Global,充当全局作用域(包含了所有全局对象、变量、函数)
  • 指代了当前浏览器的窗口

网页打开新链接的方式

  • 替换当前页面,可以后退
    • HTML <a href="#">链接</a>//默认target="_self"
    • js:先添加点击事件 open("url","_self")
  • 新窗口打开,可以打开多个
    • HTML <a href="#" target="_blank">链接</a>
    • js:先添加点击事件 open("url","_blank")
  • 新窗口打开,只能打开一个【应用:支付结账窗口】
    • HTML <a href="#" target="自定义">链接</a>
    • js:先添加点击事件 open("url","自定义")
  • 替换当前页面,禁止后退【应用:结账完毕后,不允许后退】
    • js: location.replace(新url)//替换当前网址,不会产生历史记录
      • history对象 保存了当前窗口的历史记录,功能:前进后退
      • location 保存了当前窗口正在打开的url

window对象

  • 获取浏览器窗口的大小 + 屏幕的大小 screen.width/height + 完整浏览器的大小 outerWidth/outerHeight + 文档显示区域的大小 innerWidth/innerHeight
  • 方法:
    • 打开新窗口 open("url","自定义name","width=,height=,left=,top=");
      • height、width 没有单位,宽高设置不小于200
      • 若未传入参数3,新窗口会和浏览器并为一体
      • 若传入参数3,新窗口会脱离浏览器,可能会被浏览器拦截
    • 关闭窗口 窗口.close();
    • 修改窗口大小(只能用于新窗口) 新窗口.resizeTo(宽,高);
    • 修改窗口位置 新窗口.moveTo(x,y)
  • 定时器
    • 周期性定时器(先等待,再执行一次)重复
      • 开启 timer=setInterval(function(){},毫秒数)
      • 停止 clearInterval(timer)
    • 一次性定时器(先等待,再执行一次)
      • 开启 timer=setTimeout(function(){},毫秒数)
      • 停止 clearTimeout(timer)

窗口底层都有一个名字,若出现重复的名字则新窗口会替换掉原来的窗口

2.history

保存了当前窗口的历史记录

  • 前进 history.go(1)
  • 后退 history.go(-1)
  • 刷新 history.go(0)

3.location

保存了当前窗口正在打开的url

一个url由5部分组成

  • 协议:http/https/ftp/ws
    • http/https 请求响应模式,https安全性更高
    • ftp 传输文件
    • ws 广播收听模式(直播)
  • 主机号/域名 127.0.0.1/www.baidu.com
    • 主机号不便于记忆,企业会选择购买域名
  • 端口号
    • http 80
    • https 443
  • 文件的相对路径
  • 查询字符串:表单提交到服务器内容,请求信息

属性

url5部分相关,使用console.log(location)控制台查找使用

API

  • 跳转
    • location="新url"
    • location.href="新url"
    • location.assign("新url")
  • 替换后禁止后退 location.replace("新url")
  • 刷新 location.reload()

4.navigator

保存了当前浏览器的信息(浏览器版本号/名称)

navigator.userAgent根据字符串截取浏览器名称、版本号:本身目的是做兼容,但未使用,因为API都已经设置好兼容

5.event

事件:由用户触发或浏览器自动触发的事件

绑定事件

1.直接在html元素上绑定 <elem on事件名="js语句"></elem>

  • 缺点:
    • 没有实现js与html的分离
    • 无法动态绑定事件
    • 无法同时绑定多个函数对象

2.使用js的事件属性绑定 elem.on事件名=function(){js语句}

  • 优点:
    • js与html的分离
    • 动态绑定事件
  • 缺点:无法同时绑定多个函数对象

3.使用js的API属性绑定 elem.addEventListener("事件名",function(){})

  • 优点:
    • js与html的分离
    • 动态绑定事件
    • 同时绑定多个函数对象
  • 缺点:兼容性问题
    • IE elem.attachEvent("on事件名",function(){})
if(elem.addEventListener){
    elem.addEventListener("事件名",function(){})
}else{
    elem.attachEvent("on事件名",function(){})
}

事件周期

  • 主流
    • 捕获阶段:由外向内,记录着要执行的事件
    • 目标触发阶段:当前点击的元素优先触发
    • 冒泡触发:由内向外
  • 老IE 和主流相比无捕获阶段
    • 目标触发阶段:当前点击的元素优先触发
    • 冒泡触发:由内向外

获取到事件对象event

  • 主流 事件函数中传入参数e,就可以自动接住对象event
  • 老IE window.event
  • 兼容 window.event
  • 应用
  1. 获取鼠标的位置 e.screen/client/page
  2. 阻止冒泡
  • 主流:e.stopPropagation()
  • 老IE:e.cancelBubble=true
  • 兼容:
    if(e.stopPropagation){
        e.stopPropagation();
    }else{
        e.cancelBubble=true;
    }
    
  1. 事件委托/利用冒泡 优化,每绑定一个事件,就相当于创建了一个事件监听对象,创建对象越多,网页效率越低下

=>把事件都绑定在自己的父元素上:获取目标元素:触发的元素

  • 老IE e.srcElement
  • 主流 e.target
  • 兼容 target=e.srcElement
  1. 组织浏览器的默认行为
  • 老IE e.returnValue=false
  • 主流 e.preventDefault()
  • 兼容
    if(e.preventDefault){
        e.preventDefault();
    }else{
        e.returnValue=false;
    }
    
  1. 获取键盘的键码 e.keyCode