WebApi_BOM

BOM

BOM(Browser Object Model):浏览器对象模型,提供了一套操作浏览器功能的工具。

window对象

  1. window 对象是一个全局对象,也可以说是 JavaScript 中的顶级对象
  2. document、alert()console.log() 这些都是 window 的属性,其实 BOM 中基本所有的属性和方法都是属性 window 的。
  3. 所有定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法
  4. window 对象下的属性和方法调用的时候可以省略 window

关于this

  • 函数内部的this是window
  • 方法内部的this,指向当前的对象
  • 构造函数内部的this,新创建的对象
  • 事件里面的this,当前对象

name和top

name和top是window的两个特殊字

name永远是字符串

window.open与window.close(了解)

window.open() 打开一个窗口

语法:window.open(url, [name], [features]);

  • 参数1:需要载入的url地址
  • 参数2:新窗口的名称
    • _blank:如果指定为_blank,表示在新的窗口打开
  • 参数3:窗口的属性,指定窗口的大小
  • 返回值:会返回刚刚创建的那个窗口,用于关闭

示例:

1
2
3
var newWin = window.open("http://www.baidu.com","_blank", "width=300,height=300");

//参数配置:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/open

window.close() 关闭窗口

newWin.close();newWin是刚刚创建的那个窗口

window.close(); 把当前窗口关闭

延时器与定时器(事件)

setTimeout:延时器

