前端Web APIs 二

day04 - Web APIs

学习目标:

能够说出常用的3-5个键盘事件

能够知道如何获取当前键盘按下的是哪个键

能够知道浏览器的顶级对象window

能够使用window.onload事件

能够使用window.onresize事件

能够说出两种定时器的区别

能够使用location对象的href属性完成页面之间的跳转

能够使用location对象获取url中的参数部分

能够使用history提供的方法实现页面刷新

1.1. 常用的键盘事件

1.1.1 键盘事件

  

 

 


 <script>
       // 常用的键盘事件
       //1. keyup 按键弹起的时候触发
       document.addEventListener('keyup', function() {
           console.log('我弹起了');
      })

       //3. keypress 按键按下的时候触发 不能识别功能键 比如 ctrl shift 左右箭头啊
       document.addEventListener('keypress', function() {
               console.log('我按下了press');
      })
       //2. keydown 按键按下的时候触发 能识别功能键 比如 ctrl shift 左右箭头啊
       document.addEventListener('keydown', function() {
               console.log('我按下了down');
      })
       // 4. 三个事件的执行顺序 keydown -- keypress -- keyup
   </script>

1.1.2 键盘事件对象

 

 

 

 

使用keyCode属性判断用户按下哪个键


   <script>
       // 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
       document.addEventListener('keyup', function(e) {
           console.log('up:' + e.keyCode);
           // 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
           if (e.keyCode === 65) {
               alert('您按下的a键');
          } else {
               alert('您没有按下a键')
          }
      })
       document.addEventListener('keypress', function(e) {
           // console.log(e);
           console.log('press:' + e.keyCode);
      })
   </script>

1.1.3 案例:模拟京东按键输入内容

当我们按下 s 键, 光标就定位到搜索框(文本框获得焦点)。

 

 

注意:触发获得焦点事件,可以使用 元素对象.focus()


   <input type="text">
   <script>
       // 获取输入框
       var search = document.querySelector('input');
// 给document注册keyup事件
       document.addEventListener('keyup', function(e) {
           // 判断keyCode的值
           if (e.keyCode === 83) {
               // 触发输入框的获得焦点事件
               search.focus();
          }
      })
   </script>

1.1.4 案例:模拟京东快递单号查询

要求:当我们在文本框中输入内容时,文本框上面自动显示大字号的内容。

 

 


   <div class="search">
       <div class="con">123</div>
       <input type="text" placeholder="请输入您的快递单号" class="jd">
   </div>
   <script>
       // 获取要操作的元素
       var con = document.querySelector('.con');
       var jd_input = document.querySelector('.jd');
// 给输入框注册keyup事件
       jd_input.addEventListener('keyup', function() {
// 判断输入框内容是否为空
               if (this.value == '') {
                   // 为空,隐藏放大提示盒子
                   con.style.display = 'none';
              } else {
                   // 不为空,显示放大提示盒子,设置盒子的内容
                   con.style.display = 'block';
                   con.innerText = this.value;
              }
          })
       // 给输入框注册失去焦点事件,隐藏放大提示盒子
       jd_input.addEventListener('blur', function() {
               con.style.display = 'none';
          })
       // 给输入框注册获得焦点事件
       jd_input.addEventListener('focus', function() {
           // 判断输入框内容是否为空
           if (this.value !== '') {
               // 不为空则显示提示盒子
               con.style.display = 'block';
          }
      })
   </script>

1.2. BOM

1.2.1. 什么是BOM

​ BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window。

​ BOM 由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。

​ BOM 缺乏标准,JavaScript 语法的标准化组织是 ECMA,DOM 的标准化组织是 W3C,BOM 最初是Netscape 浏览器标准的一部分。

 

 

1.2.2. BOM的构成

BOM 比 DOM 更大,它包含 DOM。

 

 

1.2.3. 顶级对象window

 

 

1.2.4. window对象的常见事件

页面(窗口)加载事件(2种)

第1种

 

 

window.onload 是窗口 (页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS 文件等), 就调用的处理函数。

 

 

第2种

 

 

​ DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。

​ IE9以上才支持!!!

​ 如果页面的图片很多的话, 从用户访问到onload触发可能需要较长的时间, 交互效果就不能实现,必然影响用户的体验,此时用 DOMContentLoaded 事件比较合适。


   <script>
       window.addEventListener('load', function() {
           var btn = document.querySelector('button');
           btn.addEventListener('click', function() {
               alert('点击我');
          })
      })
       window.addEventListener('load', function() {
           alert(22);
      })
       document.addEventListener('DOMContentLoaded', function() {
           alert(33);
      })
   </script>

调整窗口大小事件

 

 

​ window.onresize 是调整窗口大小加载事件, 当触发时就调用的处理函数。

注意:

  1. 只要窗口大小发生像素变化,就会触发这个事件。

  2. 我们经常利用这个事件完成响应式布局。 window.innerWidth 当前屏幕的宽度


   <script>
       // 注册页面加载事件
       window.addEventListener('load', function() {
           var div = document.querySelector('div');
      // 注册调整窗口大小事件
           window.addEventListener('resize', function() {
               // window.innerWidth 获取窗口大小
               console.log('变化了');
               if (window.innerWidth <= 800) {
                   div.style.display = 'none';
              } else {
                   div.style.display = 'block';
              }
          })
      })
   </script>
   <div></div>

 

1.2.5. 定时器(两种)

window 对象给我们提供了 2 个非常好用的方法-定时器。

  • setTimeout()

  • setInterval()

setTimeout() 炸弹定时器

开启定时器

 

 

 

 


普通函数是按照代码顺序直接调用。

简单理解: 回调,就是回头调用的意思。上一件事干完,再回头再调用这个函数。
例如:定时器中的调用函数,事件处理函数,也是回调函数。

