Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jquery.lazyload 插件 源码分析 #11

Open
jerryni opened this issue Apr 12, 2016 · 1 comment
Open

jquery.lazyload 插件 源码分析 #11

jerryni opened this issue Apr 12, 2016 · 1 comment
Labels

Comments

@jerryni
Copy link
Owner

jerryni commented Apr 12, 2016

jquery.lazyload.js的源码地址:
https://github.com/tuupola/jquery_lazyload/blob/master/jquery.lazyload.js

基本思路

首先给img标签设置自定义属性, 如data-src=图片真实URI, src为placeholder图片(如1x1px的图片);
在图片进入可视区域的时候, 将src设置成图片真实URI;

如何判断元素在可视区域思路分析

  • 红色矩形: 容器(默认容器是window)
  • 蓝色矩形: 子元素

也就是元素在容器的范围内, 情况有2种:

完全包含:
img2

边缘包含:
img2

反向思考可以想到, 如果有一个边缘不在容器里的话, 那么元素就不在可视区域了

看下图:

img1

说明:

  • cl(contaner left): 容器的左偏移距离
  • sl(sub left): 子元素左偏移距离
  • sw(sub width): 子元素宽度

因为4个边缘计算方式是同理的, 所以这边就以左边为例子

得出结论:

cl >= (sl + sw)的时候, 蓝色矩形是会在红色矩形左侧的;

关键代码分析

判断元素在容器左侧

  • 容器默认是window
  • 设置属性里加入了threshold(阀值)
$.leftofbegin = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.scrollLeft();
    } else {
        fold = $(settings.container).offset().left;
    }

    return fold >= $(element).offset().left + settings.threshold + $(element).width();
};

判断元素在可视区域内

$.inviewport = function(element, settings) {
    return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
        !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
};

自定义事件的使用

源码中的相关片段:

// one事件是只触发一次的事件方法
$self.one("appear", function() { 
    //这里是加载图片的一些代码............
});

// 进入可视区域后触发事件
$self.trigger("appear");

自定义$.expr[":"]的基本使用

:表达式也是一种选择器过滤方法;

内置的一些, 如:

  • $('input:text'): 选出所有type为text的input框
  • $('input:checked'): 选中所有选中的input框

源码中的相关片段, 添加了自定义过滤方法:

/*Use as $("img:below-the-fold").something()*/
$.extend($.expr[":"], {
    "below-the-fold": function(a) {
        return $.belowthefold(a, { threshold: 0 }); }
);

自己简单写个demo测试下$.expr[':']

功能是, 选中纯数字输入的input框, 代码如下:

html:

<input type="text" value="123">
<input type="text" value="123a">

script:

$.extend($.expr[':'], {
    'number': function (el) {
        return !isNaN(el.value);
    }
});

$('input:text:number'); // => <input type="text" value="123">
@jerryni jerryni added the js label Apr 12, 2016
@jerryni
Copy link
Owner Author

jerryni commented Apr 12, 2016

想起来一个类似的优化方案, 记录下

在移动端, 如果列表项太多, 这样dom太多, 会导致手机性能下降

看了下手淘列表页的解决方案如下:

以5页为一个单位, 如, 显示第10条的时候, 去掉前5条的dom,并设置原有高度,同时加上recycle类, 下次划上来的时候,可根据recycle类将数据再加载出来

taobao

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant