正在加载……
专注、离线、切勿分心

window

window:是一个全局对象,代表浏览器中一个打开的窗口,每个窗口都是一个window对象。


document

document是window的一个属性,这个属性是一个对象;document代表当前窗口中的整个网页;document对象保存了网页上所有的内容,通过document对象就可以操作网页上的内容。


DOM

DOM全称:Document Object Model,即文档模型对象;DOM 定义了访问和操作 HTML文档(网页)的标准方法。

1.通过id获取指定元素
	由于id不可以重复, 所以找到了就会将找到的标签包装成一个对象返回给我们, 找不到就返回Null.
let oDiv = document.getElementById("box");

2.通过class名称获取
	由于class可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组.
let oDivs = document.getElementsByClassName("father");

3.通过name名称获取
	由于name可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组.
let oDivs = document.getElementsByName("test");

4.通过标签名称获取
	由于标签名称可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组.
let oDivs =  document.getElementsByTagName("div");

5.通过选择器获取
	querySelector只会返回根据指定选择器找到的第一个元素.
let oDiv = document.querySelector("#box");
let oDiv = document.querySelector(".father");
let oDiv = document.querySelector("div>form");

 6.通过选择器获取
	querySelectorAll会返回指定选择器找到的所有元素.
let oDivs = document.querySelectorAll(".father");

1、 2、

1.获取指定元素所有的子元素
	children属性获取到的是指定元素中所有的子元素,childNodes属性获取到的是指定元素中所有的节点
let oDiv = document.querySelector("div");
console.log(oDiv.children);
console.log(oDiv.childNodes); // node.nodeType === 1 表示节点,node.nodeType === Node.ELEMENT_NODE

2.获取指定节点中的第一个子节点
let oDiv = document.querySelector("div");
console.log(oDiv.firstChild);

3.获取指定元素中的第一个子元素
console.log(oDiv.firstElementChild);

4.获取指定节点中最后一个子节点
console.log(oDiv.lastChild);

5.获取指定元素中最后一个子元素
console.log(oDiv.lastElementChild);

6.通过子元素获取父元素/父节点
let item = document.querySelector(".item");
console.log(item.parentElement);
console.log(item.parentNode);

7.获取相邻上/下一个节点
console.log(item.previousSibling);
console.log(item.nextSibling);

8.获取相邻上/下一个元素
c console.log(item.nextElementSibling);

节点

DOM对象(document), 这个对象以树的形式保存了界面上所有的内容,HTML页面每一部分都是由节点(标签(元素),文本,属性)


节点操作

1.创建节点
		let oSpan = document.createElement("span");

2.添加节点
    oDiv.appendChild(oSpan)
    let oA = document.createElement("a");
    oDiv.appendChild(oA);

3.插入节点
    let oH1 = document.querySelector("h1");
    oDiv.insertBefore(oSpan, oH1);
    oDiv.insertBefore(oSpan, oP);

4.删除节点
		注意点: 在js中如果想要删除某一个元素, 只能通过对应的父元素来删除元素是不能够自杀的
		oSpan.parentNode.removeChild(oSpan);

5.克隆节点
		注意点: cloneNode方法默认不会克隆子元素, 如果想克隆子元素需要传递一个true
    let oDiv = document.querySelector("div");
    let newDiv =  oDiv.cloneNode();
    let newDiv =  oDiv.cloneNode(true);

6.获取/设置元素属性
		let oImg = document.querySelector("img");
		注意点: 通过对象.属性名称的方式无法获取到自定义属性的取值,通过getAttribute方法可以获取到自定义属性的取值
    console.log(oImg.getAttribute("alt"));
    console.log(oImg.setAttribute("title", "新的title222"));

7.获取元素内容
    innerHTML获取的内容包含标签, innerText/textContent获取的内容不包含标签
    innerHTML/textContent获取的内容不会去除两端的空格, innerText获取的内容会去除两端的空格
    无论通过innerHTML/innerText/textContent设置内容, 新的内容都会覆盖原有的内容
    ———— 区别:
    如果通过innerHTML设置数据, 数据中包含标签, 会转换成标签之后再添加
    如果通过innerText/textContent设置数据, 数据中包含标签, 不会转换成标签, 会当做一个字符串直接设置

