- BOM是浏览器对象模型,DOM是文档对象模型;
- 前者是对浏览器本身进行操作,而后者是对浏览器(可看成容器)内的内容进行操作。
- window((location,history,document->DOM,navigater)->BOM),BOM包含有DOM
1.BOM对象
- BOM是Browser Object Model的缩写,即浏览器对象模型。
- BOM没有相关标准。不同浏览器定义有差别,实现方式不同。
- BOM的最根本对象是window。
-
全局变量
全局变量存在 window对象之中;
a = 10; delete window.a; console.log(a); //a没有被删除,不会报错
-
伪全局变量
未经var声明变量的就是伪全局变量;
a = 10; delete window.a; console.log(a); // a此时被删除,报错;
-
window
浏览器端JS的核心对象,每个浏览器独有,有非常大的兼容问题
window.document
window.alert
window.location
window.navigator
window.screen
//文档内部的宽高 console.log(innerWidth,innerHeight); //包含浏览器控制台的高度,自带margin是8px,只包含了左侧的8px console.log(outerWidth,outerHeight); //显示器屏幕的所有宽高 console.log(screen.width,screen.height); //不包括底下任务栏的宽高 console.log(screen.availWidth,screen.availHeight); console.log(screenX,screenY);//窗口位置坐标 console.log(screenLeft,screenRight);//同上
-
location对象
location对象 区别 历史记录 能否返回 location.href="http://www.163.com"; 跳转页面,可以获取当前地址 有 可以 location.assign("http://wwww.163.com"); 页面跳转,不能获取当前地址 有 可以 localtion.repalce("http://wwww.163.com"); 页面跳转 没有 不可以 location.reload(); //刷新缓存 location.reload(true); //底层刷新 Alt + F5 console.log(location.hostname); //域名 console.log(location.pathname); //路径和文件名 console.log(location.port); //端口号 console.log(location.protocol); //访问协议 //页面跳转,用location.search接收"?"参数后面的内容 location.href = "aa.html?a=3&b=4"; console.log(location.search); location.hash; // 浏览器地址栏中的"#"后面内容,路由跳转,超链接的锚点标记, //点击之后必须刷新页面才能在控制台出现内容, //因为不刷新时页面还没有装载完成;
- 网页文档的树形结构
- 弹出框
confirm("请点击确认");
var res = parseInt(prompt("请输入一个整数"));
- window.onload()事件
当页面中所有图片 | 内容加载结束才会执行代码
window.onload = function(){
console.log(img.width);//刚开始获取不到图片的宽和高,页面加载之后才会执行
console.log(img.height);
}
- window.onscroll()事件
屏幕滚动时候触发
window.onscroll = function(){
console.log(1);
}
- window.onresize()
窗口的大小发生改变时候触发
- history
当访问历史的时候是不会进行重载的,是将原来的内容直接打开,回退的时候会保留原始页面的部分内容,如文本框里的数据,但是不会保留密码框的数据
history.back();//返回上一层
history.forword();//向前一层
history.go(0);//刷新页面
history.go(1);//向前一个历史
history.go(-1);//向后一个地址
//页面跳转的记录
//要将一个数据与另一个页面共享数据
console.log(history.state);
history.length;//历史记录的数量
- navigator
//获取当前浏览器的内核和版本信息
console.log(navigator.userAgent);
2.DOM
- DOM是Document Object Model的缩写,即文档对象模型。
- DOM是W3C的标准。
- DOM最根本对象是document(实际上是window.document)
- DOM(Document Object model)结构,树形结构。
- Object-->EventTarget--->Node--->Element--->HTMLElement--->HTMLDivElement
- DOM的元素
把标签统称为元素Element;节点也是元素
console.log(document.documentElement); //HTML
console.log(document.head); //head标签
console.log(document.body); //body标签
- DOM元素的基本操作
document.createElement("div"); //创建一个div元素
document.body.appendChild(div); //向页面中加入创建的div
document.body.insertBefore(div,box); //把div插入在box前面
document.getElementById() // 通过ID号查找元素
document.getElementsByTagName() //通过标签名称查找元素
document.getElementsByName() // 通过name属性来查找元素
document.getElementsByClassName() //通过class属性来查找元素
-
节点
- nodeName(节点名称)
- 元素节点的nodeName是标签名称
- 文本节点的nodeName永远是#text
- 注释节点的nodeName永远是#comment
- nodeName用在两个地方,分辨标签名和获取属性节点名称的时候
- 判断节点是否为div
console.log(div.nodeName === "DIV");
- nodeValue
- 元素的nodeValue不可用
- 注释节点nodeValue包括注释内容
<div> <div> <div>0</div> <ul> <li>1</li> <li>2</li> <li id="li0">3</li> <li>4</li> <li>5</li> </ul> </div> <span>1</span> <span>2</span> <span>3</span> </div>
console.log(document.body.firstChild); //第一个子节点 console.log(document.body.firstElementChild); //第一个子元素 console.log(document.body.lastChild); //最后一个子节点 console.log(document.body.lastElementChild); //最后一个子节点 console.log(document.body.childNodes); //子节点列表 console.log(document.body.children); //子元素列表 //将以上每个li打印出来 console.log(document.body.firstElementChild.firstElementChild.lastElementChild.Child); console.log(document.getElementsByTagName("div"));//获取的是列表项,不是数组 //需要遍历时,还需要将其转换为数组 ——Array.from(); var li0 = document.querySelector("#li0"); console.log(li0.parentNode); //父节点 console.log(li0.parentElement); //父元素 console.log(li0.nextSibling); //下一个兄弟节点 console.log(li0.previousSibling); //上一个兄弟节点 console.log(li0.nextElementSibling); //下一个兄弟元素(非W3C标准) console.log(li0.previousElementSibling); //上一个兄弟元素(非W3C标准)
-
测试节点类型——nodeType
-
获取节点元素
选择器 选择内容 是否有forEach方法 适用范围 querySelector 一个元素 无 所有节点 getElementById 一个元素NodeList 无 document方法 getElementsByName 获取列表NodeList 有 document方法 querySelectorAll 获取列表Nodelist 有 所有节点方法 getElementsByClassName 获取列表 HTMLCollection 无 所有节点方法 getElementsByTagName 获取列表 HTMLCollection 无 所有节点方法 HTMLColllection不能自己遍历,而NodeList可以用forEach方法自己遍历
-
jQuery选择器
// 根据选择器获取到内容第一个元素 var div1 = div.querySelector("div"); //标签选择器 document.querySelector("#div1"); //id选择器 document.querySelector(".div0"); //class选择器 document.querySelector("div .div1"); //后代选择器 document.querySelector("div>.div1"); //子代选择器 document.querySelector("div~.div1"); //兄弟选择器 document.querySelector("div+.div1"); //唯一兄弟选择器 document.querySelector("div,.div1"); //群组选择器 document.querySelector("[type=input]"); //属性选择器
-
文本节点
-
innerHTML | innerText
- 设置 : innerHTML 原样设置 ; innerText 转义后设置内容;
- 取值 : innerHTML 原样取值 ; innerText 取出文本,标签不取出;
- 点击页面,在超链接之前,插入文本
var a = document.createElement("a"); a.href = "#"; a.textContent = "超链接"; div.appendChild(a); document.addEventListener("click", clickHandler); function clickHandler(e) { // div.textContent="你好";//这种方式会覆盖超链接 // 创建文本节点 var text = document.createTextNode("你好"); div.insertBefore(text, a); //给父元素里指定的位置插入子元素 var divs = document.createElement("div"); }
-
//根据给入标签名创建标签
document.createTextNode("文本") //根据给入的文本创建文本节点
parent.appendChild(child) //给父元素插入子元素, 追加在尾部
parent.insertBefore(要插入的新元素, 插入在谁的前面)// 给父元素里指定的位置插入子元素
document.createDocumentFragment() //创建文档碎片
- 插入在父元素的第一个子元素前
function insertFirst(parent, elem) {
parent.insertBefore(elem, parent.firstChild);
}
- 插入在当前父元素的后面
function insertNext(prev, elem) {
prev.parentElement.insertBefore(elem, prev.nextSibling);
}
- 插入在当前父元素的前面
function insertPrev(target, elem) {
target.parentElement.insertBefore(elem, target)
}
- 给当前元素包裹一个父元素
function warp(child, parent) {
insertPrev(child, parent);
parent.appendChild(child);
}
- 如果需要创建元素,已经多个子元素,先不要将父元素放在页面;
- 先把子元素全部放入父元素后,然后再将父元素放在页面中;
- 如果没有父元素的时候,则需要创建文档碎片
- 创建文档碎片
- 文档碎片用来解决什么问题 ?批量操作元素的时候 , 我们需要一个容器 ;
- 文档碎片是一个和DOM一样的容器结构,它不会在页面中被渲染, 只是简单的作为容器使用。
var elem = document.createDocumentFragment();
//这里如果不使用DocumentFragment,而使用var wrap = document.createDocument("div");也可以,只是在文档中会多增加一个标签。
for (var i = 0; i < 50; i++) {
var div = document.createElement("div");
div.innerHTML = "hello world" + i;
elem.appendChild(div);
}
document.body.appendChild(elem);
- 删除元素(并非彻底删除)
div.remove();//仅仅是从文档流中删除
div = null; //彻底删除
div.removeChild(a);//删除子元素
parent.removeChild(child);//父元素删除子元素
- 复制节点
//原元素.cloneNode(是否深复制);
var cloneAll = box.cloneNode(true);
cloneNode => cloneNode() => 复制节点的皮;
=> cloneNode(true)=> 复制节点的全部内容;
- innerHTML 和 innerText 区别
- innerHTML会原样输出
- innerText会解析到浏览器
<ul id="box">xyz
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
console.log(box.innerHTML);//原样输出
//xyz
//<li>a</li>
//<li>b</li>
//<li>c</li>
//<li>d</li>
console.log(box.innerText);//会解析到浏览器执行
//xyz a b c d
- 自定义属性的值
//设置
box.setAttribute("index",99);
//删除
box.removeAttribute();
//获取
box.getAttribute("index");
- 获取节点
parentNode //获取父节点
childNodes //获取所有子节点
children //获取所有子标签(非W3C标准)
previousSibling //前一个兄弟节点
nextSibling // 后一个兄弟节点
previousElementSibling //前一个兄弟元素(非W3C标准)
nextElementSibling //后一个兄弟元素(非W3C标准)
- 根据使用习惯封装通用选择器
function $(selector){
var firstSelector = selector[0];
if(firstSelector === "#"){
return document.querySelector( selector );
}
reutrn document.querySelectorAll( selector );
}
- 设置元素的样式
var box = document.getElementById("box");
box.style.color = "#f99";
box.style.background = "yellowgreen";
box.style.cssText = "color: rgb(255, 153, 153); background: orange;";
//推荐的元素样式设置 :
box.className += " active";
//删掉active;
console.log(box.className.split(" ").join(" "));
//eg:-------------------------------------------------
function removeEle(arr, val) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == val) {
arr.splice(i, 1);
break;
}
}
return arr;
}
var arr = box.className.split(" ");
box.className = removeEle(arr, "sss").join(" ");
- 删除元素
var box = document.getElementById("box");
document.body.removeChild(box); 或者box.parentNode.removeChild(box);
要想删除box,必须要先找到它的父级节点,于是封装了一个函数
function remove( ele ){
return ele.parentNode.removeChild(ele);
}
-
封装功能 :
- getAttribute()
找到属性节点集合 , 遍历并判定属性名称 nodeName ,如果相同则返回结果;
function getAttribute(dom, attr_name) { var attributes = dom.attributes; for (var i = 0; i < attributes.length; i++) { if (attributes[i].nodeName === attr_name) { return attributes[i].nodeValue; } } return null; } console.log(getAttribute(box, "id"));
- setAttribute()
难点 : 1. 存在属性直接赋值; 2. 不存在属性,创建属性节点,赋值;
function setAttribute(ele_node, attr_name, attr_value) { var attributes = ele_node.attributes; if (attributes[attr_name]) { attributes[attr_name].nodeValue = attr_value; } else { var attr = document.createAttribute(attr_name); attr.nodeValue = attr_value; ele_node.setAttributeNode(attr); } } setAttribute(box, "index", "hello");
- next()
找到下一个元素节点;
function next(ele_node) { var next_ele = null; while (true) { if (ele_node.nextSibling.nodeType === 1) { return ele_node.nextSibling; break; } ele_node = ele_node.nextSibling; } return next_ele; } console.log(next(box));
- nextAll()
找到后面所有的节点
function nextAll(ele_node) { var next_eles = []; while (ele_node.nextSibling !== null) { if (ele_node.nextSibling.nodeType === 1) { next_eles.push(ele_node.nextSibling); } ele_node = ele_node.nextSibling; } return next_eles; }
- nextUntil()
找后面的节点,直到遇到某一个节点为止
function nextUntil(ele_node, until) { var next_eles = []; var until_ele = document.querySelector(until); while (ele_node.nextSibling !== null && ele_node.nextSibling !== until_ele) { if (ele_node.nextSibling.nodeType === 1) { next_eles.push(ele_node.nextSibling); } ele_node = ele_node.nextSibling; } return next_eles; } console.log(nextUntil(box, "#stop"));
- prev()
找上一个兄弟节点
function prev(ele_node) { var prev_ele = null; while (true) { if (ele_node.previousSibling.nodeType === 1) { prev_node = ele_node.previousSibling; break; } ele_node = ele_node.previousSibling; } return ele_node.previousSibling; } console.log(prev(box));
- prevAll()
找元素上面所有的兄弟节点
function prevAll(ele_node) { var prev_eles = []; while (ele_node.previousSibling !== null) { if (ele_node.previousSibling.nodeType === 1) { prev_eles.unshift(ele_node.previousSibling); } ele_node = ele_node.previousSibling; } return prev_eles; } console.log(prevAll(box));
- prevUntil()
找元素上面所有的兄弟节点,直到找到某一个兄弟节点为止
function prevUntil(ele_node, until) { var prev_untils = []; while (ele_node.previousSibling !== null && ele_node.previousSibling !== until) { if (ele_node.previousSibling.nodeType === 1) { prev_untils.unshift(ele_node.previousSibling); } ele_node = ele_node.previousSibling; } return prev_untils; } console.log(prevUntil(box, one));
- parent()
找到元素的父节点
function parent(ele_node) { var parent_ele = null while (true) { if (ele_node.parentNode.nodeType === 1) { parent_ele = ele_node.parentNode; break; } ele_node = ele_node.parentNode; } return parent_ele; } console.log(parent(box));
- parents()
找寻所有的父节点,直到body
function parents(ele_node) { var parent_eles = []; while (ele_node.parentNode !== null) { if (ele_node.parentNode.nodeType === 1) { parent_eles.unshift(ele_node.parentNode); } ele_node = ele_node.parentNode; } return parent_eles; } console.log(parents(box));
- parentUntil()
向上找寻父节点,直到找到某一父节点为止
var test = document.getElementsByTagName("html"); function parentsUntil(ele_node, until) { var parent_eles = []; while (ele_node.parentNode !== null && ele_node.parentNode !== until) { if (ele_node.parentNode.nodeType === 1) { parent_eles.unshift(ele_node.parentNode); } ele_node = ele_node.parentNode; } return parent_eles; } console.log(parentsUntil(box, test));