From 9411527deb3a8b3575d894db4ad1860b06a399f8 Mon Sep 17 00:00:00 2001 From: qianguyihao Date: Sun, 4 Feb 2018 17:07:25 +0800 Subject: [PATCH] add files --- ...06-JavaScript语法基础:面向对象和内置对象.md | 27 +- .../09-JavaScript基础:事件对象Event和冒泡.md | 698 ++++++++++ 03-JavaScript基础/09-事件.md | 144 -- .../06-DOM操作练习:通过style对象设置样式.md | 97 ++ .../01-offset家族和匀速动画(含轮播图的实现).md | 2 +- 06-JavaScript进阶/02-scroll家族和缓动动画.md | 1162 +++++++++++++++++ 06-JavaScript进阶/02-缓动动画.md | 55 - 06-JavaScript进阶/03-client家族(可视区).md | 178 +++ 8 files changed, 2162 insertions(+), 201 deletions(-) create mode 100644 03-JavaScript基础/09-JavaScript基础:事件对象Event和冒泡.md delete mode 100644 03-JavaScript基础/09-事件.md create mode 100644 06-JavaScript进阶/02-scroll家族和缓动动画.md delete mode 100644 06-JavaScript进阶/02-缓动动画.md create mode 100644 06-JavaScript进阶/03-client家族(可视区).md diff --git a/03-JavaScript基础/06-JavaScript语法基础:面向对象和内置对象.md b/03-JavaScript基础/06-JavaScript语法基础:面向对象和内置对象.md index f983fe0..f509122 100644 --- a/03-JavaScript基础/06-JavaScript语法基础:面向对象和内置对象.md +++ b/03-JavaScript基础/06-JavaScript语法基础:面向对象和内置对象.md @@ -181,7 +181,7 @@ console.log(o); 20180125_1834.png -**json的介绍:** +### json的介绍 > 对象字面量和json比较像,这里我们对json做一个简单介绍。 @@ -206,6 +206,31 @@ json举例: 另外,对象和json没有长度,json.length的打印结果是undefined。于是乎,自然也就不能用for循环遍历(因为便利时需要获取长度length)。 +**json遍历的方法:** + +json 采用 `for...in...`进行遍历,和数组的遍历方式不同。如下: + + +```html + +``` + +打印结果: + +20180203_1518.png ## 类和对象 diff --git a/03-JavaScript基础/09-JavaScript基础:事件对象Event和冒泡.md b/03-JavaScript基础/09-JavaScript基础:事件对象Event和冒泡.md new file mode 100644 index 0000000..b66c65d --- /dev/null +++ b/03-JavaScript基础/09-JavaScript基础:事件对象Event和冒泡.md @@ -0,0 +1,698 @@ + + +> 本文最初发表于[博客园](http://www.cnblogs.com/smyhvae/p/8413602.html),并在[GitHub](https://github.com/smyhvae/Web)上持续更新**前端的系列文章**。欢迎在GitHub上关注我,一起入门和进阶前端。 + +> 以下是正文。 + + +## 绑定事件的两种方式 + +我们在上一篇文章中已经讲过事件的概念。这里讲一下注册事件的两种方式,我们以onclick事件为例。 + +### 方式一:onclick + +举例: + +```html + + + + + +``` + +点击按钮后,上方代码的打印结果: + +```html +事件2 +``` + +我们可以看到,这种绑定事件的方式,会层叠掉之前的事件。 + +### 方式二:addEventListener + +addEventListener()里的参数: + +- 参数1:事件名(注意,没有on) + +- 参数2:事件名(执行函数) + +- 参数3:事件名(捕获或者冒泡) + +举例: + +```html + + + + +``` + +点击按钮后,上方代码的打印结果: + + +```html + 事件1 + 事件2 +``` + +我们可以看到,这种绑定事件的方式,不会层叠掉之前的事件。 + +## 事件对象 + +在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。比如鼠标操作时候,会添加鼠标位置的相关信息到事件对象中。 + +所有浏览器都支持event对象,但支持的方式不同。如下。 + +(1)普通浏览器支持 event。比如: + +![](http://img.smyhvae.com/20180203_1735.png) + +(2)ie 678 支持 window.event。 + +于是,我们可以采取一种兼容性的写法。如下: + +```javascript + event = event || window.event; ////兼容性写法 +``` + +代码举例: + +```html + + + + + + + + + + +``` + + +### event 属性 + +event 有很多属性,比如: + +![](http://img.smyhvae.com/20180203_1739.png) + +由于pageX 和 pageY的兼容性不好,我们可以这样做: + +- 鼠标在页面的位置 = 被卷去的部分+可视区域部分。 + +## Event举例 + +### 举例1:鼠标跟随 + +代码实现: + +```html + + + + + + + + + + + + + + +``` + +实现效果: + +![](http://img.smyhvae.com/20180203_1810.gif) + +## event应用举例:获取鼠标距离所在盒子的距离 + +关键点: + +``` + 鼠标距离所在盒子的距离 = 鼠标在整个页面的位置 - 所在盒子在整个页面的位置 +``` + +代码演示: + +```html + + + + + + + + +
+ +
+ + + + + +``` + +实现效果: + +![](http://img.smyhvae.com/20180203_1828.gif) + +**举例:商品放大镜** + +代码实现: + +(1)index.html: + +```html + + + + + + + + + + + +
+
+ +
+
+
+ +
+
+ + +``` + +(2)tools.js: + +```javascript +/** + * Created by smyhvae on 2018/02/03. + */ + +//显示和隐藏 +function show(ele) { + ele.style.display = "block"; +} + +function hide(ele) { + ele.style.display = "none"; +} + +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 + } +} + +``` + +效果演示: + +![](http://img.smyhvae.com/20180203_1920.gif) + +## 小窗口拖拽案例 + +暂略。 + +## 事件冒泡 + +事件传播的三个阶段是:事件捕获、事件冒泡和目标。 + +- 事件捕获阶段:事件从最上一级标签开始往下查找,直到捕获到事件目标 target。(从祖先元素往子元素查找,DOM树结构)。在这个过程中,事件相应的监听函数是不会被触发的。 + +- 事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。 + +- 事件冒泡阶段:事件从事件目标 target 开始,往上冒泡直到页面的最上一级标签。(从子元素到祖先元素冒泡) + +如下图所示: + +![](http://img.smyhvae.com/20180204_1218.jpg) + +PS:这个概念类似于 Android 里的 **touch 事件传递**。 + + +### 事件冒泡的概念 + +**事件冒泡**: 当一个元素上的事件被触发的时候(比如说鼠标点击了一个按钮),同样的事件将会在那个元素的所有**祖先元素**中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。 + + +通俗来讲,冒泡指的是:**子元素的事件被触发时,父盒子的同样的事件也会被触发**。取消冒泡就是取消这种机制。 + +代码演示: + +```javascript + //事件冒泡 + box3.onclick = function () { + alert("child"); + } + + box2.onclick = function () { + alert("father"); + } + + box1.onclick = function () { + alert("grandfather"); + } + + document.onclick = function () { + alert("body"); + } + +``` + +![](http://img.smyhvae.com/20180204_1028.gif) + +上图显示,当我点击儿子 box3的时候,它的父亲box2、box1、body都依次被触发了。即使我改变代码的顺序,也不会影响效果的顺序。 + +**冒泡顺序**: + +一般的浏览器: (除IE6.0之外的浏览器) + +- div -> body -> html -> document -> window + +IE6.0: + +- div -> body -> html -> document + +### 事件捕获 + +addEventListener可以捕获事件: + +```javascript + box1.addEventListener("click", function () { + alert("捕获 box3"); + }, true); +``` + +上面的方法中,参数为true,代表捕获;参数为false或者不写参数,代表冒泡。 + +代码演示: + +```javascript + //参数为true,代表捕获;参数为false或者不写参数,代表冒泡 + box3.addEventListener("click", function () { + alert("捕获 child"); + }, true); + + box2.addEventListener("click", function () { + alert("捕获 father"); + }, true); + + box1.addEventListener("click", function () { + alert("捕获 grandfather"); + }, true); + + document.addEventListener("click", function () { + alert("捕获 body"); + }, true); +``` + +效果演示: + +![](http://img.smyhvae.com/20180204_1100.gif) + +### 不是所有的事件都能冒泡 + +以下事件不冒泡:blur、focus、load、unload、onmouseenter、onmouseleave。意思是,事件不会往父元素那里传递。 + +我们检查一个元素是否会冒泡,可以通过事件的以下参数: + +``` + event.bubbles +``` + +如果返回值为true,说明该事件会冒泡;反之则相反。 + +举例: + +```javascript + box1.onclick = function (event) { + alert("冒泡 child"); + + event = event || window.event; + console.log(event.bubbles); //打印结果:true + } +``` + +### 阻止冒泡的方法 + +w3c的方法:(火狐、谷歌、IE11) + +```javascipt + event.stopPropagation(); +``` + +IE10以下则是: + +```javascipt +event.cancelBubble = true +``` + +兼容代码如下: + +```javascipt + box3.onclick = function (event) { + + alert("child"); + + //阻止冒泡 + event = event || window.event; + + if (event && event.stopPropagation) { + event.stopPropagation(); + } else { + event.cancelBubble = true; + } + } +``` + +上方代码中,我们对box3进行了阻止冒泡,产生的效果是:事件不会继续传递到 father、grandfather、body了。 + +## 事件委托 + +事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素。 + +比如说有一个列表 ul,列表之中有大量的列表项 li,我们需要在点击列表项li的时候响应一个事件。如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的,效率上需要消耗很多性能。 + +因此,比较好的方法就是把这个点击事件绑定到他的父层,也就是 `ul` 上,然后在执行事件的时候再去匹配判断目标元素。 + +所以事件委托可以减少大量的内存消耗,节约效率。 + +事件委托的参考链接:[JavaScript 事件委托详解](https://zhuanlan.zhihu.com/p/26536815) + + +## 我的公众号 + +想学习**代码之外的软技能**?不妨关注我的微信公众号:**生命团队**(id:`vitateam`)。 + +扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外: + +![](http://img.smyhvae.com/2016040102.jpg) diff --git a/03-JavaScript基础/09-事件.md b/03-JavaScript基础/09-事件.md deleted file mode 100644 index 5731e1c..0000000 --- a/03-JavaScript基础/09-事件.md +++ /dev/null @@ -1,144 +0,0 @@ - - -## 绑定事件的两种方式 - -我们在上一篇文章中已经讲过事件的概念。这里讲一下注册事件的两种方式,我们以onclick事件为例。 - - -### 方式一:onclick - -举例: - -```html - - - - - -``` - -点击按钮后,上方代码的打印结果: - - -```html -事件2 -``` - -我们可以看到,这种绑定事件的方式,会层叠掉之前的事件。 - - -### 方式二:addEventListener - -addEventListener()里的参数: - -- 参数1:事件名(不带on) - -- 参数2:事件名(执行函数) - -- 参数3:事件名(捕获或者冒泡) - - -举例: - -```html - - - - -``` - - -点击按钮后,上方代码的打印结果: - - -```html -事件1 -事件2 -``` - -我们可以看到,这种绑定事件的方式,不会层叠掉之前的事件。 - - - - - -```html - -``` - - - - - -```html - -``` - - - - - -```html - -``` - - - - - -```html - -``` - - - - - -```html - -``` - - - - - -```html - -``` - - - - - -```html - -``` - diff --git a/04-前端基础练习/06-DOM操作练习:通过style对象设置样式.md b/04-前端基础练习/06-DOM操作练习:通过style对象设置样式.md index ab0304b..1da2073 100644 --- a/04-前端基础练习/06-DOM操作练习:通过style对象设置样式.md +++ b/04-前端基础练习/06-DOM操作练习:通过style对象设置样式.md @@ -405,4 +405,101 @@ style的常用属性包括: 20180129_1525.gif +## js 访问css属性 + +访问行内的css样式,有两种方式: + +方式一: + +```javascript + box.style.width + + box.style.top +``` + +方式二: + +```javascript + 元素.style["属性"]; //格式 + + box.style["width"]; //举例 +``` + +方式二最大的优点是:可以给属性传递参数。 + + +### 获取css的样式 + +上面的内容中,我们通过`box1.style.属性`只能获得**行内样式**的属性。可如果我们想获取**内嵌或者外链**的样式,该怎么办呢? + +(1)w3c的做法: + +```javascript + window.getComputedStyle("元素", "伪类"); +``` + +两个参数都是必须要有的,如果没有伪类就用 null 代替。 + + +(2)IE和opera的做法: + +```javascript + obj.currentStyle; +``` + +于是,就有了一种兼容性的写法,同时将其封装。代码举例如下: + +```html + + + + + + + + + +
+ + + + +``` + + +打印结果: + +20180204_1425.png + + + + + + + + + diff --git a/06-JavaScript进阶/01-offset家族和匀速动画(含轮播图的实现).md b/06-JavaScript进阶/01-offset家族和匀速动画(含轮播图的实现).md index 1316e2f..6430697 100644 --- a/06-JavaScript进阶/01-offset家族和匀速动画(含轮播图的实现).md +++ b/06-JavaScript进阶/01-offset家族和匀速动画(含轮播图的实现).md @@ -21,7 +21,7 @@ JS动画的主要内容如下: 4、正则 -## offset家族简介 +## offset 家族的组成 我们知道,三大家族包括:offset/scroll/client。今天来讲一下offset,以及与其相关的匀速动画。 diff --git a/06-JavaScript进阶/02-scroll家族和缓动动画.md b/06-JavaScript进阶/02-scroll家族和缓动动画.md new file mode 100644 index 0000000..a0b9dce --- /dev/null +++ b/06-JavaScript进阶/02-scroll家族和缓动动画.md @@ -0,0 +1,1162 @@ + + +## 缓动动画 + +### 三个函数 + +缓慢动画里,我们要用到三个函数,这里先列出来: + +- Math.ceil() 向上取整 + +- Math.floor() 向下取整 + +- Math.round(); 四舍五入 + + +### 缓动动画的原理 + +缓动动画的原理就是:在移动的过程中,步长越来越小。 + +设置步长为**:目标位置和盒子当前位置的十分之一**。用公式表达,即: + +``` + 盒子位置 = 盒子本身位置 + (目标位置 - 盒子本身位置)/ 10; +``` + +代码举例: + +```html + + + + + + + + + +
+ + + + +``` + +效果: + +20180202_2046.gif + +### 缓慢动画的封装(解决四舍五入的问题) + +我们发现一个问题,上图中的盒子最终并没有到达400px的位置,而是只到了396.04px就停住了: + +20180202_2140.png + +原因是:JS在取整的运算时,进行了四舍五入。 + +我们把打印396.04px这个left值打印出来看看: + +20180202_2150.png + +我么发现,通过`div.style.left`获取的值是精确的,通过`div.offsetLeft`获取的left值会进行四舍五入。 + +此时,我们就要用到取整的函数了。 + +通过对缓动动画进行封装,完整版的代码实现如下: + + +```html + + + + + + + + + + +
+ + + + +``` + + +实现效果: + +20180202_2239.gif + + +## scroll 家族的组成 + +当我们用鼠标滚轮,滚动网页的时候,会触发window.onscroll()方法。效果如下:(注意看控制台的打印结果) + +20180202_2258.gif + +### 1、ScrollWidth 和 scrollHeight + +获取盒子的宽高。调用者为节点元素。不包括 border和margin。如下: + +- scrollWidth = width + padding; + +- scrollHeight = height + padding; + +scrollHeight有一个特点:如果文字超出了盒子,高度为内容的高(包括超出的内容);不超出,则是盒子本身高度。 + +举例: + +```html + + + + + + + + + +
+ 静,能寒窗苦守;动,能点石成金。 + 静,能寒窗苦守;动,能点石成金。 + 静,能寒窗苦守;动,能点石成金。 + 静,能寒窗苦守;动,能点石成金。 + 静,能寒窗苦守;动,能点石成金。 + 静,能寒窗苦守;动,能点石成金。 +
+ + + +``` + +打印结果: + +20180203_1235.png + +### 2、scrollTop 和 scrollLeft + +网页被卷去的头部和左边的部分。 + +比如说,一个网页往上滚动的时候,上面的部分自然被浏览器遮挡了,遮挡的高度就是scrollTop。 + +scrollTop 这个属性的写法要注意兼容性,如下。 + +(1)如果文档没有 DTD 声明,写法为: + +```javascript + document.body.scrollTop +``` + +在没有 DTD 声明的情况下,如果不是这种写法,chrome浏览器认不出来。 + +(2)如果文档有 DTD 声明,写法为: + +```javascript + document.documentElement.scrollTop +``` + +在有 DTD 声明的情况下,如果不是这种写法,IE678认不出来。 + +综合上面这两个,就诞生了一种兼容性的写法: + +```javascript + document.body.scrollTop || document.documentElement.scrollTop //方式一 + + document.body.scrollTop + document.documentElement.scrollTop //方式二 +``` + +另外还有一种兼容性的写法:`window.pageYOffset` 和 `window.pageXOffset`。这种写法无视DTD的声明。这种写法支持的浏览器版本是:火狐/谷歌/ie9+。 + +综合上面的几种写法,为了兼容,不管有没有DTD,**最终版的兼容性写法:** + +```javascript + window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop; +``` + +### 判断是否已经 DTD声明 + +方法如下: + +```javascript + document.compatMode === "CSS1Compat" // 已声明 + document.compatMode === "BackCompat" // 未声明 +``` + +### 将 scrollTop 和 scrollLeft封装为 json + + +将 scrollTop 和 scrollLeft封装为一个方法,名叫scroll(),返回值为 json。json里的键为 top 和 left。以后就直接调用json.top 和json.left就好。 + +代码实现: + +```html + + + + + + + + + + + +``` + +上方代码中,函数定义的那部分就是要封装的代码。另外还有一种较为复杂的封装方式: + +```javascript +function scroll() { // 开始封装自己的scrollTop + if(window.pageYOffset !== undefined) { // 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 + } +} +``` + +## 获取 html 文档的方法 + +获取title、body、head、html标签的方法如下: + +- `document.title` 文档标题; + +- `document.head` 文档的头标签 + +- `document.body` 文档的body标签; + +- `document.documentElement` (这个很重要)。 + +`document.documentElement`表示文档的html标签。也就是说,基本结构当中的 `html 标签`而是通过`document.documentElement`访问的,并不是通过 document.html 去访问的。 + + +## scrollTop 举例:固定导航栏 + + +完整版代码实现: + +(1)index.html: + +```html + + + + + + + + + + + + +
+ +
+
+ +
+
+ +
+ + + +``` + +上方代码中,有一个技巧: + +```javascript +main.style.paddingTop = middle.offsetHeight + "px"; +``` + +仔细看注释就好。 + +(2)tools.js: + +```javascript +/** + * Created by smyhvae on 2018/02/03. + */ +function scroll() { // 开始封装自己的scrollTop + if (window.pageYOffset !== undefined) { // 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 + } +} +``` + + +实现效果: + + +20180203_1619.gif + + +工程文件: + +- 2018-02-03-scrollTop固定导航栏.rar + + +## window.scrollTo()方法举例:返回到顶部小火箭 + +(1)index.html: + + + +```html + + + + + + + + + + + +
+ 我是最顶端.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ 生命壹号,永不止步.....
+ +
+ + +``` + + +(2)tools.js: + +```javascript +/** + * Created by smyhvae on 2015/12/8. + */ + +//函数:获取scrollTop和scrollLeft的值 +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 + } +} + +``` + + +实现效果: + + +20180203_1710.gif + +小火箭的图片资源:<20180203-Top.jpg> + + + +## window.scrollTo()方法举例:楼层跳跃(暂略) + + +## 缓动框架封装 + +### 1、缓动框架封装:同时设置多个属性 + +这里我们通过`window.getComputedStyle`的方式获取属性值。 + +**完整代码如下:** + +```html + + + + + + + + + + +
+ + + + +``` + + +实现效果: + + +20180204_1440.gif + + +### 2、上方的代码改进:清除定时器 + +上方的代码中,我们还需做一下清除定时器的判断:只有所有的参数都到达指定位置了,我们就清除定时器。 + +完整版代码如下: + + +```html + + + + + + + + + + +
+ + + + +``` + + +实现效果同上。 + + +**### 3、进一步深入:如果有要同时执行讴多个动画时,就要用到回调函数(重要)**: + +上面的代码中,我们要做的动画是: + +```javascript + btnArr[0].onclick = function () { + var json = {"left": 100, "top": 200, "width": 300, "height": 300}; + animate(div, json); + } +``` + +上面的代码是执行这一个动画,可如果要同时执行两个动画呢?一般人自然想到的是下面的写法:(错误的写法) + + +```javascript + btnArr[0].onclick = function () { + var json1 = {"left": 100, "top": 200, "width": 300, "height": 300}; + var json2 = {"left": 200, "top": 10, "width": 150, "height": 150}; + animate(div, json1); + animate(div, json2); + } +``` + +但是这样写的话,第二个动画 json2 会把第一个动画 json1 **层叠掉**。也就是说,第一个动画直接就不执行了。效果如下: + + +20180204_1526.gif + +这显然不是我们想看到的。 + +如果我们想先执行第一个动画fn1(),再执行第二个动画fn2()的话,就要用到**回调函数**。意思是,将第二个动画fn2()作为回调函数即可。 + +完整版代码如下: + + +```html + + + + + + + + + + +
+ + + + +``` + +效果如下: + + +20180204_1600.gif + + + +上方代码中,如果我们要先后完成两个动画,执行的代码是: + + +```javascript + animate(div, json1, function () { //第三个参数是回调,可以保证json1的动画执行结束后,再执行json2的动画 + animate(div, json2); + }) +``` + + +如果想要先后执行两个动画,那就以此类推: + +```javascript + animate(div, json1, function () { //第三个参数是回调,可以保证json1的动画执行结束后,再执行json2的动画 + animate(div, json2,function () { + animate(div,json3); + }); + }) +``` + + + + +**举例:仿360的右下角开机效果** + +代码实现: + +```html + + + + + + + + + +
+ +
+ +
+
+ +
+
+ + +``` + + +效果如下: + +20180204_1620.gif + +工程文件: + +- 2018-02-04-仿360开机效果.rar + + + +### 4、对 opacity和 z-index 属性进行单独改进 + +我们以上的代码中,如果要进行动画参数的设置,是直接把参数放到json里面去的。例如: + +```javascript + var json1 = {"left": 100, "top": 200, "width": 300, "height": 300}; + var json2 = {"left": 300, "top": 10, "width": 100, "height": 100}; +``` + +可是,下面这两个属性,却不能这样放到json里,会出现兼容性的问题: + + +``` + opacity: 0.5; //透明度 + z-index: 1; +``` + + +如何改进呢?赞略。 diff --git a/06-JavaScript进阶/02-缓动动画.md b/06-JavaScript进阶/02-缓动动画.md deleted file mode 100644 index 5ce7c79..0000000 --- a/06-JavaScript进阶/02-缓动动画.md +++ /dev/null @@ -1,55 +0,0 @@ - - -## 缓动动画 - -### 缓动动画的原理 - -缓动动画的原理就是:在移动的过程中,步长越来越小。 - -设置步长为**:目标位置和盒子当前位置的十分之一**。用公式表达,即: - -``` - 盒子位置 = 盒子本身位置 + (目标位置 - 盒子本身位置)/ 10; -``` - -代码举例: - -```html - - - - - - - - - -
- - - - -``` - -效果: - -20180202_2046.gif diff --git a/06-JavaScript进阶/03-client家族(可视区).md b/06-JavaScript进阶/03-client家族(可视区).md new file mode 100644 index 0000000..918d7c5 --- /dev/null +++ b/06-JavaScript进阶/03-client家族(可视区).md @@ -0,0 +1,178 @@ + + + +## client 家族的组成 + +### clientWidth 和 clientHeight + +盒子调用时: + +- clientWidth:获取盒子区域宽度(padding + width)。 + +- clientHeight:获取盒子区域高度(padding + height)。 + +body/html调用时: + +- clientWidth:获取网页可视区域宽度。 + +- clientHeight:获取网页可视区域高度。 + + +### clientX 和 clientY + +event调用: + +- clientX:鼠标距离可视区域左侧距离。 + +- clientY:鼠标距离可视区域上侧距离。 + + + +### clientTop 和 clientLeft + +- clientTop:盒子的上border。 + +- clientLeft:盒子的左border。 + + +## 三大家族 offset/scroll/client 的区别 + +### 区别1:宽高 + +- offsetWidth = width + padding + border +- offsetHeight = height + padding + border + +- scrollWidth = 内容宽度(不包含border) +- scrollHeight = 内容高度(不包含border) + +- clientWidth = width + padding +- clientHeight = height + padding + + +### 区别2:上左 + + +offsetTop/offsetLeft: + +- 调用者:任意元素。(盒子为主) +- 作用:距离父系盒子中带有定位的距离。 + + +scrollTop/scrollLeft: + +- 调用者:document.body.scrollTop(window调用)(盒子也可以调用,但必须有滚动条) +- 作用:浏览器无法显示的部分(被卷去的部分)。 + + +clientY/clientX: + +- 调用者:event +- 作用:鼠标距离浏览器可视区域的距离(左、上)。 + + + + +## 函数封装:获取浏览器的宽高(可视区域) + +函数封装如下: + +```javascript +//函数封装:获取屏幕可视区域的宽高 +function client() { + if (window.innerHeight !== undefined) { + //ie9及其以上的版本的写法 + return { + "width": window.innerWidth, + "height": window.innerHeight + } + } else if (document.compatMode === "CSS1Compat") { + //标准模式的写法(有DTD时) + return { + "width": document.documentElement.clientWidth, + "height": document.documentElement.clientHeight + } + } else { + //没有DTD时的写法 + return { + "width": document.body.clientWidth, + "height": document.body.clientHeight + } + } +} + +``` + + +**案例:根据浏览器的可视宽度,给定不同的背景的色。** + +> PS:这个可以用来做响应式。 + +代码如下:(需要用到上面的封装好的方法) + +```html + + + + + + + + + + + + +``` + + +上当代码中,`window.onresize`事件指的是:在窗口或框架被调整大小时发生。各个事件的解释如下: + +- window.onscroll 屏幕滑动 + +- window.onresize 浏览器大小变化 + +- window.onload 页面加载完毕 + +- div.onmousemove 鼠标在盒子上移动(注意:不是盒子移动) + + + +## 获取显示器的分辨率 + +比如,我的电脑的显示器分辨率是:1920*1080。 + + +获取显示器的分辨率: + +```javascript + window.onresize = function () { + document.title = window.screen.width + " " + window.screen.height; + } +``` + +显示效果: + +20180203_2155.png + +上图中,不管我如何改变浏览器的窗口大小,title栏显示的值永远都是我的显示器分辨率:1920*1080。 + + +