用jQuery的ajax加载完毕异步消息切换,js检查测验

时间:2020-02-08 00:39来源:亚洲城ca88唯一官方网站
时间: 2018-07-26阅读: 1506标签: js知识应用场景: 转载地址:https://segmentfault.com/a/1190000010744417 懒加载 什么是懒加载 懒加载其实就是延迟加载,是一种对网页性能优化的方式,比如当访问

时间: 2018-07-26阅读: 1506标签: js知识应用场景:

图片 1

转载地址:https://segmentfault.com/a/1190000010744417
懒加载
什么是懒加载
懒加载其实就是延迟加载,是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示的时候再发送图片请求,避免打开网页时加载过多资源。

只要页面加载了,其中在页面中出现的li就向控制台输出第几个发送请求;在本次加载的页面中,再将滚动条滚回前边的li,不再向控制台输出东西,也就是说已经显示过的li,不再向控制台输出东西。

“我们继续上午的ajax加载,把剩下的事情做完吧!”,老朱跟小白说道。

什么时候用懒加载
当页面中需要一次性载入很多图片的时候,往往都是需要用懒加载的。

bodyulli onclick="jumpOther()"0001/lili0002/lili0003/lili0004/lili0005/lili0006/lili0007/lili0008/lili0009/lili00010/lili00011/lili00012/lili00013/lili00014/lili00015/lili00016/lili00017/lili00018/lili00019/lili00020/lili 00021/lili00022/li/ul/body

“好的,我现在就打开上午的那个文件。”

懒加载原理
我们都知道HTML中的<img>标签是代表文档中的一个图像。。说了个废话。。

思路一:

图片 2

<img>标签有一个属性是src,用来表示图像的URL,当这个属性的值不为空时,浏览器就会根据这个值发送请求。如果没有src属性,就不会发送请求。

定义了一个全局变量lastItem,用来记下最后显示的li的index;如此,当li的indexlastItem,就表示li还没展示过,能输出东西。

“好的,小白,上午我们写的这个ajax加载是向handle页面发送一个用户uid,handle页面给我们返回这个用户的标识(uid)、姓名(userName)头像(imgSrc)、电话(tel)。现在我们实现这样一个简单的功能:点击用户列表中用户的名字,然后在详细信息显示区显示对应用户的详细信息。”