8.设置元素样式
    let oDiv = document.querySelector("div");
    oDiv.className = "box";
    oDiv.style.width = "300px"; // 注意点: 通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式
    oDiv.style.height = "300px";

9.获取元素样式
    注意点: 通过style属性只能到行内样式的属性值, 获取不到CSS设置的属性值
		console.log(oDiv.style.width);
    注意点: 如果想获取到CSS设置的属性值, 必须通过getComputedStyle方法来获取
    getComputedStyle方法接收一个参数, 这个参数就是要获取的元素对象
    getComputedStyle方法返回一个对象, 这个对象中就保存了CSS设置的样式和属性值
    let oDiv = document.querySelector("div");
    let style = window.getComputedStyle(oDiv);

DOM事件

用户和浏览器之间的交互行为我们就称之为事件,比如:点击,移入/移出;

在JavaScript中所有的HTML标签都可以添加事件,元素.事件名称 = function(){};;如果给元素添加了和系统同名的事件, 我们添加的事件不会覆盖系统添加的事件

添加事件的三种方式:

1、 oBtn.onclick = function () {}

注意点: 由于是给属性赋值, 所以后赋值的会覆盖先赋值

2、oBtn.addEventListener("click", function () {}

事件名称不需要添加on; 后添加的不会覆盖先添加的; 只支持最新的浏览器IE9;
oBtn.addEventListener("click", function () {
    alert("666");
});

3、oBtn.attachEvent("onclick", function () {}

事件名称必须加上on; 后添加的不会覆盖先添加的; 只支持低版本的浏览器;
let oBtn = document.querySelector("button");
oBtn.onclick = function () {
    alert("按钮被点击了");
}

oBtn.onclick = function () {
    alert("a标签被点击了");
    // 以下代码的含义: 用我们添加的事件覆盖掉系统同名的事件
    return false;
}

// 1.移入事件
oDiv.onmouseover = function () {
    console.log("移入事件");
}
oDiv.onmouseenter = function () { // 注意点: 建议使用onmouseenter
    console.log("移入事件");
}

// 2.移出事件
oDiv.onmouseout = function () {
    console.log("移出事件");
}
oDiv.onmouseleave = function () { // 建议使用onmouseleave
    console.log("移出事件");
}

// 3.移动事件
oDiv.onmousemove = function () {
    console.log("移动事件");
}

// 1.监听input获取焦点
oInput.onfocus = function () {
    console.log("获取到了焦点");
}
// 2.监听input失去焦点
oInput.onblur = function () {
    console.log("失去了焦点");
}
// 3.监听input内容改变
oInput.onchange = function () { // 注意点: onchange事件只有表单失去焦点的时候, 才能拿到修改之后的数据
    console.log(this.value);
}

闭包

闭包(closure)是一种特殊的函数。当一个内部函数引用了外部函数的数据(变量/函数)时,那么内部的函数就是闭包,所以只要满足"是函数嵌套"、"内部函数引用外部函数数据"。

特点:只要闭包还在使用外部函数的数据,那么外部的数据就一直不会被释放;也就是说可以延长外部函数数据的生命周期。当后续不需要使用闭包时候, 一定要手动将闭包设置为null, 否则会出现内存泄漏。


事件对象

事件对象是一个系统自动创建的一个对象,当注册的事件被触发的时候, 系统就会自动创建事件对象。

注意点:

在高级版本的浏览器中, 会自动将事件对象传递给回调函数。

在低级版本的浏览器中, 不会自动将事件对象传递给回调函数,需要通过window.event来获取事件对象。

var oBtn = document.getElementById("btn");
oBtn.onclick = function (event) {
    // 兼容性的写法
    event = event || window.event;
    console.log(typeof event);
    return false; // 阻止默认行为; event.preventDefault();方法只支持高级版本的浏览器, event.returnValue = false; // IE9以下的浏览器
}
// event.stopPropagation(); 阻止事件冒泡

事件的三个阶段

1. 捕获阶段(从外向内的传递事件)
2. 当前目标阶段
3. 冒泡的阶段(从内向外的传递事件)
三个阶段只有两个会被同时执行,要么捕获和当前, 要么当前和冒泡;这是JS处理事件的历史问题,早期各大浏览器厂商为占领市场, 以及对事件的理解不同,后续W3C为了兼容, 将两种方式都纳入标准

如何设置事件到底是捕获还是冒泡:通过addEventListener方法,这个方法接收三个参数,第一个参数: 事件的名称、第二个参数: 回调函数、第三个参数: false冒泡 / true 捕获

注意点:

onXxx的属性,不接收任何参数,所以默认就是冒泡。attachEvent方法, 只能接收两个参数, 所以默认就是冒泡

不是所有的事件都能冒泡,以下事件不冒泡:blur、focus、load、unload

// 事件冒泡的应用
<ul>
    <li class="selected">我是第1个li</li>
    <li>我是第2个li</li>
    <li>我是第3个li</li>
</ul>

let oUl = document.querySelector("ul");
let oLi = document.querySelector(".selected");
oUl.onclick = function (event) {
    event = event || window.event;
    oLi.className = "";
    let item = event.target;
    item.className = "selected";
    oLi = item;
}

BOM

BOM就是一套操作浏览器的API(接口/方法/属性)。

// BOM中常见的对象
window: 代表整个浏览器窗口
注意: window是BOM中的一个对象, 并且是一个顶级的对象(全局)
Navigator: 代表当前浏览器的信息, 通过Navigator我们就能判断用户当前是什么浏览器
Location:  代表浏览器地址栏的信息, 通过Location我们就能设置或者获取当前地址信息
History:   代表浏览器的历史信息, 通过History来实现刷新/上一步/下一步
注意点: 出于隐私考虑, 我们并不能拿到用户所有的历史记录, 只能拿到当前的历史记录
Screen:   代表用户的屏幕信息

代表当前浏览器的信息,通过Navigator我们就能判断用户当前是什么浏览器。

console.log(window.navigator);
var agent = window.navigator.userAgent;
if(/chrome/i.test(agent)){
    alert("当前是谷歌浏览器");
}else if(/firefox/i.test(agent)){
    alert("当前是火狐浏览器");
}else if(/msie/i.test(agent)){
    alert("当前是低级IE浏览器");
}else if("ActiveXObject" in window){
    alert("当前是高级IE浏览器");
}

Location

代表浏览器地址栏的信息,通过Location我们就能设置或者获取当前地址信息。

// 获取当前地址栏的地址
window.location.href

// 设置当前地址栏的地址
window.location.href = "http://www.baidu.com";

// 重新加载界面
window.location.reload();

// 强制刷新
window.location.reload(true);

History

代表浏览器的历史信息,通过History来实现刷新/前进/后退。出于隐私考虑,我们并不能拿到用户所有的历史记录,只能拿到当前的历史记录。只有当前访问过其它的界面,才能通过forward/go方法前进,back/go方法后退。如果给go方法传递1,就代表前进1个界面,传递2就代表进行2个界面。

window.history.go(1);
window.history.forward();

window.history.go(0); // 如果给go方法传递0, 就代表刷新

window.history.go(-1); // 后退
window.history.back(-1);

获取元素宽高

  • getComputedStyle/currentStyle/style 获取的宽高不包括 边框和内边距

  • offsetWidth/offsetHeight 获取的宽高包括 边框和内边距

  • getComputedStyle/currentStyle/offsetXXX 只支持获取, 不支持设置

  • style 可以获取, 也可以设置

  • getComputedStyle/currentStyle/offsetXXX 即可以获取行内,也可以获取外联和内联样式

  • style 只能获取行内样式

offset/clientXXX 属性

offsetLeftoffsetTop作用获取元素到第一个定位祖先元素之间的偏移位,如果没有祖先元素是定位的, 那么就是获取到body的偏移位

offsetWidthoffsetHeight 表示 边框 + 内边距 + 宽/高

clientWidth/clientHeight 表示 内边距 + 宽/高

clientLeft/clientTop 左边框 和 顶部边框

scrollWidth/scrollHeight 元素宽度 + 内边距宽度 === clientWidth,,内容超出元素范围时:元素宽/高度 + 内边距宽度 + 超出的宽度

scrollHeight 获取对象的滚动高度。
scrollWidth 获取对象的滚动宽度
scrollLeft 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离

offsetHeight 获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
offsetLeft 获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
offsetTop 获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置

pageXOffset 页面滚动出可是区域的宽度 window.pageXOffset, 和scrollLeft类似
pageYOffset 页面滚动出可是区域的高度 window.pageYOffset

event.clientX 相对文档(浏览器可视区域)的水平座标,可视区域是不包括滚动出去的范围的
event.clientY 相对文档(浏览器可视区域)的垂直座标,可视区域是不包括滚动出去的范围的

event.offsetX 相对容器的水平坐标
event.offsetY 相对容器的垂直坐标

document.documentElement.scrollTop 垂直方向滚动的值
event.clientX+document.documentElement.scrollTop 相对文档的水平座标+垂直方向滚动的量 

位置获取

offsetX/offsetY:事件触发相对于当前元素自身的位置

clientX/clientY:事件触发相对于浏览器可视区域的位置,可视区域是不包括滚动出去的范围的

pageX/pageY: 事件触发相对于整个网页的位置,整个网页包括滚动出去的范围的

screenX/screenY: 事件触发相对于屏幕的位置

offsetParent

获取元素的第一个定位祖先元素,如果没有祖先元素是定位的, 那么就是获取到的就是body。

// 获取页面滚动出可是区域宽/高度
  function getPageScroll() {
    let x, y;
    if (window.pageXOffset) {
      x = window.pageXOffset;
      y = window.pageYOffset;
    } else if (document.compatMode === "BackCompat") { //  浏览器在渲染网页的时候有两种模式"标准模式"/"混杂模式/怪异模式", 默认标准模式, 如果网页没有书写文档声明, 那么就会按照"混杂模式/怪异模式"来进行渲染的(BackCompat)
      x = document.body.scrollLeft;
      y = document.body.scrollTop;
    } else {
      x = document.documentElement.scrollLeft;
      y = document.documentElement.scrollTop;
    }
    return {
      x: x,
      y: y
    }
  }

window.scrollTo(0, i * screenHeight); // 指定页面滚动到哪个位置
document.documentElement.scrollTop = i * screenHeight + "px"; // 可以设置单位

函数防抖

debounce ,函数防抖是优化高频率执行js代码的一种手段,可以让被调用的函数在一次连续的高频操作过程中只被调用一次。主要作用:减少代码执行次数,提升网页性能。

函数防抖应用场景:oninput / onmousemove / onscroll / onresize等事件

let oInput = document.querySelector("input");

function debounce(fn, delay) {
  let timerId = null;
  return function () {
    let self = this;
    let args = arguments;
    timerId && clearTimeout(timerId);
    timerId = setTimeout(function () {
      fn.apply(self, args);
    }, delay || 1000);
  }
}

函数节流

throttle ,函数节流也是优化高频率执行js代码的一种手段,可以减少高频调用函数的执行次数。主要作用:减少代码执行次数, 提升网页性能。

函数节流作用:oninput / onmousemove / onscroll / onresize等事件

function throttle(fn, delay) { // fn = test
  let timerId = null;
  let flag = true;
  return function () {
    if (!flag) return;
    flag = false;
    let self = this;
    let args = arguments;
    timerId && clearTimeout(timerId);
    timerId = setTimeout(function () {
      flag = true;
      fn.apply(self, args);
    }, delay || 1000);
  }
}

window.onresize = throttle(() => { resetSize() }, 500)

函数节流和函数防抖区别:

  • 函数节流是减少连续的高频操作函数执行次数 (例如连续调用10次, 可能只执行3-4次)
  • 函数防抖是让连续的高频操作时函数只执行一次(例如连续调用10次, 但是只会执行1次)
posted on 2021-06-20 00:37  正在加载……  阅读(128)  评论(0编辑  收藏  举报