什么是Api? 什么是WebApi?
API(Application Programming Interface,应用程序编程接口),
通俗的讲,API就是编程语言给我提供的一些工具,通过这些工具,我们可以非常轻易的完成一些功能。
Web API : 是浏览器提供的 一套操作网页(web)的方法(API), 通过这套API我们可以非常轻松的操作页面的元素
和浏览器的一些功能
ECMAScript - JavaScript的核心
-
ECMAScript是一套标准, 规范了语言的基本语法和数据类型;
-
与具体实现无关
DOM - 文档对象模型
-
一套操作页面元素的API
-
通过DOM提供的API可以获取/操作网页上的元素。
BOM - 浏览器对象模型
-
一套操作浏览器功能的API
-
通过BOM可以操作浏览器窗口, 比如刷新、控制浏览器跳转等;
DOM - 文档对象模型
DOM基本概念 (记)
DOM ( Document Object Model ) 文档对象模型, 是
W3C组织
推荐的一套操作网页元素的API。
DOM又称为文档树模型, 因为整个HTML文档是一个树形的结构
代码:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div></div>
<p></p>
<span></span>
</body>
</html>
DOM中常见的概念 : (记忆)
-
文档
document
: 一个网页可以称为文档 ; (换句话说: 操作页面,其实就是操作document)console.log(document); // DOM 会把整个网页当成一个对象,我们操作这个网页, 只要操作这个document对象即可 // DOM 会把网页中的所有的东西都当作对象
-
节点
node
: 网页中的所有内容都是节点 (标签、属性、文本)<ul class="box"> <!-- 这是一些测试 --> <li>测试</li> <li>测试</li> <li>测试</li> </ul> // ul : 标签节点 // class="box" : 属性节点 // <!-- 这是一些测试 --> : 注释节点 // 测试 : 文本节点
-
元素
element
: 网页中的标签节点 -
ul : 元素 li : 元素
DOM初体验
<!-- 需求:有一个img标签,,我们来修改img的title属性 和 src 属性 -->
在DOM中,想要操作一个元素,首先需要先获取到这个元素才能进行操作。
document.getElementById() : 通过id 获取元素
document.getElementById()
//功能:通过id 获取元素
document : 文档对象
get : 得到
element:元素
by:通过
id:id值
// 参数 : 字符串类型的id
//返回值 : 一个元素 一个对象
var div = document.getElementById('div');
console.dir(div);
关于console.log
和console.dir
的区别
-
console.log
打印一个元素的时候,是以标签的形式进行展示的 -
console.dir
打印一个元素的时候,是以对象的形式进行展示的
在DOM中,页面标签的属性和DOM对象的属性是一一对应的,因此我们可以通过修改DOM对象的属性来修改标签的属性。
// img对象 和 img标签 一一对应的
// 以后想要操作img标签,,只需要操作 img对象即可
var img = document.getElementById('img');
// console.dir(img.id);
// console.dir(img.src);
// console.dir(img.title);
使用getElementById的注意事项
-
如果id不存在,返回值为null
-
在DOM中,
document.getElementById('box')
方法需要写在html内容的后面, 保证页面加载完成之后才能获取到内容 (div标签就是) -
Id
错写成ID
, 记得这是一个驼峰命名 :document.getElementById
错误1 : 如果获取的是null,然后获取其属性
Uncaught TypeError: Cannot read property 'title' of null
错误2 : 方法写错Id=> ID错了 `getElementByID`
Uncaught TypeError: document.getElementByID is not a function
演示:
<!--没有id-->
<div id="box">前端学科</div>
<script>
//如果找不到,返回的是null,试图给null设置属性会报错
var element = document.getElementById("box");
element.title = "嘿嘿";//报错Uncaught TypeError: Cannot set property 'title' of null
</script>
事件的基本使用
事件:理解为浏览器的感知系统 , 触发 --> 响应机制,javascript是基于事件驱动的。
<!-- 需求 : 点击按钮切换图片 大 -->
// 注册一个点击事件
// btn : 你要点击谁
// on 在...时候
// click 点击
// 结构 : 事件源.onclick = function() {..}
事件三要素 : 事件源 + 事件名称 + 事件处理函数
-
事件源 : 给谁注册事件 ( 按钮 btn )
-
事件名称 : 注册了什么事件 ( click事件 )
-
事件处理函数 : 事件触发后要执行的代码(函数形式)
注意:事件处理函数并不会立马执行,而是当事件触发的时候才会执行(浏览器会自动调用)
注册事件的基本语法 :
var box = document.getElementById('box');
//on:当 click:点击 当按钮被点击的时候触发
box.onclick = function() {
console.log('代码会在box被点击后执行');
};
两种按钮
<button>点亮</button>
<input type="button" value="哈">
都是可点击的普通按钮
一个是文字显示在标签内容里, 而且还可以放其他标签
一个是文字显示在vaue中
修改标签的属性
-
1.标签属性 : 标签的alt,title,src,width,height等属性,可以直接通过对象进行修改。
-
2.样式属性 : 如果设置是样式 , 就要借助class属性,在js中class是关键字,因此对应的是className属性
-
3.通过 innerText 属性和修改标签的内容
var box = document.getElementById('box');
box.innerText = '嘎嘎';
getElementsByTagName
<!-- 需求 : 点击按钮一次性修改多个 p 标签的文本内容 -->
作用 : 通过标签名获取元素
//参数:标签名
//返回值:一个伪数组, 伪数组不是数组,不能使用属性的方法,但是可以跟数组一样进行遍历和使用下标进行操作。
var ps = document.getElementsByTagName('p');
注意:返回值有没有获取到元素,都是一个伪数组,即便元素只有一个
找对象方法总结复习 (重要)
-
根据id获取元素
// 第一个方法: getElementById() // 作用 : 根据 id值 , 获取元素 // 参数 : 字符串 id值 // 返回值 : 一个对象 // 注意点 : element // 方法 : 1个 // document.getElementById();
-
根据标签获取元素
// 第二个方法: getElementsByTagName() // 作用 : 根据 标签名 , 获取元素 // 参数 : 字符串 标签名 // 返回值 : 数组 (一般使用的话 都是遍历) // 注意点 : elements // 方法 : 2个 // document.getElementsByTagName() // element.getElementsByTagName()
-
方法 ( 2个 ) :
//方法1 : document.getElementsByTagName('div') //获取页面中所有的div标签 // 方法2 : element.getElementsByTagName('li') //获取 某个元素 中的所有li标签
-
注意
-
返回值是一个伪数组 伪数组不能直接使用数组的方法,,不过可以遍历或者通过下标来获取 (够用的了)
-
伪数组不能直接注册事件,需要遍历后拿到标签再注册事件
-
即使获取的标签只有一个,那也是数组,,只不过数组长度为1
-
-
标签属性操作
1.普通标签属性
通过DOM设置普通标签属性,两边都会变化。常见的属性有:src、title、href、class、id等
2.表单属性操作
常见的表单属性有:disabled、type、value、checked、selected
对于disabled、checked、selected三个属性来说,比较特殊。
disabled : 禁用
- true : 禁用
- false : 不禁用
checked : 多选框和单选框选中
- true : 选中
- false : 不选中
selected : 菜单下拉框选中
- true : 选中
- false : 不选中
在DOM对象中,他们的赋值.只要有值,很多都可以起到效果,但是为了统一规范, 我们使用 true/false
3.标签的自定义属性
我们之前讨论的属性,都是HTML规范中,标签本来就有的属性,对于标签自定义的一些属性比较特殊。
在html页面中,定义一个自定义属性
<div id="box" aa="bb"></div>
// 给div标签中 添加不存在的未知属性aa, 这就是自定义属性
attribute方法
attribute系列方法用于设置 标签的属性
//设置标签的属性
box.setAttribute(name, value);
//获取标签的属性
box.getAttribute(name);
//移除标签的属性
box.removeAttribute(name);
总结 :
// 1. 直接给标签里添加固有的属性 title 等 标签+对象里都有显示
// 2. 给标签添加自定义属性 => 标签上 ok + 对象里 不ok
// 3. 给对象添加自定义属性 => 标签里 不ok + 对象里 ok 【掌握】
// 自定义: box.aa = bb; 只能给对象里添加,, 标签内是没有的
// 获取话 : box.aa
// 3. 自定义 : setAttribute 设置, 添加给标签内了获取的话 getAttribute 【掌握】
标签的内容属性 innerText 和 innerHTML
共同点 : 都是用来获取和设置标签的内容的
区别 : innerHTML可以用于获取和设置标签的所有内容,包括标签和文本内容
//innerHTML:内部的HTML
// 获取标签内容的时候,不管标签还是文本,都能获取到
// innerHTML设置内容的时候,覆盖原来内容,标签也能生效,浏览器能解析这个标签。
innerText可以用于获取和设置标签的文本内容,会丢弃掉标签
//innerText:内部 文本
// 获取标签内容的时候,只会获取文本,标签扔掉了
// 设置标签内容的时候,覆盖原来内容,对标签进行转义(目的:把标签直接当文本来用)
二者的区别:
-
innerHTML能够识别标签,标签能够生效
-
innerText只识别文本,标签会被转义。
浏览器兼容性:指网页在各种浏览器上的显示效果不一致。或者是一些属性和方法在低版本的浏览器中不支持。
//1. innerText是IE提出来的属性,因此低版本的火狐浏览器不支持这个属性。
//2. 火狐有一个textContent属性,效果跟innerText一样,但是IE678不支持这个属性
书写innerText的兼容性代码
function getInnerText(element){
if(typeof element.innerText === "string"){
return element.innerText;
} else {
return element.textContent;
}
}
使用:
//innerHTML和innerText用哪个?
//innerHTML:能够识别html标签,
//innerText:不识别标签,
//设置标签的内容,推荐使用 innerText
获取元素的方法总结 [重要]
根据id获取 (掌握)
// getElementById
// 作用 : 根据id 获取元素
// 参数:元素的id
// 返回值:一个元素,如果id不存在,返回null
document.getElementById("id");
根据标签名获取 (掌握)
// getElementsByTagName
// 作用 : 根据标签名 获取元素
// 参数:标签名
// 返回值:伪数组,无论有几个元素,返回都是伪数组
document.getElementsByTagName("tagName");
box.getElementsByTagName("tagName");
//getElementsByTagNameNS 命名空间
var btns = document.getElementsByTagNameNS('*','button');
这两个方法是没有任何兼容性问题的。
根据类名获取
// getElementsByClassName
// 作用 : 根据类名获取元素
// 参数:字符串类型的类名
// 返回值:伪数组
document.getElementsByClassName("class")
注意:这个方法ie678不支持
根据name获取
// getElementsByName
// 作用 : 通过name属性值 获取元素
// 参数 : name值
// 返回值 : 伪数组
var ps = document.getElementsByName("aa");
根据css选择器获取 (重点)
// 回顾 :
// 简单选择器 : div .box #box
// 复杂选择器 : * div,p p.div div p div>p
// 作用 : 根据css选择器获取
//参数:是一个css选择器,, 如果是类选择器, .demo 如果是id选择器: #aa
//返回值:只会返回一个对象,如果有很多个,会返回第一个
document.querySelector();
//参数:是一个css选择器
//返回值:会返回伪数组,不管有多少个,都会返回伪数组
document.querySelectorAll();
行内样式操作(style属性)
标签不仅可以通过class属性操作样式 (嵌套样式),还可以通过style属性操作样式 (行内样式)。
同样的DOM对象可以通过className操作样式 (嵌套样式),也可以通过style属性操作样 (行内样式)。
css : 嵌套样式 => js : 类名 div.className = 'red';
css : 行内样式 => js : style对象 div.style.color = 'red';
1.样式属性初体验
//1. style 属性是一个对象, 里面存储了所有行内样式的键值对
//2. style属性只能获取和设置 ` 行内样式 ` , 在类样式中,嵌套样式通过style获取不到的
//3. 如果样式的名字带来-, 比如background-color, 到了 style对象中,变成了驼峰命名法 => backgroundColor (因为-在js中不是一个合法的标识符)
style设置的样式是行内样式,,因为优先级要高于className设置的样式 ; 所以会出现一个覆盖,以行内样式为准 (行内样式 > 嵌套样式)
<button>按钮</button>
<div style="color:red;background-color:blue;">小马哥</div>
//可以获取样式
console.log(div.style);
console.log(div.style.color);
// 也阔以通过这种方式设置
// 当时 css初始化 的属性
div.style.color ='red';
div.style.background = 'blue';
div.style.width = '200px';
div.style.height = '200px';
div.style.fontSize = '100px';
2.关于body的样式操作
1. document.body :body比较常用, 并且在页面中是唯一的, 因此可以使用document.body直接获取
// 可以通过qs获取,也可直接获取
2. document.documentElement : 可以获取html元素
3. document.head : 可以直接获取head元素
4. document.title : 可以直接获取title的文本
事件学习
1. 焦点事件 : onfocus 和 onblur 下的样式操作
-
onfocus : 当前元素 获得焦点 时会触发
onfocus
事件. -
onblur : 当前元素 失去焦点 时会触发
onblur
事件.
2. 鼠标事件 onmouseover 和 onmouseout 下的样式操作
on 当...时候 mouse : 鼠标 over:经过 out:离开
-
onmouseover : 当 鼠标在元素上方 会触发 onmouseover 事件.
-
onmouseout : 当 鼠标离开 会触发 onmouseout 事件.
关于cssText (了解)
使用cssText可以设置style的属性值
可以省略
<div style="width:100px;height:100px">哈哈哈</div>
//优点:可以一次性设置多个值
//缺点:会覆盖其他值 不利于阅读
var div = document.querySelector('div');
div.style.cssText = 'background:red;color:yellow';
节点(元素)操作 (超级重要)
1.节点属性 (了解)
节点分类:
元素节点、文本节点、属性节点、注释节点
节点常用的属性
-
childNodes : 获取所有的子节点
-
nodeType: 节点类型:元素节点 = 1 属性-2(过时) 注释-8 文本-3
-
nodeName: 节点名称
-
nodeValue: 节点值
<ul >
<!-- 下面是li -->
<li>导航1</li>
<li>导航2</li>
<li>导航3</li>
<li>导航4</li>
</ul>
// childNodes 子节点(们)
console.log(ul.childNodes);
console.log(ul.childNodes[1]);
2.节点查找 (重点)
孩子节点
//childNodes:获取所有的孩子节点(包括了元素节点和其他很多类型的节点,基本不常用)
★ children --- 获取所有的子元素(用途很广泛),兼容性:IE678会把注释节点算上。
//firstChild //第一个子节点 (基本不常用)
★ firstElementChild --- 第一个子元素 有兼容性问题(IE678)
//lastChild //最后一个节点 (基本不常用)
★ lastElementChild --- 最后一个子元素 有兼容性问题(IE678)
// 第几个元素
children[n] 第n个元素
<ul >
<!-- 下面是li -->
<li>导航1</li>
<li>导航2</li>
<li>导航3</li>
<li>导航4</li>
</ul>
兄弟节点
//1. nextSibling:下一个兄弟节点 (基本不常用)
★ 2. nextElementSibling:下一个兄弟元素(IE678不兼容)
//3. previousSibling//上一个兄弟节点 (基本不常用)
★ 4. previousElementSibling //上一个兄弟元素 有兼容性问题 可以封装一个兼容性方法
【附加:事件学习】
onkeydown : 当用户 按下键盘上按键 时会触发
onkeydown
事件.onkeyup : 在当前元素上 释放键盘按键 时会触发
onkeyup事件.
父亲节点
★ 1. parentNode:父节点 //没有兼容性问题
3.添加节点 (重点)
appendChild 在子元素的最后添加一个新元素
语法:parent.appendChild(newChild)
父元素.appendChild(子元素);
parent : 调用者,父节点来调用
newChild : 需要添加的那个孩子。
作用 :把newChild添加到parent的孩子的 最后面。 (就相当于生孩子一样,最后的孩子,都是最小的最靠后的)
注意 :: 如果添加的是页面中本来就存在的元素,是一个剪切的效果,原来的就不在了。
<div>
<li class="l1">我是li-1</li>
<li class="l2">我是li-2</li>
<li class="l3">我是li-3</li>
</div>
<hr>
<p class="other">我不是亲生的</p>
insertBefore : 放在某个元素之前
语法:parent.insertBefore(newChild, refChild);
parent:必须要父节点来调用
newChild:需要添加的那个节点
refChild:添加到哪一个节点的前面。
// 1. 拼接到最后 (常用)
div.appendChild(p);
// 2. 添加到s1之前 s2 s3之前 (常用)
div.insertBefore(p,s1);
// 3. 添加到最后一个
div.insertBefore(p,null);
// 4. 拓展 :非要添加在s2之后??
// insertAfter?? no
// p2.next
div.insertBefore(p,s2.nextElementSibling);
//5. 添加到父元素最前 (常用)
div.insertBefore(p,div.children[0]);
4.克隆节点 (重点)
语法:var newNode = 节点.cloneNode(deep)
功能:在内存中克隆一份节点
参数:false / true
-
false:默认值:是浅复制,只会复制标签,节点本身,不会复制节点的孩子。
-
true: 深度复制,会复制标签,还会复制标签的所有内容 常用
克隆出来的节点跟原来的节点没有关系了,修改了也不会相互影响。
如果克隆的节点带了id,我们需要给id重新设置一个值,不让id冲突
var newNode = div.cloneNode(true);
// false : 浅复制 只复制该元素
// true : 深复制 不仅复制该元素 还复制其子元素
console.log(newNode);
5.创建节点(3种方式) (重点)
document.write(基本不用)
可以生成新的节点,但是不推荐使用。如果页面已经加载完成了,你还是用document.write写内容的话,会把之前的页面给覆盖掉
原理:页面从上往下加载的时候,会开启一个文档流,当页面加载完,文档流就会关闭。
document.write的本意就是在文档流上写入内容。如果页面没加载完成,文档流还是开着的,document.write直接在这个文档流上写东西
如果页面加载完成了,还是用document.write写东西,会重新开启一个新的文档流,往新的文档流上写东西,旧的文档流就被新的文档流覆盖了。
window.onload = function () {
document.write('你妹')
}
innerHTML (偶尔用)
innerHTML也可以创建节点
innerHTML创建节点的时候有一个特点,如果原来有内容的话,使用innerHTML会把原先的内容给干掉。
慎用:很容易出现效率问题。
div.innerHTML = '<h1>哈哈</h1>'
createElement (常用)
语法:var element = document.createElement("tagName");
作用:在内存里面创建了一个节点
返回:一个元素
var div = document.querySelector('div')
var h1 = document.createElement('h1');
console.log(h1);
h1.style.background = 'red';
h1.innerText = '哈';
div.appendChild(h1);
6.删除节点 (重点)
语法:parent.removeChild(child);
解析 : 父元素.removeChild(子元素);
功能:有父盒子调用,删除里面的一个子元素。
//1 使用1 :
div.removeChild(p);
//2 使用2 :
p.parentNode.removeChild(p);
// 总结 : //1. 正常情况下可以使用 chilrdren //2. 如果涉及到删除等情况 querySelectorAll
7.替换节点
语法:parentNode.replaceChild(newChild, oldChild);
-
newChild
用来替换oldChild
的新节点,如果newChild
已经存在于DOM树中,则它会被从原始位置删除。
BOM
BOM(Browser Object Model):浏览器对象模型,提供了一套操作浏览器功能的工具。
BOM包含的内容很多,但是很多东西都不太常用,在BOM中需要大家掌握的大知识点就一个,那就是定时器 。 offset系列 还有一些其他小知识点
window
-
window对象是一个全局对象,也可以说是JavaScript中的顶级对象
-
像document、alert()、console.log()这些都是window的属性,其实BOM中基本所有的属性和方法都是属性window的。
-
所有定义在全局作用域中的变量、函数都会变成window对象的属性和方法
-
window对象下的属性和方法调用的时候可以省略window
window.onload(掌握)
window.onload事件会在窗体加载完成后执行,通常我们称之为入口函数。
window.onload = function(){
//里面的代码会在 `窗体加载`完成后执行。
// `窗体加载` 完成包括文档树(DOM html)的加载、还有图片、文件的加载完成。
}
如果有图片加载,那么代码一定要写到window.onload里面,否则会出现图片没有加载完成,获取到的宽度和高度不对的情况。
浏览器会对页面的加载做优化,在加载图片的时候,图片的引入会延迟。
<img src="./01.png" alt="">
window.onload = function () {
var img = document.querySelector('img');
console.log(img.width);
console.log(img.height);
}
//1.img也不能写在script的后面
//2.要写在window.onload的里面
window.open与window.close(了解)
window.open() 打开一个窗口
//语法:window.open(url, [name], [features]);
//参数1:需要载入的url地址
//参数2:新窗口的名称或者targt属性
//_blank:如果指定为_blank,表示在新的窗口打开
//参数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(callback,time)
// 参数1: 回调函数, 时间到了就会执行
// 参数2: 延时的时间 毫秒为单位 1s = 1000毫秒
// 返回 : 定时器的id,用于清除
var timer = setTimeOut(function(){
//1秒后将执行的代码。
}, 1000);
清除延时器
//语法 : clearTimeOut(timeerId)
//参数 : 定时器id
// 示例 :
clearTimeOut(timer) ; // 清除上面定义的定时器
setInterval 定时器
setInterval 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间间隔。 (每隔一段时间执行一段代码)
定时器除非清除,否则会一直执行下去。
设置定时器
// 语法 :var timerId = setInterval(func,dealy);
// 参数1 : 重复执行的函数
// 参数2 : 每次间隔的毫秒数
// 返回 : 定时器的id, 用于清除
// 示例 :
var timer = setInterval(function(){
//重复执行的代码
},1000);
清除定时器
//语法 : clearInterval(intervalId);
//参数 : 定时器id
// 示例 :
clearInterval(timerId) // 清除上面的定时器
location 对象
location 对象也是window的一个属性;
location 其实对应的就是浏览器中的地址栏
常用属性和方法
location.href : 控制地址栏的地址
location.href='http://www.baidu.com'; // 让页面跳转到百度首页
location.reload() ; 让页面重新加载
location.reload() ; // 刷新
location的其他值
http://www.xmg.com:8080/index.html?id=666&psd=123#xxx
- location.hash //哈希值 其实就是锚点 ==> #xxx
- location.host //服务器 服务器名+端口号 => www.xmg.com:8080
- location.hostname //服务器名 => www.xmg.com
- location.pathname //路径名 => index.html
- location.port //端口 => 8080
- location.protocol //协议 => http
- location.search //参数 => ?id=666&psd=123
其他对象
history对象表示页面的历史
// 随便打开一个网页 可以演示
//后退:
history.back();
history.go(-1);
//前进:
history.forward();
history.go(1);
screen 对象
console.log(screen.width);//屏幕的宽度
console.log(screen.height);//屏幕的高度
console.log(screen.availWidth);//浏览器可占用的宽度
console.log(screen.availHeight);//浏览器可占用的高度
offset系列 (重要)
offset系列用于用于获取元素自身的大小和位置,在webapi中有广泛应用offset系列主要有:offsetHeight、offsetWidth、offsetParent、offsetLeft、offsetTop
offsetHeight与offsetWidth
offsetHeight与offsetWidth
1. 获取的是元素真实的高度和宽度
2. 获取到的是数值类型,方便计算
3. offsetHeight与offsetWidth是只读属性,不能设置。
style.height与style.width
1. 只能获取行内样式
2. 获取到的是字符串类型,需要转换
结论
1. 设置宽度高度使用style.width与style.height
2. 获取宽度和高度offsetWidth与offsetHeight
offsetParent
parentNode和offsetParent
1. parentNode始终是父元素
2. offsetParent是离当前元素最近的定位元素(absolute、relative),如果没有,那就找body
offsetLeft与offsetTop
offsetLeft: 自身左侧到offsetParent左侧的距离:left + margin-leftoffsetTop:自身顶部到offsetParent顶部的距离 : top + margin-top
offsetLeft与offsetTop
1. 元素自身与offsetParent真实的距离
2. 获取到的是数值类型,方便计算
3. 只读属性,只能获取,不能设置
style.left与style.top
1. 只能获取行内样式
2. 获取到的是字符串,需要转换
3. 可以获取,也可以设置
结论
获取操作:用offset系列 ==> 数值类型
设置操作:用style.xxx进行设置。 ==> 字符串类型
动画函数封装
了解一下思路, 以后都是用封装好的
div:hover {
transition: all 4s;
transform: translateX(400px);
}
动画初体验 (单方向移动)
var timeId = setInterval(function () {
var step = 10;
var current = div.offsetLeft;
//只有当当前的位置小于目标的位置的时候,才能走
if(current < 400) {
current += step;
div.style.left = current + "px";
}else {
clearInterval(timeId);
}
}, 15);
动画函数 (双方向移动)
//3. 回到原点
btn1.onclick = function () {
var timerId = setInterval(function () {
//1. 获取当前位置
var current = div.offsetLeft;
var step = -9;
var target = 0;
if (current > target) {
//2. 累加小碎步
current += step;
//3. 重新赋值
div.style.left = current + 'px';
}else {
clearInterval(timerId);
}
},15);
}
动画函数封装
step : 决定的是方向
关系什么时候会走? 目标距离-现在距离的之间的鹅距离只要大于一个步数, 就可以累加跳
也不可以 400-200 >9 可以 但是 0-200 >-9 就不对 需要移动,,我们要看的距离
不够一步的直接等于即可
一个对象添加了两个定时器是不好的,连续点会乱, 给对象添加一个timerId值,,这样的话
每个元素只能绑定一个,如果多点了把之前的取消掉即可
//动画函数封装
function animate(element, target) {
if(element.timeId) {
clearInterval(element.timeId);
}
element.timeId = setInterval(function () {
var current = element.offsetLeft;
var step = current < target ? 10 : -10;
//当目标位置距离当前位置的距离超过一步的时候,继续走
if (Math.abs(target - current) >= Math.abs(step)) {
current += step;
element.style.left = current + "px";
} else {
clearInterval(element.timeId);
}
}, 15);
}
事件对象
事件对象的概述
在触发某个事件的时候,都会产生一个事件对象Event,这个对象中包含所有与事件相关的一些信息,包括触发事件的元素,事件的类型以及其他与事件相关的信息。
鼠标事件触发时,事件对象中会包含鼠标的位置信息。
键盘事件触发时,事件对象中会包含按下的键相关的信息。
获取事件对象
现代浏览器获取 : (掌握)
// 给一个形参即可
btn.onclick = function(event){
//event就是事件对象,里面包含了事件触发时的一些信息。
console.log(event);
}
低版本浏览器 (ie678): (了解)
btn.onclick = function(){
//IE678通过window.event获取事件对象
console.log(window.event);
}
兼容性 :
btn.onclick = function(event){
//只要用到了事件对象,就要记得处理浏览器兼容性
event = event || window.event;
}
事件对象的常用属性
事件对象中有很多很多的属性,但是很多属性并不常用。我们经常用到的是鼠标位置信息 和键盘码 相关的信息。
(一)记录了鼠标位置信息的相关属性
-
clientX与clientY: 相对于浏览器可视区左上角的位置 (常用)光标相对于可视区左上角的水平位置和垂直位置。
-
pageX与pageY:相对于网页内容左上角的位置光标相对于网页(文档document)左上角的水平位置与垂直位置
-
screenX与screenY:相对于屏幕左上角的位置光标相对于屏幕左上角的水平位置与垂直位置。
document.onclick = function (e) {
//获取事件对象
//clientX clientY :获取的是鼠标在可视区的位置
//pageX pageY :获取的是鼠标在整个页面中的位置: 包括scrollTop
//screenX scrennY :获取在屏幕中的位置
console.log(e.clientX, e.clientY);
console.log(e.pageX, e.pageY);
console.log(e.screenX, e.screenY);
}
(二)记录了键盘码的属性
事件学习:
onkeydown : 键盘按下
onkeyup : 键盘抬起
适用于document和input等等
event.keyCode:键盘按下的那个键的键盘码
注册事件的两种方式
1.on + 事件名称
onclick、onmouseover这种on+事件名称的方式注册事件几乎所有的浏览器都支持。
注册事件:
box.onclick = function(){
//事件处理程序
}
移除事件:
box.onclick = null;
缺点:
同一个元素同一类型的事件,只能注册一个,如果注册了多个,会出现覆盖问题。
2.注册事件的新方式 : addEventListener
现代浏览器支持的注册事件的新方式,这种方式注册的事件不会出现覆盖问题。
addEventListener的语法
//第一个参数:事件的类型:click mouseover
//第二个参数:函数,监听者,每次点击,这个函数就执行。
element.addEventListener(type, func);
btn.addEventListener('click',function () {
console.log(111);
})
removeEventListen的语法
//第一个参数:参数类型
//第二个参数:要移除的那个函数
element.removeEventListener(type, func);
btn.removeEventListener('click',fn);
// 注意 : 如果想让注册的事件能移除,不能用匿名函数。
低版本浏览器兼容问题: (了解)
IE678不支持addEventListener与removeEventListen两个方法,但是支持attachEvent与detachEvent
attachEvent的用法:
//type:事件类型 需要加上on onclick onmouseenter
//func:需要执行的那个事件
attachEvent(type, func)
//代码:
var btn = document.getElementById('btn');
btn.attachEvent('onclick',function () {
alert(1)
});
detachEvent的用法
//type:事件类型 需要加上on onclick onmouseenter
//func:需要执行的那个事件
detachEvent(type, func)
兼容性封装(了解)
//添加事件
function addEvent(element, type, fn){
//能力检测
if(element.addEventListener){
element.addEventListener(type, fn, false);
}else if(element.attachEvent){
element.attachEvent("on"+type, fn);
}else {
//如果都不行,那就用on方式
element["on"+type] = fn;
}
}
//移除事件
function removeEvent(element, type, fn) {
if(element.removeEventListener){
element.removeEventListener(type, fn, false);
}else if(element.detachEvent){
element.detachEvent("on"+type, fn);
}else {
element["on"+type] = null;
}
}
事件流
事件冒泡
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为冒泡
说白了就是:当我们触发了子元素的某个事件后,父元素对应的事件也会触发。
拓展 : 阻止事件冒泡 (掌握)
代码 : event.stopPropagation();
//1. 因为是事件的冒泡,,因事件引起,也要因事件停止
father/son/sun.onclick = function (event) {
//stop :停止 propagation:传播
event.stopPropagation();
}
// onclick : 默认就是 第三个参数为 false:
father.addEventListener('click',function(){
alert('father');
},false);
// a 跳转
// return false;
事件捕获 (了解)
事件冒泡 是 ie 提出来的
路径 : 触发事件的目标元素(sun) > son > father > body > document
事件捕获是火狐提出来的
路径 : document > body > father > son > 触发事件的目标元素 (sun)
解析 : 事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递
//当addEventListener第三个参数为true时,表示事件捕获
// 参数3 : 是否捕获
arr[i].addEventListener("click", function () {
console.log(this);
},true);
事件的三个阶段 (掌握)
事件的捕获阶段
事件的目标阶段(触发自己的事件)
事件的冒泡阶段
事件有三个阶段 :
-
捕获事件和冒泡事件都存在 的话 , 首先发生的是捕获阶段, 然后 是目标阶段,,最后才是冒泡阶段,
-
addEventListener 第三个参数为是否捕获 ,
-
如果为true时, 表示该事件在捕获阶段发生,
-
如果为false时 , 表示该事件在冒泡阶段发生
-
某一个事件只会执行一次
代码演示 :
// addEventListener 第三参数 是否捕获,,true : 捕获,,false:冒泡
document.addEventListener('click',function () {
alert('document')
},true);
document.body.addEventListener('click',function () {
alert('body')
},false);
father.addEventListener('click',function () {
alert('father')
},true);
son.addEventListener('click',function () {
alert('son')
},false);
sun.addEventListener('click',function () {
alert('sun')
},true);
常见的事件
1.常见的鼠标事件
-
onclick:单击事件
-
ondblclick:双击事件
-
onmouseover:鼠标经过事件
-
onmouseout:鼠标离开事件
-
onmousemove:鼠标移动事件
-
onfocus:获得焦点事件
-
onblur:失去焦点事件
-
onmousedown:鼠标按下事件
-
onmouseup:鼠标弹起事件
son.onmousemove = function (e) {
// 到浏览器可视区左侧的距离
console.log(e.clientX);
}
2.常见的键盘事件
onkeydown:键盘按下时触发
onkeypress : 键盘按下时触发
onkeyup:键盘弹起时触发
三大家族
offset家族 (都掌握)
offset系列用于用于获取元素自身的大小和位置 ,在网页特效中有广泛应用
offset家族主要有:offsetHeight、offsetWidth、offsetParent、offsetLeft、offsetTop
offsetHeight与offsetWidth
-
获取的是元素真实的高度和宽度
-
获取到的是数值类型,方便计算
-
offsetHeight与offsetWidth是只读属性,不能设置。
style.height与style.width
-
只能获取行内样式
-
获取到的是字符串类型,需要转换
总结
//0. 要求 : 都要掌握
//1. 获取以后用 : offsetWidth 和 offsetheight
(内容大小+border+padding)
//2. 设置以后用 : style.width 和 style.height
scroll家族 (掌握1个)
scroll家族是用来获取盒子内容的大小和位置
scroll 家族主要有 : scrollWidth、scrollHeight、scrollLeft、scrollTop
scrollWidth与scrollHeight
-
scrollWidth与scrollHeight是盒子内容的真实的宽度和高度。与和盒子大小无关,仅仅与盒子的内容有关系。 (padding + 内容)
-
如果内容不超过盒子,盒子高度就是 scrollHeight ,(宽度同理)
-
如果内容超过盒子, 内容高度 就是scrollHieght
scrollTop 被浏览器卷去的高度
-
scrollTop用于获取内容垂直滚动的像素数。如果没有滚动条,那么scrollTop值是0
-
给内容超过盒子, 盒子设置 overflow:scroll 就可出现滚动条
scrollLeft
-
scrollLeft用于获取内容水平滚动的像素数
-
演示可以使用内容只是纯字母的
-
浏览器切忌这种出现水平滚动条,用户体验极差,避免
onscroll 事件
对于有滚动条的盒子, 可以使用onscroll注册滚动事件,,每滚动一像素,就会触发该事件
var div = doucment.getElementById(“div”);
div.onscroll = function(){
console.log(div.scrollLeft);
console.log(div.scrollTop);
}
总结 :
//1. 要求 : 掌握 scrollTop 和 onscroll 事件
场景 : 获取页面被卷去的高度和宽度
通常来说,scroll家族用的最多的地方就是用来获取页面被卷去的高度,非常的常用
-
对于老式的浏览器,需要获取html或者body的scrollTop
-
对于现在浏览器,使用window.pageYOffset进行获取
页面被卷去的高度和宽度的兼容性封装
// 给整个页面注册滚动事件
document.onscroll = function() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0
}
client家族
client家族用于获取盒子可视区的大小
client家族有clientWidth、clientHeight、clientLeft、clientTop
clientWidth、clientHeight 可视区宽高
三大家族对比
clientTop与clientLeft 完全没有用,他们就是borderTop与borderLeft
onresize事件:onresize事件会在窗口被调整大小的时候发生。
window.onresize = function(){
//事件处理程序
}
场景 : client系列一般用来获取页面的可视区宽高
// 因为求的是窗口大小所以用window
window.onresize = function () {
var W = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
console.log(W);
var H = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
console.log(H);
}
大总结
offset家族 : 真实宽高和位置
1. width : 内容 + border + padding;
2. offsetWidth : 真实宽度
3. offsetHeight :真实高度
4. offsetLeft : 真实左侧距离
5. offsetTop : 真实顶部距离
使用 :
1. 获取 offset系列
2. 设置 style系列
scroll家族 : 内容大小
1. scrollTop : 被页面卷去的高度
2. div.onscroll : 给div注册滚动事件 (前提是有滚动条)
3. window.onscroll : 给整个页面注册滚动事件
4. 获取 被页面卷去的高度
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
5. 重点掌握 : pageYOffset
client 家族 可视区域大小
1.window.onresize onresize事件会在窗口被调整大小的时候发生。
2. 可视区域大小 : window.innerWidth