以前我们讲的   element.onclick = function(){}   或者 element.addEventListener(“click”, fn);   里面的 函数也是回调函数。

 


   <script>
       // 回调函数是一个匿名函数
        setTimeout(function() {
            console.log('时间到了');

        }, 2000);
       function callback() {
           console.log('爆炸了');
      }
// 回调函数是一个有名函数
       var timer1 = setTimeout(callback, 3000);
       var timer2 = setTimeout(callback, 5000);
   </script>
案例:5秒后关闭广告

 

 

 

 

 


<body>
   <img src="images/ad.jpg" alt="" class="ad">
   <script>
       // 获取要操作的元素
       var ad = document.querySelector('.ad');
// 开启定时器
       setTimeout(function() {
           ad.style.display = 'none';
      }, 5000);
   </script>
</body>
停止定时器

 

 


   <button>点击停止定时器</button>
   <script>
       var btn = document.querySelector('button');
// 开启定时器
       var timer = setTimeout(function() {
           console.log('爆炸了');
      }, 5000);
// 给按钮注册单击事件
       btn.addEventListener('click', function() {
           // 停止定时器
           clearTimeout(timer);
      })
   </script>

 

setInterval() 闹钟定时器

开启定时器

 

 


   <script>
       // 1. setInterval
       setInterval(function() {
           console.log('继续输出');
      }, 1000);
   </script>
案例:倒计时

 

 

 

 


   <div>
       <span class="hour">1</span>
       <span class="minute">2</span>
       <span class="second">3</span>
   </div>
   <script>
       // 1. 获取元素(时分秒盒子)
       var hour = document.querySelector('.hour'); // 小时的黑色盒子
       var minute = document.querySelector('.minute'); // 分钟的黑色盒子
       var second = document.querySelector('.second'); // 秒数的黑色盒子
       var inputTime = +new Date('2019-5-1 18:00:00'); // 返回的是用户输入时间总的毫秒数

       countDown(); // 我们先调用一次这个函数,防止第一次刷新页面有空白

       // 2. 开启定时器
       setInterval(countDown, 1000);

       function countDown() {
           var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
           var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数
           var h = parseInt(times / 60 / 60 % 24); //时
           h = h < 10 ? '0' + h : h;
           hour.innerHTML = h; // 把剩余的小时给 小时黑色盒子
           var m = parseInt(times / 60 % 60); // 分
           m = m < 10 ? '0' + m : m;
           minute.innerHTML = m;
           var s = parseInt(times % 60); // 当前的秒
           s = s < 10 ? '0' + s : s;
           second.innerHTML = s;
      }
   </script>
停止定时器

 

 

案例:发送短信倒计时

​ 点击按钮后,该按钮60秒之内不能再次点击,防止重复发送短信。

 

 


   手机号码: <input type="number"> <button>发送</button>
   <script>
       var btn = document.querySelector('button');
// 全局变量,定义剩下的秒数
       var time = 3;
// 注册单击事件
       btn.addEventListener('click', function() {
           // 禁用按钮
           btn.disabled = true;
           // 开启定时器
           var timer = setInterval(function() {
               // 判断剩余秒数
               if (time == 0) {
                   // 清除定时器和复原按钮
                   clearInterval(timer);
                   btn.disabled = false;
                   btn.innerHTML = '发送';
              } else {
                   btn.innerHTML = '还剩下' + time + '秒';
                   time--;
              }
          }, 1000);
      });
   </script>

 

1.2.6. this指向问题

​ this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象。

现阶段,我们先了解一下几个this指向

  1. 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)

  2. 方法调用中谁调用this指向谁

  3. 构造函数中this指向构造函数的实例


   <button>点击</button>
   <script>
       // this 指向问题 一般情况下this的最终指向的是那个调用它的对象
       // 1. 全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window)
       console.log(this);
       function fn() {
           console.log(this);
      }
       window.fn();
       window.setTimeout(function() {
           console.log(this);
      }, 1000);
       // 2. 方法调用中谁调用this指向谁
       var o = {
           sayHi: function() {
               console.log(this); // this指向的是 o 这个对象
          }
      }
       o.sayHi();
       var btn = document.querySelector('button');
       btn.addEventListener('click', function() {
               console.log(this); // 事件处理函数中的this指向的是btn这个按钮对象
          })
       // 3. 构造函数中this指向构造函数的实例
       function Fun() {
           console.log(this); // this 指向的是fun 实例对象
      }
       var fun = new Fun();
   </script>

 

1.2.7. location对象

什么是 location 对象

 

 

URL

 

 

 

 

location 对象的属性

 

 

案例:5分钟自动跳转页面

 

 


   <button>点击</button>
   <div></div>
   <script>
       var btn = document.querySelector('button');
       var div = document.querySelector('div');
       btn.addEventListener('click', function() {
           // console.log(location.href);
           location.href = 'http://www.itcast.cn';
      })
       var timer = 5;
       setInterval(function() {
           if (timer == 0) {
               location.href = 'http://www.itcast.cn';
          } else {
               div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
               timer--;
          }
      }, 1000);
   </script>

案例:获取URL参数

 

 

 

 


   <div></div>
<script>
       console.log(location.search); // ?uname=andy
       // 1.先去掉? substr('起始的位置',截取几个字符);
       var params = location.search.substr(1); // uname=andy
       console.log(params);
       // 2. 利用=把字符串分割为数组 split('=');
       var arr = params.split('=');
       console.log(arr); // ["uname", "ANDY"]
       var div = document.querySelector('div');
       // 3.把数据写入div中
       div.innerHTML = arr[1] + '欢迎您';
   </script>

location对象的常见方法

 

 


   <button>点击</button>
   <script>
       var btn = document.querySelector('button');
       btn.addEventListener('click', function() {
           // 记录浏览历史,所以可以实现后退功能
           // location.assign('http://www.itcast.cn');
           // 不记录浏览历史,所以不可以实现后退功能
           // location.replace('http://www.itcast.cn');
           location.reload(true);
      })
   </script>

1.2.8. navigator对象

​ navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的是 userAgent,该属性可以返回由客户机发送服务器的 user-agent 头部的值。

下面前端代码可以判断用户那个终端打开页面,实现跳转


if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
   window.location.href = "";     //手机
} else {
   window.location.href = "";     //电脑
}

1.2.9 history对象

​ window对象给我们提供了一个 history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。

 

 

history对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到。

 

 

1.3. JS执行机制

 

 

以下代码执行的结果是什么?


console.log(1);

setTimeout(function () {
    console.log(3);
}, 1000);

console.log(2);

以下代码执行的结果是什么?


console.log(1);

setTimeout(function () {
    console.log(3);
}, 0);

console.log(2);

 

1.3.1 JS 是单线程

 

 


单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

1.3.2 同步任务和异步任务

​ 单线程导致的问题就是后面的任务等待前面任务完成,如果前面任务很耗时(比如读取网络数据),后面任务不得不一直等待!!

​ 为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,但是子线程完全受主线程控制。于是,JS 中出现了同步任务异步任务

同步

​ 前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。

异步

​ 你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。

 

 


JS中所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

同步任务指的是:
在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务指的是:
不进入主线程、而进入”任务队列”的任务,当主线程中的任务运行完了,才会从”任务队列”取出异步任务放入主线程执行。

 

 

1.3.3 JS执行机制(事件循环)

 

 

 

 

1.3.4 代码思考题


console.log(1);
document.onclick = function() {
  console.log('click');
}

setTimeout(function() {
  console.log(3)
}, 3000)
console.log(2);

 

 

 

 

 

 

 

 

day05 - Web APIs

学习目标:

能够说出常见 offset 系列属性的作用

能够说出常见 client 系列属性的作用

能够说出常见 scroll 系列属性的作用

能够封装简单动画函数

1.1. 元素偏移量 offset 系列

1.1.1 offset 概述

offset 翻译过来就是偏移量, 我们使用 offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。

  1. 获得元素距离带有定位父元素的位置

  2. 获得元素自身的大小(宽度高度)

  3. 注意:返回的数值都不带单位

 

 

 

1.1.2 offset 与 style 区别

offset

  • offset 可以得到任意样式表中的样式值

  • offset 系列获得的数值是没有单位的

  • offsetWidth 包含padding+border+width

  • offsetWidth 等属性是只读属性,只能获取不能赋值

  • 所以,我们想要获取元素大小位置,用offset更合适

style

  • style 只能得到行内样式表中的样式值

  • style.width 获得的是带有单位的字符串

  • style.width 获得不包含padding和border 的值

  • style.width 是可读写属性,可以获取也可以赋值

  • 所以,我们想要给元素更改值,则需要用style改变

因为平时我们都是给元素注册触摸事件,所以重点记住 targetTocuhes

1.1.3 案例:获取鼠标在盒子内的坐标

  1. 我们在盒子内点击,想要得到鼠标距离盒子左右的距离。

  2. 首先得到鼠标在页面中的坐标(e.pageX, e.pageY)

  3. 其次得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop)

  4. 用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标

  5. 如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动

var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;
})

1.1.4 案例:模态框拖拽

弹出框,我们也称为模态框。

​ 1.点击弹出层,会弹出模态框, 并且显示灰色半透明的遮挡层。

​ 2.点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层。

​ 3.鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动。

​ 4.鼠标松开,可以停止拖动模态框移动

1.1.5. 案例分析:

  1. 点击弹出层, 模态框和遮挡层就会显示出来 display:block;

  2. 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none;

  3. 在页面中拖拽的原理:鼠标按下并且移动, 之后松开鼠标

  4. 触发事件是鼠标按下mousedown,鼠标移动mousemove 鼠标松开 mouseup

  5. 拖拽过程:  鼠标移动过程中,获得最新的值赋值给模态框的left和top值,这样模态框可以跟着鼠标走了

  6. 鼠标按下触发的事件源是最上面一行,就是  id 为 title

  7. 鼠标的坐标减去 鼠标在盒子内的坐标, 才是模态框真正的位置。

  8. 鼠标按下,我们要得到鼠标在盒子的坐标。

  9. 鼠标移动,就让模态框的坐标  设置为  :鼠标坐标 减去盒子坐标即可,注意移动事件写到按下事件里面。

  10. 鼠标松开,就停止拖拽,就是可以让鼠标移动事件解除 

 // 1. 获取元素
       var login = document.querySelector('.login');
       var mask = document.querySelector('.login-bg');
       var link = document.querySelector('#link');
       var closeBtn = document.querySelector('#closeBtn');
       var title = document.querySelector('#title');
       // 2. 点击弹出层这个链接 link 让mask 和login 显示出来
       link.addEventListener('click', function() {
               mask.style.display = 'block';
               login.style.display = 'block';
          })
           // 3. 点击 closeBtn 就隐藏 mask 和 login
       closeBtn.addEventListener('click', function() {
               mask.style.display = 'none';
               login.style.display = 'none';
          })
           // 4. 开始拖拽
           // (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
       title.addEventListener('mousedown', function(e) {
           var x = e.pageX - login.offsetLeft;
           var y = e.pageY - login.offsetTop;
           // (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
           document.addEventListener('mousemove', move)

           function move(e) {
               login.style.left = e.pageX - x + 'px';
               login.style.top = e.pageY - y + 'px';
          }
           // (3) 鼠标弹起,就让鼠标移动事件移除
           document.addEventListener('mouseup', function() {
               document.removeEventListener('mousemove', move);
          })
      })

1.1.6 案例:仿京东放大镜

  1. 整个案例可以分为三个功能模块

  2. 鼠标经过小图片盒子, 黄色的遮挡层 和 大图片盒子显示,离开隐藏2个盒子功能

  3. 黄色的遮挡层跟随鼠标功能。

  4. 移动黄色遮挡层,大图片跟随移动功能。