setTimeout延时器可以在延迟时间到期后执行一个指定的函数。只执行一次

  • 语法:var timer = setTimeOut(function(){ //1秒后将执行的代码。}, 1000);
  • 第一个参数是一个回调函数,第二参数是毫秒数
  • 返回一个延时器的id,用于清除定时器
  • 清除延时器:clearTimeOut(timer); 清除上面定义的定时器
1
2
3
4
5
var timer = setTimeOut(function(){
//1秒后将执行的代码。
}, 1000);

clearTimeOut(timer);//清除上面定义的定时器

setInterval:定时器

setInterval,方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。定时器除非清除,否则会一直执行下去。

  • 语法:var timer = setInterval(function(){ //重复执行的代码。}, 1000);
  • 第一个参数是一个回调函数,第二参数是毫秒数
  • 返回一个延时器的id,用于清除定时器
  • 清除定时器:clearInterval(timer);//清除上面定义的定时器
1
2
3
4
5
var timer = setInterval(function(){
//重复执行的代码。
}, 1000);

clearInterval(timer);//清除上面定义的定时器

location 对象

location 对象也是 window 的一个属性,location 其实对应的就是浏览器中的地址栏。

location.href 控制地址栏中的地址;location.href = "http://www.baidu.com"; 让页面跳转到百度首页

location.reload() 让页面重新加载

1
2
3
4
5
location.reload(true);//强制刷新,相当于ctrl+F5
location.reload(false);//刷新,相当于F5
history.go(1) // 下一页,前提有缓存
history.go(0) // 当前页,刷新
history.go(-1) // 返回上一页

location 的其他属性

1
2
3
4
5
6
7
console.log(window.location.hash);//哈希值 其实就是锚点   SPA(single page application)
console.log(window.location.host);//服务器 服务器名+端口号
console.log(window.location.hostname);//服务器名
console.log(window.location.pathname);//路径名
console.log(window.location.port);//端口
console.log(window.location.protocol);//协议
console.log(window.location.search);//参数

window的其他对象

window.navigator 的一些属性可以获取客户端的一些信息;navigator.userAgent 浏览器版本

history 对象表示页面的历史

1
2
3
4
5
6
//后退:
history.back();
history.go(-1);
//前进:
history.forward();
history.go(1);

screen 对象

1
2
3
4
console.log(screen.width);//屏幕的宽度
console.log(screen.height);//屏幕的高度
console.log(screen.availWidth);//浏览器可占用的宽度
console.log(screen.availHeight);//浏览器可占用的高度

三大家族

offset系列

获取元素的宽高

element.style.height:对应的是行内样式,对于写在类中的样式是获取不到的;

  1. 设置宽度高度使用style.width与style.height
  2. 获取宽度和高度offsetWidth与offsetHeight

element.offsetHeight:element 的真实高度 padding+border+Height;获取到的是元素的真实高度,包括padding和border;是一个在只读属性,不能对元素设置属性;

element.offsetWidth:element 的真实宽度 padding+border+Width;获取到的是元素的真实宽度,包括padding和border;是一个在只读属性,不能对元素设置属性;

offsetParent

element.offsetParent 获取的是向上最近的有定位的父级元素

parentNode 和 offsetParent

  1. parentNode始终是父元素
  2. offsetParent是离当前元素最近的定位元素(absolute、relative),如果没有,那就找body

offsetLeft与offsetTop

offsetLeft 自身左侧到offsetParent左侧的距离 left + margin-left
offsetTop 自身顶部到offsetParent顶部的距离 top + margin-top

  1. 元素自身与offsetParent真实的距离
  2. 获取到的是数值类型,方便计算
  3. 只读属性,只能获取,不能设置

element.offsetLeft:element 距离向上最近的有定位的父级元素的真实距离 left+margin-left

element.offsetTop:element 距离向上最近的有定位的父级元素的真实距离 top+margin-top

结论:获取操作:用offset系列;设置操作:用style.xxx进行设置。

scroll系列

scroll家族用来获取盒子内容的大小和位置

scroll家族有:scrollWidthscrollHeightscrollLeftscrollTop

通常来说,scroll家族用的最多的地方就是用来获取页面被卷去的宽度和高度,非常的常用;

scrollWidthscrollHeight 获取的是盒子中内容的真实大小,与盒子无关;只有当盒子中的内容小于盒子本身+padding时,才显示盒子本身+padding的大小。

scrollTopscrollLeft 当有滚动条时,获取的是被滚动掉的像素值,没有滚动条时获取的值为0;

window.pageXOffsetwindow.pageYOffset 是现代浏览器的新用法

client系列

client家族用于获取盒子可视区的大小

client家族有clientWidthclientHeightclientLeftclientTop

clientWidthclientHeight 获取的是可视区的大小,对于盒子来说是盒子本身+padding的大小,对于浏览器是当前页面可视区的大小

window.innerWidthwindow.innerHeight 是现代浏览器的用法

clientTopclientLeft 就是上边框和左边框的大小,如果有滚动条会加上滚动条的大小,基本上没用

动画函数封装

  • 清除定时器使用element作为父级对象存储定时器返回值
    • 封装在函数内部
    • element.timeId
    • 只对当前element起作用,不会被其他元素影响或者被影响
  • 清除定时器时,不管有没有到目标位置,都让element的style设置为目标值
  • 向前移动还是向后移动,用绝对值来判断
  • 使用三元运算符来设置是正的移动值还是负的移动值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 /**
* 封装动画函数-左右方向
* @param element 为那个元素设置动画
* @param target 动画移动的目标值
* @param distance 动画每次定时器调用移动多远
*/
function animation(element, target, distance) {
//清除定时器
//element.timeId; 保证了此定时器的唯一性,并且不会影响或者被影响
clearInterval(element.timeId);
////获取元素的left位置
var location = element.offsetLeft;
//判断是要前进还是倒退
var step = location < target ? distance : -distance;
//设置定时器
element.timeId = setInterval(function () {
//判断定时器是不是还需要继续
if (Math.abs(target - location) > Math.abs(step)) {
location += step;
element.style.left = location + "px";
} else {
//不能继续的时候清除定时器
clearInterval(element.timeId);
//清除定时器以后,不管你有没有到达目标位置,都让你到达目标位置
element.style.left = target+"px";
}
}, 15)

轮播图

存放图片的ul宽度要设置足够大,lis.length*图片宽度

在图片末尾多加一张图,第一幅图片,用来实现无缝轮播

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//是最后一张图片了
if (count >= imgs.length - 1) {
//瞬间把图片变回第0张
count = 0;
//并且把ul的位置设置到0
ul.style.left = 0;
}

//第一张图片
if (count <= 0) {
//瞬间变到最后一张
count = imgs.length - 1;
//ul的位置应该换到最后
ul.style.left = -count * box.offsetWidth + "px";
}

同步小圆点,图片比圆点多一

1
2
3
4
5
6
7
8
9
10
11
12
13
//3. 同步小圆点
//3.1 干掉所有的小圆点
for (var i = 0; i < points.length; i++) {
points[i].className = "";
}
//3.2 复活count, 如果是最后一张,显示第0个小圆点
if (count >= imgs.length - 1) {
points[0].className = "now";
} else {
points[count].className = "now";
}

// 左右点击都是一样

自动播放通过自点击事件 element.click(); 和定时器自己点击来轮播

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//思路:开启一个定时器, 每隔2s点击一下右箭头
var timeId = setInterval(function () {
//表示触发右箭头的点击事件
rightArr.click();
}, 2000);


//给box注册onmouseover事件,清除定时器
box.onmouseover = function () {
clearInterval(timeId);
}

//给box注册onmouseout事件,开启定时器
box.onmouseout = function () {
timeId = setInterval(function () {
//表示触发右箭头的点击事件
rightArr.click();
}, 2000);
}

事件

注册事件

  • 事件:触发-响应机制,javascript是基于事件驱动的。
  • 事件源:哪个对象受到了触发
  • 事件名称:触发的条件;需要什么动作
  • 事件处理程序:会发生什么;事件触发后要执行的代码(函数形式)

事件对象

在触发某个事件时,都会产生一个事件对象Event,这个对象中包含所有事件的相关信息,包括触发事件的元素,事件的类型和其他一系列事件相关的信息。

获取事件的对象,在注册事件时,对函数设置一个形参就能获取;

对于IE678来说,获取事件对象则是另一种方式,在事件里面,通过 window.event 来获取事件对象;

event.target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。

1
2
3
4
5
//兼容性封装
btn.onclick = function(event){
//只要用到了事件对象,就要记得处理浏览器兼容性
event = event || window.event;
}

事件常用的属性

  • clientX,clientY:相对于可视区left和top的距离
  • pageX,pageY:相对于内容的left和top的距离,包括不能显示的部分(和scroll系列类似)
  • screenX,screenY:相对于整个屏幕(显示器)的left和top的距离

常用事件

  • onclick:鼠标点击事件
  • 鼠标经过事件与鼠标离开事件
    • onmouseover:当鼠标经过时触发
    • onmouseout:当鼠标离开时触发
  • 获得焦点与失去焦点
    • onfocus:获得焦点时触发
    • onblur:失去焦点时触发
  • 键盘的按下和弹起事件
    • keydown:当键盘按下时触发的事件
    • keyup:键盘弹起时触发的事件
    • 注意:如果给文本框注册的是keydown事件,获取的value值是上一次的。(按下8次,会记录第一次空白和后面7次)
    • event.keyCode属性:在键盘事件中,这个会记录键盘按下的键盘码,具有唯一性
  • 双击事件
    • ondblclick:双击的时候触发
  • 自点击事件 element.click(); 一般和定时器一同使用,
  • onscroll事件滚动条滚动事件;当有滚动条时,滚动条被移动时才触发
  • onresize事件窗口大小调整事件;在当前可视区大小发生变化时才出发,一般用于响应式布局
  • onmousedown鼠标按下事件;鼠标按下的时候触发,一般用于单击按住不放拖拽
  • onmouseup鼠标弹起事件;鼠标弹起的时候触发,onclick事件时发生在鼠标弹起后
  • onmousemove鼠标移动事件;给谁注册就只能在谁的身上生效移动

注册事件的方式

on+事件名称

  • on+事件默认是冒泡
  • 如果同一元素有多个相同的事件会被后面的覆盖掉

addEventListener与removeEventListener现代浏览器支持的注册事件的新方式,这种方式注册的事件不会出现覆盖问题。

addEventListener(type, func, useCapture); 注册事件

三个参数:

  • type:字符串事件名称,不用加on;
  • func:事件处理函数,如果需要移除这个函数,不能使用匿名函数,此处不能直接声明函数,在这里声明的函数,移除时使用函数名无效;
  • useCapture:布尔类型,默认值是false,表示冒泡;true,表示捕获;

removeEventListener(type, func, useCapture); 移除事件

三个参数:

  • type:需要移除的字符串事件名称,不用加on;
  • func:需要移除的函数名
  • useCapture:布尔类型,默认值是false;

attachEvent与detachEvent(了解)只有IE678才支持

IE678不支持addEventListener与removeEventListen两个方法,但是支持attachEvent与detachEvnet

attachEvent的用法:

1
2
3
//type:事件类型   需要加上on   onclick  onmouseenter
//func:需要执行的那个事件
attachEvent(type, func)

detachEvent的用法

1
2
3
//type:事件类型   需要加上on   onclick  onmouseenter
//func:需要执行的那个事件
detachEvent(type, func)

事件流

事件大三个阶段

任何事件 发生,都会有三个阶段,首先发生的是捕获阶段,然后是目标阶段,最后是冒泡阶段;从最大祖先级向目标捕获到达目标在向最大祖先级冒泡,只要有同一事件就会被触发,

当使用 addEventLinstener(type, func, useCapture); 时,useCapture的值为true时,表示在捕获阶段发生,值为false时表示在冒泡阶段发生,所有的事件只会触发一次,根据这个值来判断,用on+注册事件默认都是冒泡。

当使用 event.stopPropagation(); 阻止时,会立即停止在当前的事件。即使是没有到目标位置也会停止。

  1. 捕获阶段–首先发生
  2. 目标阶段–然后发生
  3. 冒泡阶段–最后发生

事件冒泡

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡。

说白了就是:当我们触发了子元素的某个事件后,父元素对应的事件也会触发。

通常情况,事件冒泡对于我们来说是没有问题的,我们直接不管就行了,但是如果当事件冒泡给我们带来影响的时候,我们需要阻止事件冒泡。

事件捕获

事件捕获是火狐浏览器提出来的,IE678不支持事件捕获(基本上,我们都是用事件冒泡)

事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递

阻止事件传播

event.stopPropagation(); 表示阻止传播事件,所有的事件处理函数中,出现此语句时,会立即停止在当前事件,即使是没有到达目标阶段。

window.onload

window.onload事件会在窗体加载完成后执行,通常我们称之为入口函数。

作用:会等待页面所有的资源都加载完成,才会执行。

一般用在获取图片的宽高属性时,会用到,

给window注册的几个事件

window.onload 所有加载完之后才触发
window.onscroll 滚动条滚动触发
window.onresize 可视区大小改变时触发

获取计算后的样式

window.getComputedStyle(element)

通过element.style.xxx只能获取到行内样式

通过offset系列只能获取到特殊的一些样式

获取元素计算后的样式指的是元素经过层叠后真正生效的样式,不管样式写在哪,计算后的样式指的就是最终的样式。
现代浏览器:return window.getComputedStyle(element, null)[attr];

IE678:return element.currentStyle[attr];

window.getComputedStyle(element) 获取到的是最终生效的元素样式,用于获取元素计算后的样式(元素生效的样式)