嗯?貌似这点可以利用一下?

 script type="text/javascript" var lastItem=0;$(document).ready(function () { sendAsk();window.addEventListener("scroll",function(e){sendAsk();});});function sendAsk(){var lis= $('ul').find("li");//swHeight=滚动的高度 窗体的高度;当li的offset高度=swHeight,那么说明当前li显示在可视区域了 var swHeight=$(window).scrollTop() $(window).height(); $.each(lis, function (index, item) { mTop=item.offsetTop; var dItem=index 1; if(mTopswHeightdItemlastItem){ console.log(index 1 "个发送请求 "); lastItem =1; } });}/script

图片 3

我先不设置src,需要的时候再设置?

思路二:

图片 4

nice,就是这样。

给每个li动态添加一个属性,用来表示这个li是否显示过;在发送请求后,设置属性为true即可;未显示过不添加属性即可。

“这是现在页面的一个HTML布局,ul标签里面的li上我增加了一个uid属性记录每一个人的uid值。”

我们先不给<img>设置src,把图片真正的URL放在另一个属性data-src中,在需要的时候也就是图片进入可视区域的之前,将URL取出放到src中。

function sendAsk() {var lis= $('ul').find("li"); //swHeight=滚动的高度 窗体的高度;当li的offset高度=swHeight,那么说明当前li显示在可视区域了 var swHeight=$(window).scrollTop() $(window).height(); $.each(lis, function (index, item) { mTop=item.offsetTop; if(mTopswHeight!item.getAttribute("data-send")){ console.log(index 1 "个发送请求 "); item.setAttribute("data-send","true"); } });}

“uid不是li的默认属性吧?”

实现
HTML结构

思路三:

“恩,在HTML5里面每一个标签都可以看作是一个对象,而对象除了自带的属性外,我们还可以给它们添加一些特有属性,这里的uid我是写死的,如果是实际开发的时候,这里的li肯定也是通过ajax加载用户列表生成的,由于咱是练习为了方便我就先这样写了。”

<div class="container">
  <div class="img-area">
    ![](./img/img1.png)
  </div>
  <div class="img-area">
    ![](./img/img2.png)
  </div>
  <div class="img-area">
    ![](./img/img3.png)
  </div>
  <div class="img-area">
    ![](./img/img4.png)
  </div>
  <div class="img-area">
    ![](./img/img5.png)
  </div>
</div>

利用getBoundingClientRect()方法,只要其中的.top=可视区域的高度即可

“你先说一下你的实现思路吧!”,老朱对小白说。

仔细观察一下,<img>标签此时是没有src属性的,只有alt和data-src属性。

function sendAsk(){var lis= $('ul').find("li"); //swHeight=滚动的高度 窗体的高度;当li的offset高度=swHeight,那么说明当前li显示在可视区域了 var swHeight=$(window).height(); $.each(lis, function (index, item) { mTop=item.getBoundingClientRect().top; console.log(mTop); if(mTop=swHeight){ console.log(index 1 "个发送请求 "); } });}

“我觉得应该通过鼠标的点击(click)事件来触发ajax加载,当加载完成以后把加载回来的信息放到左边的显示区里面。我先看一下页面布局,稍等我试试看能不能实现这个功能。”

alt 属性是一个必需的属性,它规定在图像无法显示时的替代文本。
data-* 全局属性:构成一类名称为自定义数据属性的属性,可以通过HTMLElement.dataset来访问。

拓展:

过了大概30分钟小白兴奋的找到老朱,“我实现出来了!你看看我的代码。”

如何判断元素是否在可视区域
方法一
网上看到好多这种方法,稍微记录一下。
通过document.documentElement.clientHeight
获取屏幕可视窗口高度
通过element.offsetTop
获取元素相对于文档顶部的距离
通过document.documentElement.scrollTop
获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离

getBoundingClientRect()

图片 5

然后判断②-③<①是否成立,如果成立,元素就在可视区域内。
方法二(推荐)
通过getBoundingClientRect()
方法来获取元素的大小以及位置,MDN上是这样描述的:
The Element.getBoundingClientRect() method returns the size of an element and its position relative to the viewport.

来源:

“不错!你给我讲讲实现的原理吧!”

这个方法返回一个名为ClientRect
的DOMRect
对象,包含了top
、right
、botton
、left
、width
、height
这些值。
MDN上有这样一张图:

“好的,因为我们现在需要通过点击右边的用户名字进行ajax加载,所以我首先通过$("#userList ul li")选择器找到名字所在的容器列表,然后使用jQuery的click事件来触发ajax请求。”

图片 6

“恩,不错!请继续。”

image.png

“ajax请求的关键参数是uid,而uid记录在了li标签上的uid属性里面,所以第一步就是通过$(this).attr()取当前触发点击事件(this)的li上的uid属性。拿到uid之后就可以向handle页面发送请求了,当请求成功以后,我先通过控制台输出查看返回的数据结构,然后把返回的用户信息放到对应的容器中。你看一下我实现的效果!”

可以看出返回的元素位置是相对于左上角而言的,而不是边距。
我们思考一下,什么情况下图片进入可视区域。
假设const bound = el.getBoundingClientRect();
来表示图片到可视区域顶部距离;并设 const clientHeight = window.innerHeight;
来表示可视区域的高度。
随着滚动条的向下滚动,bound.top
会越来越小,也就是图片到可视区域顶部的距离越来越小,当bound.top===clientHeight
时,图片的上沿应该是位于可视区域下沿的位置的临界点,再滚动一点点,图片就会进入可视区域。
也就是说,在bound.top<=clientHeight
时,图片是在可视区域内的。
我们这样判断:

图片 7

function isInSight(el) {
  const bound = el.getBoundingClientRect();
  const clientHeight = window.innerHeight;
  //如果只考虑向下滚动加载
  //const clientWidth = window.innerWeight;
  return bound.top <= clientHeight   100;
}

“非常好!你的进步很快,以后如果你要是做web前端开发ajax加载数据会在各种功能模块中遇到,好的开始就是成功的一半,以后碰到不管多复杂的页面、一个页面不管同时发出多少个ajax请求,都是以今天的这个功能为基础的。所以我希望你能再次认真把jQuery中的ajax所有的参数介绍看一遍,脑海里有了这些参数的印象,以后碰到具体问题最起码知道ajax哪些功能可以实现,哪些功能不能实现,你说对不对?”

这里有个 100是为了提前加载。

“没问题~”

经提醒。。这个方法性能


加载图片
页面打开时需要对所有图片进行检查,是否在可视区域内,如果是就加载。

想学H5的朋友可以关注老炉,您的关注是我持续更新《小白HTML5成长之路》的动力!

function checkImgs() {
  const imgs = document.querySelectorAll('.my-photo');
  Array.from(imgs).forEach(el => {
    if (isInSight(el)) {
      loadImg(el);
    }
  })
}

function loadImg(el) {
  if (!el.src) {
    const source = el.dataset.src;
    el.src = source;
  }
}

这里应该是有一个优化的地方,设一个标识符标识已经加载图片的index,当滚动条滚动时就不需要遍历所有的图片,只需要遍历未加载的图片即可。

函数节流
在类似于滚动条滚动等频繁的DOM操作时,总会提到“函数节流、函数去抖”。

所谓的函数节流,也就是让一个函数不要执行的太频繁,减少一些过快的调用来节流。

基本步骤:

获取第一次触发事件的时间戳
获取第二次触发事件的时间戳
时间差如果大于某个阈值就执行事件,然后重置第一个时间

function throttle(fn, mustRun = 500) {
  const timer = null;
  let previous = null;
  return function() {
    const now = new Date();
    const context = this;
    const args = arguments;
    if (!previous){
      previous = now;
    }
    const remaining = now - previous;
    if (mustRun && remaining >= mustRun) {
      fn.apply(context, args);
      previous = now;
    }
  }
}

这里的mustRun就是调用函数的时间间隔,无论多么频繁的调用fn,只有remaining>=mustRun时fn才能被执行。

方法三 IntersectionObserver
经大佬提醒,发现了这个方法
先附上链接:
jjc大大:https://github.com/justjavac/the-front-end-knowledge-you-may-dont-know/issues/10
阮一峰大大:http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html
API Sketch for Intersection Observers:https://github.com/WICG/IntersectionObserver
IntersectionObserver
可以自动观察元素是否在视口内。

var io = new IntersectionObserver(callback, option);
// 开始观察
io.observe(document.getElementById('example'));
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();

callback的参数是一个数组,每个数组都是一个IntersectionObserverEntry对象,包括以下属性:

属性 描述
time 可见性发生变化的时间,单位为毫秒
rootBounds 与getBoundingClientRect()方法的返回值一样
boundingClientRect 目标元素的矩形区域的信息
intersectionRect 目标元素与视口(或根元素)的交叉区域的信息
intersectionRatio 目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
target 被观察的目标元素,是一个 DOM 节点对象
我们需要用到intersectionRatio来判断是否在可视区域内,当intersectionRatio > 0 && intersectionRatio <= 1即在可视区域内。

代码

function checkImgs() {
  const imgs = Array.from(document.querySelectorAll(".my-photo"));
  imgs.forEach(item => io.observe(item));
}

function loadImg(el) {
  if (!el.src) {
    const source = el.dataset.src;
    el.src = source;
  }
}

const io = new IntersectionObserver(ioes => {
  ioes.forEach(ioe => {
    const el = ioe.target;
    const intersectionRatio = ioe.intersectionRatio;
    if (intersectionRatio > 0 && intersectionRatio <= 1) {
      loadImg(el);
    }
    el.onload = el.onerror = () => io.unobserve(el);
  });
});

编辑:亚洲城ca88唯一官方网站 本文来源:用jQuery的ajax加载完毕异步消息切换,js检查测验

关键词: 亚洲城ca88