1.1.7. 案例分析:

  1. 黄色的遮挡层跟随鼠标功能。

  2. 把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准。

  3. 首先是获得鼠标在盒子的坐标。

  4. 之后把数值给遮挡层做为left 和top值。

  5. 此时用到鼠标移动事件,但是还是在小图片盒子内移动。

  6. 发现,遮挡层位置不对,需要再减去盒子自身高度和宽度的一半。

  7. 遮挡层不能超出小图片盒子范围。

  8. 如果小于零,就把坐标设置为0

  9. 如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离

  10. 遮挡层的最大移动距离:小图片盒子宽度 减去 遮挡层盒子宽度

 

 

 


window.addEventListener('load', function() {
   var preview_img = document.querySelector('.preview_img');
   var mask = document.querySelector('.mask');
   var big = document.querySelector('.big');
   // 1. 当我们鼠标经过 preview_img 就显示和隐藏 mask 遮挡层 和 big 大盒子
   preview_img.addEventListener('mouseover', function() {
       mask.style.display = 'block';
       big.style.display = 'block';
  })
   preview_img.addEventListener('mouseout', function() {
           mask.style.display = 'none';
           big.style.display = 'none';
      })
       // 2. 鼠标移动的时候,让黄色的盒子跟着鼠标来走
   preview_img.addEventListener('mousemove', function(e) {
       // (1). 先计算出鼠标在盒子内的坐标
       var x = e.pageX - this.offsetLeft;
       var y = e.pageY - this.offsetTop;
       // console.log(x, y);
       // (2) 减去盒子高度 300的一半 是 150 就是我们mask 的最终 left 和top值了
       // (3) 我们mask 移动的距离
       var maskX = x - mask.offsetWidth / 2;
       var maskY = y - mask.offsetHeight / 2;
       // (4) 如果x 坐标小于了0 就让他停在0 的位置
       // 遮挡层的最大移动距离
       var maskMax = preview_img.offsetWidth - mask.offsetWidth;
       if (maskX <= 0) {
           maskX = 0;
      } else if (maskX >= maskMax) {
           maskX = maskMax;
      }
       if (maskY <= 0) {
           maskY = 0;
      } else if (maskY >= maskMax) {
           maskY = maskMax;
      }
       mask.style.left = maskX + 'px';
       mask.style.top = maskY + 'px';
       // 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
       // 大图
       var bigIMg = document.querySelector('.bigImg');
       // 大图片最大移动距离
       var bigMax = bigIMg.offsetWidth - big.offsetWidth;
       // 大图片的移动距离 X Y
       var bigX = maskX * bigMax / maskMax;
       var bigY = maskY * bigMax / maskMax;
       bigIMg.style.left = -bigX + 'px';
       bigIMg.style.top = -bigY + 'px';

  })

})

1.2. 元素可视区 client 系列

1.2.1 client概述

client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

 

 

1.2.2. 淘宝 flexible.js 源码分析

立即执行函数 (function(){})()  或者 (function(){}())

主要作用: 创建一个独立的作用域。 避免了命名冲突问题

下面三种情况都会刷新页面都会触发 load 事件。

1.a标签的超链接

2.F5或者刷新按钮(强制刷新)

3.前进后退按钮

但是 火狐中,有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里。

所以此时后退按钮不能刷新页面。

此时可以使用 pageshow事件来触发。,这个事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件

注意这个事件给window添加。

 

1.3.元素滚动 scroll 系列

1.3.1. scroll 概述

scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

 

 

1.3.2. 页面被卷去的头部

如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发 onscroll事件。

 

1.3.3.案例:仿淘宝固定右侧侧边栏

  1. 原先侧边栏是绝对定位

  2. 当页面滚动到一定位置,侧边栏改为固定定位

  3. 页面继续滚动,会让 返回顶部显示出来

1.3.4.案例分析:

  1. 需要用到页面滚动事件 scroll  因为是页面滚动,所以事件源是document

  2. 滚动到某个位置,就是判断页面被卷去的上部值。

  3. 页面被卷去的头部:可以通过window.pageYOffset 获得  如果是被卷去的左侧window.pageXOffset

  4. 注意,元素被卷去的头部是element.scrollTop  , 如果是页面被卷去的头部 则是 window.pageYOffset

  5. 其实这个值 可以通过盒子的 offsetTop可以得到,如果大于等于这个值,就可以让盒子固定定位了


 //1. 获取元素
       var sliderbar = document.querySelector('.slider-bar');
       var banner = document.querySelector('.banner');
       // banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
       var bannerTop = banner.offsetTop
           // 当我们侧边栏固定定位之后应该变化的数值
       var sliderbarTop = sliderbar.offsetTop - bannerTop;
       // 获取main 主体元素
       var main = document.querySelector('.main');
       var goBack = document.querySelector('.goBack');
       var mainTop = main.offsetTop;
       // 2. 页面滚动事件 scroll
       document.addEventListener('scroll', function() {
           // console.log(11);
           // window.pageYOffset 页面被卷去的头部
           // console.log(window.pageYOffset);
           // 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位
           if (window.pageYOffset >= bannerTop) {
               sliderbar.style.position = 'fixed';
               sliderbar.style.top = sliderbarTop + 'px';
          } else {
               sliderbar.style.position = 'absolute';
               sliderbar.style.top = '300px';
          }
           // 4. 当我们页面滚动到main盒子,就显示 goback模块
           if (window.pageYOffset >= mainTop) {
               goBack.style.display = 'block';
          } else {
               goBack.style.display = 'none';
          }

      })

1.3.5.页面被卷去的头部兼容性解决方案

需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:

  1. 声明了 DTD,使用 document.documentElement.scrollTop

  2. 未声明 DTD,使用  document.body.scrollTop

  3. 新方法 window.pageYOffset和 window.pageXOffset,IE9 开始支持


function getScroll() {
   return {
     left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
     top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
  };
}
使用的时候  getScroll().left

