疑问:event事件对象
冒泡和捕获还有点疑问
1.offset家族
Offset家族简介
offset这个单词本身是--偏移,补偿,位移的意思。
js中有一套方便的获取元素尺寸的办法就是offset家族;
offsetWidth和offsetHight 以及offsetLeft和offsetTop以及offsetParent
共同组成了offset家族。
offsetWidth和offsetHight (检测盒子自身宽高+padding+border)
这两个属性,他们绑定在了所有的节点元素上。获取之后,只要调用这两个属性,我们就能够获取元素节点的宽和高。
offset宽/高 = 盒子自身的宽/高 + padding +border;
offsetWidth = width+padding+border;
offsetHeight = Height+padding+border;
offsetLeft和offsetTop (检测距离有定位的父盒子的左/上面的距离)
返回距离上级盒子(带有定位)左边的位置
如果父级都没有定位则以body为准
offsetLeft 从父亲的padding 开始算,父亲的border 不算。
在父盒子有定位的情况下,offsetLeft == style.left(去掉px)
offsetParent (检测父系盒子中带有定位的父盒子节点)
1、返回改对象的父级 (带有定位)
如果当前元素的父级元素没有进行CSS定位 (position为absolute或 relative,fixed), offsetParent为body。
如果当前元素的父级元素中有CSS定位 (position为absolute或 relative,fixed), offsetParent取最近的那个父级元素。
offsetLeft和style.left区别
最大区别在于offsetLeft可以返回没有定位盒子的距离左侧的位置。
而 style.left不可以,offset只能与行内式进行互动,其余取不到值。
二、offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。
三、offsetTop 只读,而 style.top 可读写。(只读是获取值,可写是赋值)
四、如果没有给 HTML 元素指定过 top 样式,则style.top 返回的是空字符串。
style.left在=的左边和右边还不一样。(左边的时候是属性,右边的时候是值)
<div class="box1">
<div class="box3">
<div class="box2" style="left: 10px"></div>
</div>
</div>
<script>
var box2 = document.getElementsByClassName("box2")[0];
//offsetTop和offsetLeft
console.log(box2.offsetLeft);
console.log(box2.style.left);
// 一、最大区别在于offsetLeft可以返回没有定位盒子的距离左侧的位置。
//如果父系盒子中都没有定位,以body为准。
//style.left只能获取行内式,如果没有返回“”;
// 二、offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。
//div.offsetLeft = 100; div.style.left = "100px";
// 三、offsetTop 只读,而 style.top 可读写。(只读是获取值,可写是赋值)
//style.left和style.top可以赋值
//offsetLeft和offsetTop只能获取值
// 四、如果没有给 HTML 元素指定过 top 样式,则style.top 返回的是空字符串。
//style.left只能获取行内式,如果没有返回“”;
</script>
2.动画和封装
1匀速动画原理:
1.1
盒子未来的位置 = 盒子现在的位置 + 步长;
style.left赋值,用offsetLeft获取值。
style.left获取值不方便,获取行内式,如果没有是“”;容易出现NaN;
offsetLeft获取值特别方便,而且是现成number方便计算。因为他是只读的不能赋值。
1.2.要用定时器,先清除定时器
动画原理: 盒子未来的位置 = 盒子现在的位置 + 步长;
动画原理中的target不是指两者距离多远,而是要移动到的位置距离最初原始位置的距离,
这个值根据页面布局原则来判断正负。
2.缓动动画原理
2.1三个函数
都是在数轴上向上或者向下取整。
Math.ceil() 向上取整
Math.floor() 向下取整
Math.round(); 四舍五入
2.2缓动动画原理
leader=leader+(target-leader)/10;
盒子位置 = 盒子本身位置+(目标位置-盒子本身位置)/ 10;
动画原理 = 盒子位置 + 步长(步长越来越小)。
2.3 offset取值问题
<div style="position: absolute;left: 396.5px"></div>
<script>
var div = document.getElementsByTagName("div")[0];
console.log(div.style.left);//396.5px
console.log(div.offsetLeft);//397
</script>
offsetLeft会四舍五入。
3.匀速动画封装
function animate(ele,target){
//要用定时器,先清除定时器
//一个盒子只能有一个定时器,这样儿的话,不会和其他盒子出现定时器冲突
//而定时器本身讲成为盒子的一个属性
clearInterval(ele.timer);
//我们要求盒子既能向前又能向后,那么我们的步长就得有正有负
//目标值如果大于当前值取正,目标值如果小于当前值取负
var speed = target>ele.offsetLeft?10:-10;
ele.timer = setInterval(function () {
//在执行之前就获取当前值和目标值之差
var val = target - ele.offsetLeft;
ele.style.left = ele.offsetLeft + speed + "px";
//目标值和当前值只差如果小于步长,那么就不能在前进了
//因为步长有正有负,所有转换成绝对值来比较
if(Math.abs(val)<Math.abs(speed)){
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},30)
}
4.缓动动画封装
缓动。如何缓动呢?步长越来越小....
步长用目标位置和盒子自身位置的十分之一
//缓动动画封装
function animate(ele,target) {
//要用定时器,先清定时器
//一个萝卜一个坑儿,一个元素对应一个定时器
clearInterval(ele.timer);
//定义定时器
ele.timer = setInterval(function () {
//获取步长
//步长应该是越来越小的,缓动的算法。
var step = (target-ele.offsetLeft)/10;
//对步长进行二次加工(大于0向上取整,小于0项下取整)
step = step>0?Math.ceil(step):Math.floor(step);
//动画原理: 目标位置 = 当前位置 + 步长
ele.style.left = ele.offsetLeft + step + "px";
//检测缓动动画有没有停止
console.log(1);
if(Math.abs(target-ele.offsetLeft)<=Math.abs(step)){
//处理小数赋值
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},30);
}
3.第二系列scroll
Scroll家族组成
ScrollWidth和scrollHeight(不包括border)
检测盒子的宽高。(调用者:节点元素。属性。)
盒子内容的宽高。(如果有内容超出了,显示内容的高度)
IE567可以比盒子小。 IE8+火狐谷歌不能比盒子小.
也就是说//IE8以下,不包括IE8为盒子本身内容的多少。
scrollTop和scrollLeft
网页,被浏览器遮挡的头部和左边部分。
被卷去的头部和左边部分。
有兼容性问题
function scroll(){
//如果这个属性存在,那么返回值应该是0-无穷大
//如果没有返回值是undefined;
//只要判断不是undefined就可以调用此方法
//练习使用此种封装
if(window.pageYOffset !== undefined){
return {
"top": window.pageYOffset,
"left": window.pageXOffset
};
}else if(document.compatMode === "CSS1Compat"){
return {
"top": document.documentElement.scrollTop,
"left": document.documentElement.scrollLeft
};
}else{
return {
"top": document.body.scrollTop,
"left": document.body.scrollLeft
};
}
}
获取title、body、head、html标签
document.title --- 文档标题;
document.head --- 文档的头标签
document.body --- 文档的body标签;
document.documentElement --- 这个很重要
它表示文档的html标签, 也就是说,基本结构当中的html标签并不是通过document.html 去访问的,而是document.documentElement 。
Json知识点
Json是一种和数组类似的数据类型。
不同的是:数组中的元素是单一的。
而json中的元素,是以键值对的形式出现的。(key: value)
定义方法
var json = { key1:value1,key2:value2,key3:value3... };
数组是通过索引值获取数组中的元素的,而json是通过key获取元素的。
获取内容
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,我们称之为JavaScript对象表示法。使用JSON进行数据传输的优势之一。表示方法为键值对,key:value。
var myjson={k1:v1,k2:v2,k3:v3...}
获取方式:v1 == myjson.k1 v2 == myjson.k2
Json一般就是被当做一个配置单用;
Json的遍历(了解)
用的是新的语法方法:for ... In ....
获取方式:myjson[key];
scrollTop方法封装
function scroll() { // 开始封装自己的scrollTop
if(window.pageYOffset != null) { // ie9+ 高版本浏览器
// 因为 window.pageYOffset 默认的是 0 所以这里需要判断
return {
left: window.pageXOffset,
top: window.pageYOffset
}
}
else if(document.compatMode === "CSS1Compat") { // 已经声明
标准浏览器
来判断有没有声明DTD
return {
left: document.documentElement.scrollLeft,
top: document.documentElement.scrollTop
}
}
return { // 未声明 DTD
left: document.body.scrollLeft,
top: document.body.scrollTop
}
}
///////////8.9
4.小知识
onscroll事件
window.onscroll = function(){
}
只要页面滚动无论向左向右,向上向下,哪怕只有1px,都会触动这个事件
屏幕跳转
window.scrollTo
方法可把浏览器内容滚动到指定的坐标。
格式:
scrollTo(xpos,ypos)
xpos 必需。要在窗口文档显示区左上角显示的文档的 x 坐标。
ypos 必需。要在窗口文档显示区左上角显示的文档的 y 坐标
CSS特点
100%子盒子会继承父盒子的宽高。父盒子继承body宽高。Body继承html的宽高。
盒子属性:auto:适应盒子自身的宽度或者高度。(对自己负责)
盒子属性:100%:适应盒子父盒子的宽度或者高度。(对爸爸负责)
5.事件对象(event)
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象,但支持的方式不同。
比如鼠标操作时候,会添加鼠标位置的相关信息到事件对象中。(类似Date)
普通浏览器支持 event(带参,任意参数)
ie 678 支持 window.event(无参,内置)
总结:他是一个事件中的内置对象。内部装了很多关于鼠标和事件本身的信息。
事件对象的获取(event的获取)
IE678中,window.event
在火狐谷歌中,event或者,在事件绑定的函数中,加参,这个参数就是event.
Box.onclick = function (aaa){ aaa就是event }
兼容获取方式有两种:
不写参数直接使用event;
写参数,但是为event....var event = event || window.event;(主要用这种)
event内容重要内容
screenX、pageX和clientX的区别
PageY/pageX: 鼠标位于整个网页页面的顶部和左侧部分的距离。(页面)body
ScreenY/screenX: 鼠标位于屏幕的上方和左侧的距离。(屏幕)电脑屏幕
ClientX/clientY: 鼠标位于浏览器的左侧和顶部的距离。(浏览器大小和位置)浏览器可视区域
PageY和pageX的兼容写法(很重要)
在页面位置就等于 = 看得见的+看不见的
pageY/pageX=event.clientY/clientX+scroll().top/scroll().left
例子:
document.onclick = function (event) {
event = event || window.event;
鼠标点击事件,鼠标距离屏幕可视区域的距离clientY,鼠标距离屏幕的距离是screenY。
console.log(event.pageY);//body ,距离整个页面。
console.log(event.screenY);//屏幕
console.log(event.clientY);//浏览器可视区域
}
新事件(onmousemove)
只要鼠标在绑定该事件的事件源上移动,哪怕1像素,也会触动这个事件。
(这个事件可以直接或者间接的替代定时器)
6.第三大家族client
主要成员
1、clientWidth 获取网页可视区域宽度(两种用法)
clientHeight 获取网页可视区域高度(两种用法)
调用者不同,意义不同:
盒子调用: 指盒子本身。
body/html调用: 可视区域大小。
2、clientX 鼠标距离可视区域左侧距离(event调用)
clientY 鼠标距离可视区域上侧距离(event调用)
3、clientTop/clientLeft 盒子的border宽高
三大家族区别(三大家族总结)
Width和height
clientWidth = width + padding
clientHeight = height + padding
offsetWidth = width + padding + border
offsetHeight = height + padding + border
scrollWidth = 内容宽度(不包含border)
scrollHeight = 内容高度(不包含border)
top和left
offsetTop/offsetLeft :
调用者:任意元素。(盒子为主)
嘛作用:距离父系盒子中带有定位的距离。
scrollTop/scrollLeft:(盒子也可以调用,必须有滚动条)
调用者:document.body.scrollTop/.....(window)
嘛作用:浏览器无法显示的部分(被卷去的部分)。
clientY/clientX:(clientTop/clientLeft 值的是border)
是指:事件被触发时鼠标指针向对于浏览器页面的距离。
调用者:event.clientX(event)
嘛作用:鼠标距离浏览器可视区域的距离(左、上)。
client家族特殊用法之:
检浏览器宽/高度(可视区域)
function client(){
if(window.innerHeight !== undefined){
return {
"width": window.innerWidth,
"height": window.innerHeight
}
}else if(document.compatMode === "CSS1Compat"){
return {
"width": document.documentElement.clientWidth,
"height": document.documentElement.clientHeight
}
}else{
return {
"width": document.body.clientWidth,
"height": document.body.clientHeight
}
}
}
Onresize事件
只要浏览器的大小改变,哪怕1像素,都会触动这个事件。
案例:根据浏览器可视区域大小,给定背景色
事件总结
区分:
1.window.onscroll 屏幕滑动
2.window.onresize 浏览器大小变化
3.window.onload 页面和图片加载完毕
4.div.onmousemove 鼠标在盒子上移动
(注意:不是盒子移动!!!)
5.onmouseup/onmousedown == onclick
获得屏幕宽高
window.screen.width
分辨率是屏幕图像的精密度,指显示器所能显示的像素有多少。
我们的电脑一般:
横向1280个像素点,
纵向960个像素点。
我们看电影的时候是满屏和半屏的,就是这。
7.事件冒泡和捕获的彻底弄懂
冒泡
事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。(BUG)
(本来应该一人做事一人当,结果,我做错了事情,你去告诉我妈)
什么是冒泡:子元素事件被触动,父盒子的同样的事件也会被触动。
取消冒泡就是取消这种机制。
阻止冒泡
w3c的方法是:(火狐、谷歌、IE11)
event.stopPropagation()
IE10以下则是使用:event.cancelBubble = true
兼容代码如下:
var event = event || window.event;
if(event && event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
取消之后,当盒子有相关动作时,父盒子的相同动作没有反应。
谁触动事件,会被放进target中。
console.log(event.target);
addEventListenner(参数1,参数2,参数3)
调用者是:事件源。 参数1:事件去掉on 参数2 :调用的函数
参数3:可有可无。没有默认false.false情况下,支持冒泡。True支持捕获。
目标元素是指:事情发生的那个元素,冒泡先从目标元素的事件找起,如果没有,就往父元素走,找元素的方法。
捕获是指:目标元素即使被点中了,也是从父元素中相同方法中开始运行,然后往目标元素走。
冒泡是从目标元素往父元素走,捕获是从祖宗元素开始往目标元素走;两个都有的话先捕获再冒泡。
冒泡机制来处理事件委托,帮助那些新建立的节点还没来得及建方法的,建立方法。
ul.onclick = function (event) {
获取事件触动的时候传递过来的值
event = event || window.event;
var aaa = event.target?event.target:event.srcElement;
判断标签名,如果是li标签弹窗
if(aaa.tagName === "LI"){
alert("我是li");
}
}
Document事件的绑定,无论绑定什么事件,只要事件被出发,传递过来的应该是指定的元素本身,而不是document。(有疑问)
8.封装框架遇到的CSS获取值问题
1.知识点回顾:
样式表有三种方式:
内嵌样式(inline Style) :是写在Tag里面的,内嵌样式只对所有的Tag有效。 (也称作“内联样式”)
内部样式(internal Style Sheet):是写在HTML的里面的,内部样式只对所在的网页有效。
外部样式表(External Style Sheet):如果很多网页需要用到同样的样式(Styles),将样式(Styles)写在一个以.css为后缀的CSS文件里,然后在每个需要用到这些样式(Styles)的网页里引用这个CSS文件。 最常用的是style属性,在JavaScript中,通过document.getElementById(id).style.XXX就可以获取到XXX的值,但意外的是,这样做只能取到通过内嵌方式设置的样式值,即style属性里面设置的值。
2.原有的方法:div.style.width :这个方法比较固定,不能用变量或者字符串的形式更换属性,不方便我传值获取属性,和给属性赋值。
属性值的获取和属性的赋值
div.style["width"] = "5000px";
可以通过传字符串或者变量的方式获取和赋值属性。
缺点:他的操作完全是对行内式CSS来操作的。赋值的时候毫无问题。但是,获取值的时候有问题了。
3.获取任意类型的CSS样式的属性值
Div.style.width
div.currentStyle.width
Window.getComputedStyle(div,null).width;
他们的公共使用变量或者字符串获取属性值的方法都是:去电属性和点,然后加上中括号和属性的字符串形式。
Div.style[“width”];
div.currentStyle[“width”];
Window.getComputedStyle(div,null)[“width”];
4.重点
style:各大浏览器都兼容,能设置样式和获取样式,但是获取不了外部样式,如果写了行内没有的样式,返回的是空值。
写法:ele.style.attr(这样为获取),ele.style.attr="值";
currentStyle:该属性只兼容IE,不兼容火狐和谷歌。
写法:ele.currentStyle["attr"]或者ele.currentStyle.attr;
getComputedStyle:该属性是兼容火狐谷歌,不兼容IE。
写法:window.getComputedStyle(ele,null)[attr]获取是window.getComputedStyle(ele,null).attr
currentStyle属性和getComputedStyle属性不能设置属性,只能获取
5.getComputedStyle
getComputedStyle
是一个可以获取当前元素所有最终使用的CSS属性值。
语法如下:
var style = window.getComputedStyle("元素", "伪类");
例子:
var dom = document.getElementById("test"),
style = window.getComputedStyle(dom , ":after");
就两个参数,大家都懂中文的,没什么好说的。只是额外提示下:Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) 之前,第二个参数“伪类”是必需的(如果不是伪类,设置为null
),不过现在嘛,不是必需参数了。
6.所有获取css的兼容性写法
function getStyle(ele,attr){
if(window.getComputedStyle){
return window.getComputedStyle(ele,null)[attr];
}
return ele.currentStyle[attr];
}
例子:
获取行内式和内嵌式
console.log(typeof window.getComputedStyle(div,null));
console.log(window.getComputedStyle(div,null).border);
console.log(window.getComputedStyle(div,null)["background-color"]);
console.log(window.getComputedStyle(div,null));
console.log(div.currentStyle.padding);
console.log(div.currentStyle["background-color"]);
9.正则定义
(1.内置对象法。 2.字面量)
1.对象定义法
var reg1 = new RegExp(/abc/);
2.字面量[]{}/a/
var reg2 = /def/;
console.log(reg2);
console.log(typeof reg2);
使用:test();正则表带是有一个方法,test,有一个返回值是bool类名,决定参数是否符合正则表达式
console.log(reg1.test("abc"));
console.log(/abc/.test("hjkl"));