JS学习笔记4-JS特效

疑问: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"));

 

猜你喜欢

转载自blog.csdn.net/jerryken0204/article/details/80846762
今日推荐