1.4. 三大系列总结

 

 

他们主要用法:

1.offset系列 经常用于获得元素位置    offsetLeft  offsetTop

2.client经常用于获取元素大小  clientWidth clientHeight

3.scroll 经常用于获取滚动距离 scrollTop  scrollLeft  

4.注意页面滚动的距离通过 window.pageXOffset  获得

1.5. mouseenter 和mouseover的区别

  • 当鼠标移动到元素上时就会触发mouseenter 事件

  • 类似 mouseover,它们两者之间的差别是

  • mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter  只会经过自身盒子触发

  • 之所以这样,就是因为mouseenter不会冒泡

  • 跟mouseenter搭配鼠标离开 mouseleave  同样不会冒泡

1.6. 动画函数封装

1.6.1. 动画实现原理

核心原理:通过定时器 setInterval() 不断移动盒子位置。

实现步骤:

  1. 获得盒子当前位置

  2. 让盒子在当前位置加上1个移动距离

  3. 利用定时器不断重复这个操作

  4. 加一个结束定时器的条件

  5. 注意此元素需要添加定位,才能使用element.style.left

1.6.2. 动画函数给不同元素记录不同定时器

如果多个元素都使用这个动画函数,每次都要var 声明定时器。我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)。

核心原理:利用 JS 是一门动态语言,可以很方便的给当前对象添加属性。


function animate(obj, target) {
           // 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
           // 解决方案就是 让我们元素只有一个定时器执行
           // 先清除以前的定时器,只保留当前的一个定时器执行
           clearInterval(obj.timer);
           obj.timer = setInterval(function() {
               if (obj.offsetLeft >= target) {
                   // 停止动画 本质是停止定时器
                   clearInterval(obj.timer);
              }
               obj.style.left = obj.offsetLeft + 1 + 'px';

          }, 30);
      }


day06 - Web APIs

学习目标:

能够封装简单动画函数

能够理解缓动动画的封装

能够使用动画函数

能够写出网页轮播图案例

能够写出移动端触屏事件

1.1. 动画函数封装

1.1.1 缓动效果原理

缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来

思路:

  1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来。

  2. 核心算法: (目标值 - 现在的位置)   /  10    做为每次移动的距离步长

  3. 停止的条件是: 让当前盒子位置等于目标位置就停止定时器 

  4. 注意步长值需要取整  

1.1.2 动画函数多个目标值之间移动

可以让动画函数从 800 移动到 500。

当我们点击按钮时候,判断步长是正值还是负值

​ 1.如果是正值,则步长往大了取整

​ 2.如果是负值,则步长 向小了取整

1.1.3 动函数添加回调函数

回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。

回调函数写的位置:定时器结束的位置。

1.1.4 动画完整版代码:

function animate(obj, target, callback) {
   // console.log(callback); callback = function() {} 调用的时候 callback()

   // 先清除以前的定时器,只保留当前的一个定时器执行
   clearInterval(obj.timer);
   obj.timer = setInterval(function() {
       // 步长值写到定时器的里面
       // 把我们步长值改为整数 不要出现小数的问题
       // var step = Math.ceil((target - obj.offsetLeft) / 10);
       var step = (target - obj.offsetLeft) / 10;
       step = step > 0 ? Math.ceil(step) : Math.floor(step);
       if (obj.offsetLeft == target) {
           // 停止动画 本质是停止定时器
           clearInterval(obj.timer);
           // 回调函数写到定时器结束里面
           // if (callback) {
           //     // 调用函数
           //     callback();
           // }
           callback && callback();
      }
       // 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
       obj.style.left = obj.offsetLeft + step + 'px';

  }, 15);
}

1.2. 常见网页特效案例

1.2.1 案例:网页轮播图

轮播图也称为焦点图,是网页中比较常见的网页特效。

功能需求:

​ 1.鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮。

​ 2.点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理。

​ 3.图片播放的同时,下面小圆圈模块跟随一起变化。

​ 4.点击小圆圈,可以播放相应图片。

​ 5.鼠标不经过轮播图,轮播图也会自动播放图片。

​ 6.鼠标经过,轮播图模块, 自动播放停止。


window.addEventListener('load', function() {
  // 1. 获取元素
  var arrow_l = document.querySelector('.arrow-l');
  var arrow_r = document.querySelector('.arrow-r');
  var focus = document.querySelector('.focus');
  var focusWidth = focus.offsetWidth;
  // 2. 鼠标经过focus 就显示隐藏左右按钮
  focus.addEventListener('mouseenter', function() {
      arrow_l.style.display = 'block';
      arrow_r.style.display = 'block';
      clearInterval(timer);
      timer = null; // 清除定时器变量
  });
  focus.addEventListener('mouseleave', function() {
      arrow_l.style.display = 'none';
      arrow_r.style.display = 'none';
      timer = setInterval(function() {
          //手动调用点击事件
          arrow_r.click();
      }, 2000);
  });
  // 3. 动态生成小圆圈 有几张图片,我就生成几个小圆圈
  var ul = focus.querySelector('ul');
  var ol = focus.querySelector('.circle');
  // console.log(ul.children.length);
  for (var i = 0; i < ul.children.length; i++) {
      // 创建一个小li
      var li = document.createElement('li');
      // 记录当前小圆圈的索引号 通过自定义属性来做
      li.setAttribute('index', i);
      // 把小li插入到ol 里面
      ol.appendChild(li);
      // 4. 小圆圈的排他思想 我们可以直接在生成小圆圈的同时直接绑定点击事件
      li.addEventListener('click', function() {
          // 干掉所有人 把所有的小li 清除 current 类名
          for (var i = 0; i < ol.children.length; i++) {
              ol.children[i].className = '';
          }
          // 留下我自己 当前的小li 设置current 类名
          this.className = 'current';
          // 5. 点击小圆圈,移动图片 当然移动的是 ul
          // ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 注意是负值
          // 当我们点击了某个小li 就拿到当前小li 的索引号
          var index = this.getAttribute('index');
          // 当我们点击了某个小li 就要把这个li 的索引号给 num  
          num = index;
          // 当我们点击了某个小li 就要把这个li 的索引号给 circle  
          circle = index;
          // num = circle = index;
          console.log(focusWidth);
          console.log(index);

          animate(ul, -index * focusWidth);
      })
  }
  // 把ol里面的第一个小li设置类名为 current
  ol.children[0].className = 'current';
  // 6. 克隆第一张图片(li)放到ul 最后面
  var first = ul.children[0].cloneNode(true);
  ul.appendChild(first);
  // 7. 点击右侧按钮, 图片滚动一张
  var num = 0;
  // circle 控制小圆圈的播放
  var circle = 0;
  // flag 节流阀
  var flag = true;
  arrow_r.addEventListener('click', function() {
      if (flag) {
          flag = false; // 关闭节流阀
          // 如果走到了最后复制的一张图片,此时 我们的ul 要快速复原 left 改为 0
          if (num == ul.children.length - 1) {
              ul.style.left = 0;
              num = 0;
          }
          num++;
          animate(ul, -num * focusWidth, function() {
              flag = true; // 打开节流阀
          });
          // 8. 点击右侧按钮,小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放
          circle++;
          // 如果circle == 4 说明走到最后我们克隆的这张图片了 我们就复原
          if (circle == ol.children.length) {
              circle = 0;
          }
          // 调用函数
          circleChange();
      }
  });

  // 9. 左侧按钮做法
  arrow_l.addEventListener('click', function() {
      if (flag) {
          flag = false;
          if (num == 0) {
              num = ul.children.length - 1;
              ul.style.left = -num * focusWidth + 'px';

          }
          num--;
          animate(ul, -num * focusWidth, function() {
              flag = true;
          });
          // 点击左侧按钮,小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放
          circle--;
          // 如果circle < 0 说明第一张图片,则小圆圈要改为第4个小圆圈(3)
          // if (circle < 0) {
          //     circle = ol.children.length - 1;
          // }
          circle = circle < 0 ? ol.children.length - 1 : circle;
          // 调用函数
          circleChange();
      }
  });

  function circleChange() {
      // 先清除其余小圆圈的current类名
      for (var i = 0; i < ol.children.length; i++) {
          ol.children[i].className = '';
      }
      // 留下当前的小圆圈的current类名
      ol.children[circle].className = 'current';
  }
  // 10. 自动播放轮播图
  var timer = setInterval(function() {
      //手动调用点击事件
      arrow_r.click();
  }, 2000);

})

 

1.2.2. 节流阀

防止轮播图按钮连续点击造成播放过快。

节流阀目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发。

核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

 开始设置一个变量var flag= true;

If(flag){flag = false; do something}       关闭水龙头

利用回调函数动画执行完毕, flag = true     打开水龙头

1.2.3. 案例:返回顶部

  1. 带有动画的返回顶部

  2. 此时可以继续使用我们封装的动画函数

  3. 只需要把所有的left 相关的值改为 跟 页面垂直滚动距离相关就可以了

  4. 页面滚动了多少,可以通过 window.pageYOffset 得到

  5. 最后是页面滚动,使用 window.scroll(x,y)


 //1. 获取元素
       var sliderbar = document.querySelector('.slider-bar');
       var banner = document.querySelector('.banner');
       // banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
       var bannerTop = banner.offsetTop
           // 当我们侧边栏固定定位之后应该变化的数值
       var sliderbarTop = sliderbar.offsetTop - bannerTop;
       // 获取main 主体元素
       var main = document.querySelector('.main');
       var goBack = document.querySelector('.goBack');
       var mainTop = main.offsetTop;
       // 2. 页面滚动事件 scroll
       document.addEventListener('scroll', function() {
               // console.log(11);
               // window.pageYOffset 页面被卷去的头部
               // console.log(window.pageYOffset);
               // 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位
               if (window.pageYOffset >= bannerTop) {
                   sliderbar.style.position = 'fixed';
                   sliderbar.style.top = sliderbarTop + 'px';
              } else {
                   sliderbar.style.position = 'absolute';
                   sliderbar.style.top = '300px';
              }
               // 4. 当我们页面滚动到main盒子,就显示 goback模块
               if (window.pageYOffset >= mainTop) {
                   goBack.style.display = 'block';
              } else {
                   goBack.style.display = 'none';
              }

          })
           // 3. 当我们点击了返回顶部模块,就让窗口滚动的页面的最上方
       goBack.addEventListener('click', function() {
           // 里面的x和y 不跟单位的 直接写数字即可
           // window.scroll(0, 0);
           // 因为是窗口滚动 所以对象是window
           animate(window, 0);
      });

1.2.4. 案例:筋头云案例

  1. 利用动画函数做动画效果

  2. 原先筋斗云的起始位置是0

  3. 鼠标经过某个小li,把当前小li的offsetLeft 位置做为目标值即可

  4. 鼠标离开某个小li,就把目标值设为 0

  5. 如果点击了某个小li, 就把li当前的位置存储起来,做为筋斗云的起始位置


window.addEventListener('load', function() {
           // 1. 获取元素
           var cloud = document.querySelector('.cloud');
           var c_nav = document.querySelector('.c-nav');
           var lis = c_nav.querySelectorAll('li');
           // 2. 给所有的小li绑定事件
           // 这个current 做为筋斗云的起始位置
           var current = 0;
           for (var i = 0; i < lis.length; i++) {
               // (1) 鼠标经过把当前小li 的位置做为目标值
               lis[i].addEventListener('mouseenter', function() {
                   animate(cloud, this.offsetLeft);
              });
               // (2) 鼠标离开就回到起始的位置
               lis[i].addEventListener('mouseleave', function() {
                   animate(cloud, current);
              });
               // (3) 当我们鼠标点击,就把当前位置做为目标值
               lis[i].addEventListener('click', function() {
                   current = this.offsetLeft;
              });
          }
      })

1.3. 触屏事件

1.3.1. 触屏事件概述

移动端浏览器兼容性较好,我们不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android和 IOS 都有。

touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。

常见的触屏事件如下:

 

 

1.3.2. 触摸事件对象(TouchEvent)

TouchEvent 是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等

touchstart、touchmove、touchend 三个事件都会各自有事件对象。

触摸事件对象重点我们看三个常见对象列表:

 

 

 

因为平时我们都是给元素注册触摸事件,所以重点记住 targetTocuhes

1.3.3.案例:移动端拖动元素

  1. touchstart、touchmove、touchend可以实现拖动元素

  2. 但是拖动元素需要当前手指的坐标值 我们可以使用  targetTouches[0] 里面的pageX 和 pageY

  3. 移动端拖动的原理:    手指移动中,计算出手指移动的距离。然后用盒子原来的位置 + 手指移动的距离

  4. 手指移动的距离:  手指滑动中的位置 减去  手指刚开始触摸的位置

    拖动元素三步曲:

    (1) 触摸元素 touchstart: 获取手指初始坐标,同时获得盒子原来的位置

    (2) 移动手指 touchmove: 计算手指的滑动距离,并且移动盒子

    (3) 离开手指 touchend:

    注意: 手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动 e.preventDefault();

 

 

 

day07 - Web APIs

学习目标:

能够写出移动端触屏事件能够写出常见的移动端特效能够使用移动端开发插件开发移动端特效能够使用移动端开发框架开发移动端特效能够写出 sessionStorage 数据的存储以及获取能够写出 localStorage 数据的存储以及获取能够说出它们两者的区别

1.1. 触屏事件

1.1.1 触屏事件概述

移动端浏览器兼容性较好,我们不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android 和 IOS 都有。touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。

常见的触屏事件如下:

 

 

 

1.1.2 触摸事件对象(TouchEvent)

TouchEvent 是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等

touchstart、touchmove、touchend 三个事件都会各自有事件对象。

触摸事件对象重点我们看三个常见对象列表:

 

 

 

因为平时我们都是给元素注册触摸事件,所以重点记住 targetTocuhes

1.1.3 移动端拖动元素

  1. touchstart、touchmove、touchend 可以实现拖动元素

  2. 但是拖动元素需要当前手指的坐标值 我们可以使用  targetTouches[0] 里面的pageX 和 pageY

  3. 移动端拖动的原理:    手指移动中,计算出手指移动的距离。然后用盒子原来的位置 + 手指移动的距离

  4. 手指移动的距离:  手指滑动中的位置 减去  手指刚开始触摸的位置

拖动元素三步曲:

(1) 触摸元素 touchstart: 获取手指初始坐标,同时获得盒子原来的位置

(2) 移动手指 touchmove: 计算手指的滑动距离,并且移动盒子

(3) 离开手指 touchend:

 

注意: 手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动 e.preventDefault();

1.2. 移动端常见特效

1.2.1 案例: 移动轮播图

移动端轮播图功能和基本PC端一致。

  1. 可以自动播放图片

  2. 手指可以拖动播放轮播图

1.2.2. 案例分析:

  1. 自动播放功能

  2. 开启定时器

  3. 移动端移动,可以使用translate 移动

  4. 想要图片优雅的移动,请添加过渡效果

  1.  

     

  2. 自动播放功能-无缝滚动

  3. 注意,我们判断条件是要等到图片滚动完毕再去判断,就是过渡完成后判断

  4. 此时需要添加检测过渡完成事件  transitionend 

  5. 判断条件:如果索引号等于 3 说明走到最后一张图片,此时 索引号要复原为 0

  6. 此时图片,去掉过渡效果,然后移动

  7. 如果索引号小于0, 说明是倒着走, 索引号等于2

  8.  

     

  9. 此时图片,去掉过渡效果,然后移动

1.2.3 classList 属性

classList属性是HTML5新增的一个属性,返回元素的类名。但是ie10以上版本支持。

该属性用于在元素中添加,移除及切换 CSS 类。有以下方法

添加类:

element.classList.add(’类名’);

focus.classList.add('current');

移除类:

element.classList.remove(’类名’);


focus.classList.remove('current');

切换类:

element.classList.toggle(’类名’);


focus.classList.toggle('current');

注意:以上方法里面,所有类名都不带点

1.2.4. 案例分析

  1. 小圆点跟随变化效果

  2. 把ol里面li带有current类名的选出来去掉类名 remove

  3. 让当前索引号的小li 加上 current   add

  4. 但是,是等着过渡结束之后变化,所以这个写到 transitionend 事件里面

  5.  

     

  1. 手指滑动轮播图

  2. 本质就是ul跟随手指移动,简单说就是移动端拖动元素

  3. 触摸元素touchstart:  获取手指初始坐标

  4. 移动手指touchmove:  计算手指的滑动距离,并且移动盒子

  5. 离开手指touchend:   根据滑动的距离分不同的情况

  6. 如果移动距离小于某个像素  就回弹原来位置

  7. 如果移动距离大于某个像素就上一张下一张滑动。

  8. 滑动也分为左滑动和右滑动判断的标准是 移动距离正负 如果是负值就是左滑 反之右滑

  9. 如果是左滑就播放下一张 (index++)

  10. 如果是右滑就播放上一张  (index--)

 

 

 

 

 

 

1.3.1. 案例:返回顶部

当页面滚动某个地方,就显示,否则隐藏

点击可以返回顶部

1.3.2.案例分析

  1. 滚动某个地方显示

  2. 事件:scroll页面滚动事件 

  3. 如果被卷去的头部(window.pageYOffset )大于某个数值

  4. 点击,window.scroll(0,0) 返回顶部

 

 

 

1.4. click 延时解决方案

移动端 click 事件会有 300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom) 页面。

解决方案:

​ 1. 禁用缩放。 浏览器禁用默认的双击缩放行为并且去掉300ms 的点击延迟。


 <meta name="viewport" content="user-scalable=no">

​ 2.利用touch事件自己封装这个事件解决300ms 延迟。

​ 原理就是:

  1. 当我们手指触摸屏幕,记录当前触摸时间

  2. 当我们手指离开屏幕, 用离开的时间减去触摸的时间

  3. 如果时间小于150ms,并且没有滑动过屏幕, 那么我们就定义为点击

代码如下:

//封装tap,解决click 300ms 延时
function tap (obj, callback) {
       var isMove = false;
       var startTime = 0; // 记录触摸时候的时间变量
       obj.addEventListener('touchstart', function (e) {
           startTime = Date.now(); // 记录触摸时间
      });
       obj.addEventListener('touchmove', function (e) {
           isMove = true;  // 看看是否有滑动,有滑动算拖拽,不算点击
      });
       obj.addEventListener('touchend', function (e) {
           if (!isMove && (Date.now() - startTime) < 150) {  // 如果手指触摸和离开时间小于150ms 算点击
               callback && callback(); // 执行回调函数
          }
           isMove = false;  // 取反 重置
           startTime = 0;
      });
}
//调用  
 tap(div, function(){   // 执行代码 });
  1. 使用插件。fastclick 插件解决300ms 延迟。

  2.  

     

1.5. 移动端常用开发插件

1.5.1. 什么是插件

移动端要求的是快速开发,所以我们经常会借助于一些插件来帮我完成操作,那么什么是插件呢?

JS 插件是 js 文件,它遵循一定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图和瀑布流插件。

特点:它一般是为了解决某个问题而专门存在,其功能单一,并且比较小。

我们以前写的animate.js 也算一个最简单的插件

fastclick 插件解决 300ms 延迟。 使用延时

GitHub官网地址: https://github.com/ftlabs/fastclick

1.5.2. 插件的使用

  1. 引入 js 插件文件。

  2. 按照规定语法使用。

  3. fastclick 插件解决 300ms 延迟。 使用延时

  4. GitHub官网地址: https://github.com/ftlabs/fastclick


    if ('addEventListener' in document) {
               document.addEventListener('DOMContentLoaded', function() {
                          FastClick.attach(document.body);
              }, false);
    }

1.5.3. Swiper 插件的使用

中文官网地址: https://www.swiper.com.cn/

  1. 引入插件相关文件。

  2. 按照规定语法使用

1.5.4. 其他移动端常见插件

lsuperslide: http://www.superslide2.com/

l iscroll: https://github.com/cubiq/iscroll

1.5.5. 插件的使用总结

1.确认插件实现的功能

2.去官网查看使用说明

3.下载插件

4.打开demo实例文件,查看需要引入的相关文件,并且引入

5.复制demo实例文件中的结构html,样式css以及js代码

1.5.6. 移动端视频插件 zy.media.js

H5 给我们提供了 video 标签,但是浏览器的支持情况不同。

不同的视频格式文件,我们可以通过source解决。

但是外观样式,还有暂停,播放,全屏等功能我们只能自己写代码解决。

这个时候我们可以使用插件方式来制作。

我们可以通过 JS 修改元素的大小、颜色、位置等样式。

 

1.6. 移动端常用开发框架

1.6.1. 移动端视频插件 zy.media.js

框架,顾名思义就是一套架构,它会基于自身的特点向用户提供一套较为完整的解决方案。框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发。

插件一般是为了解决某个问题而专门存在,其功能单一,并且比较小。

前端常用的框架有 Bootstrap、Vue、Angular、React 等。既能开发PC端,也能开发移动端

前端常用的移动端插件有 swiper、superslide、iscroll等。

框架: 大而全,一整套解决方案

插件: 小而专一,某个功能的解决方案

1.6.2. Bootstrap

Bootstrap 是一个简洁、直观、强悍的前端开发框架,它让 web 开发更迅速、简单。

它能开发PC端,也能开发移动端

Bootstrap JS插件使用步骤:

1.引入相关js 文件

2.复制HTML 结构

3.修改对应样式

4.修改相应JS 参数

1.7. 本地存储

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。

1.7.1.本地存储特性

1、数据存储在用户浏览器中

2、设置、读取方便、甚至页面刷新不丢失数据

3、容量较大,sessionStorage约5M、localStorage约20M

4、只能存储字符串,可以将对象JSON.stringify() 编码后存储

1.7.2.window.sessionStorage

1、生命周期为关闭浏览器窗口

2、在同一个窗口(页面)下数据可以共享

3、以键值对的形式存储使用

存储数据:


sessionStorage.setItem(key, value)

获取数据:


sessionStorage.getItem(key)

删除数据:


sessionStorage.removeItem(key)

清空数据:(所有都清除掉)


sessionStorage.clear()

1.7.3.window.localStorage

1、声明周期永久生效,除非手动删除 否则关闭页面也会存在

2、可以多窗口(页面)共享(同一浏览器可以共享)

  1. 以键值对的形式存储使用

存储数据:


localStorage.setItem(key, value)

获取数据:


localStorage.getItem(key)

删除数据:


localStorage.removeItem(key)

清空数据:(所有都清除掉)


localStorage.clear()

1.7.4.案例:记住用户名

如果勾选记住用户名, 下次用户打开浏览器,就在文本框里面自动显示上次登录的用户名

案例分析

  1. 把数据存起来,用到本地存储

  2. 关闭页面,也可以显示用户名,所以用到localStorage

  3. 打开页面,先判断是否有这个用户名,如果有,就在表单里面显示用户名,并且勾选复选框

  4. 当复选框发生改变的时候change事件

  5. 如果勾选,就存储,否则就移除

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-04-16 10:01  wq9  阅读(233)  评论(0编辑  收藏  举报