惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

zodream梦想开源/个人编程日记

angular 21 升级使用 signals 方案笔记-zodream梦想开源/个人编程日记 文件解析笔记-zodream梦想开源/个人编程日记 密码本开发笔记之读写与保存-zodream梦想开源/个人编程日记 基于 SkiaSharp 的轮廓获取-zodream梦想开源/个人编程日记 SkiaSharp 把 pixel byte[] 转成 SKBitmap-zodream梦想开源/个人编程日记 nas 使用 Docker 安装 gogs-zodream梦想开源/个人编程日记 复制 android 手机中的文件到电脑-zodream梦想开源/个人编程日记 最新|个人日记-zodream梦想开源/个人编程日记 升级 SiteServer CMS 并迁移到 Linux 服务器-zodream梦想开源/个人编程日记 最新|个人日记-zodream梦想开源/个人编程日记 最新|个人日记-zodream梦想开源/个人编程日记 最新|个人日记-zodream梦想开源/个人编程日记 周报:寻找优质的周刊-zodream梦想开源/个人编程日记 开发日志:对Markdown的代码块新增引用来源支持-zodream梦想开源/个人编程日记 周报:怎么写技术类的教程文章-zodream梦想开源/个人编程日记 css display:flex 布局尺寸超出问题-zodream梦想开源/个人编程日记 周报:SEO优化的思考-zodream梦想开源/个人编程日记 Edge 浏览器不适用 Edge Image Viewer 打开图片 -zodream梦想开源/个人编程日记 SEO 学习笔记(一) 内容来源-zodream梦想开源/个人编程日记 PHP 实现双因素身份认证(2FA)-zodream梦想开源/个人编程日记 winui3 自定义标题栏-zodream梦想开源/个人编程日记 WPF MVVM 获取List 多选数据-zodream梦想开源/个人编程日记 php 接入 WebAuthn 登录-zodream梦想开源/个人编程日记 Burp Suite 抓包-zodream梦想开源/个人编程日记 lnmp php集成环境安装包使用-zodream梦想开源/个人编程日记 js 进行在线编辑器开发-zodream梦想开源/个人编程日记 使用 indexnow 注意事项-zodream梦想开源/个人编程日记 Godot 使用字体图标 例如: Iconfont、FontAwesome-zodream梦想开源/个人编程日记 angular 15 对指定页面进行访问限制-zodream梦想开源/个人编程日记 CSS 使用 column-count 实现瀑布流出现内容分割的解决办法-zodream梦想开源/个人编程日记 angular 15 实现按下确认键,焦点移动到下一个表单或提交表单-zodream梦想开源/个人编程日记 input 确认按键事件在手机端不生效-zodream梦想开源/个人编程日记 C# 使用socket 进行通讯-zodream梦想开源/个人编程日记 Maui开发中Windows应用开启管理员权限-zodream梦想开源/个人编程日记 Maui 中自定义控件-zodream梦想开源/个人编程日记 TencentOS Server 3.1 安装 Nginx 1.23、PHP 8.2、MariaDB 10.11-zodream梦想开源/个人编程日记 angular 14 使用 ng-template 实现tree 结构显示-zodream梦想开源/个人编程日记 angular 14 替换 ComponentFactoryResolver 实现动态创建组件-zodream梦想开源/个人编程日记 c# 动态安装和卸载dll-zodream梦想开源/个人编程日记 慎用 CompositionTarget.Rendering-zodream梦想开源/个人编程日记 c# 重写 c++ 程序笔记:数据初始化-zodream梦想开源/个人编程日记 源码编译 aseprite-zodream梦想开源/个人编程日记 记录一下字符串分隔split各语言之间的不同-zodream梦想开源/个人编程日记 c# Gzip解码无头内容-zodream梦想开源/个人编程日记 Windows 10 查看内存占用-zodream梦想开源/个人编程日记 UWP 使用 win2d:加阴影-zodream梦想开源/个人编程日记 清除 PowerShell 历史记录-zodream梦想开源/个人编程日记 c# 调用 c++ 的dll-zodream梦想开源/个人编程日记 c# 重写 c++ 程序笔记:遍历-zodream梦想开源/个人编程日记 Net Core 与 UWP 共用类开发-zodream梦想开源/个人编程日记 hashcat(二)找回rar解压密码-zodream梦想开源/个人编程日记 Godot 学习笔记(一)-zodream梦想开源/个人编程日记 升级vue3记录-zodream梦想开源/个人编程日记 angular 12 显示数学公式-zodream梦想开源/个人编程日记 js 监听按键事件-zodream梦想开源/个人编程日记 angular 12 ng-deep 使用注意事项-zodream梦想开源/个人编程日记 angular 16 动态生成组件-zodream梦想开源/个人编程日记 angular 12 动画执行完成事件-zodream梦想开源/个人编程日记 angular 12 全局搜索组件-zodream梦想开源/个人编程日记 angular 12 中单例 Service 的使用-zodream梦想开源/个人编程日记 js 实现一个正则替换-zodream梦想开源/个人编程日记 uwp win2d 使用-zodream梦想开源/个人编程日记 UWP Custom Control自定义控件开发-zodream梦想开源/个人编程日记 UWP 读取应用内资源-zodream梦想开源/个人编程日记 gin 使用笔记(二)出错点-zodream梦想开源/个人编程日记 gin 使用笔记(一)基础-zodream梦想开源/个人编程日记 angular 关于自定义组件事件传递-zodream梦想开源/个人编程日记 angular 11 怎么获取 Content-Disposition-zodream梦想开源/个人编程日记 apache 使用gzip 压缩 js、css-zodream梦想开源/个人编程日记 angular 11 返回上一页保留页面数据的思考-zodream梦想开源/个人编程日记 一个简单的HTML音视频播放器-zodream梦想开源/个人编程日记 Net Core 实现一个简单的分页功能-zodream梦想开源/个人编程日记 关于内容中的 @用户 加 话题 的一些想法-zodream梦想开源/个人编程日记 Github Host 更改-zodream梦想开源/个人编程日记 OBS-Studio 等录屏软件录制显示器内容的黑屏的解决方法-zodream梦想开源/个人编程日记 angular 11 FormBuilder 中 FormGroup 和 FormArray 使用-zodream梦想开源/个人编程日记 angular 11 ngrx/effects 使用理解-zodream梦想开源/个人编程日记 angular 11 ngrx/store 使用理解-zodream梦想开源/个人编程日记 angular 10 直接获取表单值-zodream梦想开源/个人编程日记 angular 10 使用 tinymce 编辑器-zodream梦想开源/个人编程日记 htaccess 搭配 angular 10 放在二级目录-zodream梦想开源/个人编程日记 微信小程序跨页面传值-zodream梦想开源/个人编程日记 js 对 FileList 进行文件过滤上传-zodream梦想开源/个人编程日记 angular自定义表单组件支持 formControlName-zodream梦想开源/个人编程日记 基于不同形式的json响应处理-zodream梦想开源/个人编程日记 flutter CupertinoPicker 使用不显示-zodream梦想开源/个人编程日记 CC协议-zodream梦想开源/个人编程日记 flutter margin 负值实现-zodream梦想开源/个人编程日记 win10添加删除开机自启项-zodream梦想开源/个人编程日记 Wallpager Engine 删除记录-zodream梦想开源/个人编程日记 angular10教程之http 拦截器-zodream梦想开源/个人编程日记 dpl 文件-zodream梦想开源/个人编程日记 微信小程序开发记录(一)真机无法进入页面-zodream梦想开源/个人编程日记 flutter 跳转页面操作上一页-zodream梦想开源/个人编程日记 Regex Generator 使用指南-zodream梦想开源/个人编程日记 go init函数-zodream梦想开源/个人编程日记 angular 9 升级 angular 10-zodream梦想开源/个人编程日记 kotlin AndroidManifest 注意事项-zodream梦想开源/个人编程日记 对于zodream 框架的优化的思考-zodream梦想开源/个人编程日记 flutter 页面滚动条-zodream梦想开源/个人编程日记
jquery插件系列之延迟加载-zodream梦想开源/个人编程日记
2017-10-28 · via zodream梦想开源/个人编程日记

思路

  1. 当浏览器滚动到指定元素进行加载
  2. 可以加载多次

先上代码

enum LazyMode {
    once,
    every
}

class LazyItem {
    constructor(
       public element: JQuery,
       public callback: Function,
       public mode: LazyMode = LazyMode.once,
       public diff: number|Function = 0
    ) {
       element.on('lazy-refresh', () => {
           this.refresh();
       });
    }

    private _lastHeight: number; // 上次执行的高度
    /**
     * 重新刷新
     */
    public refresh() {
        this._lastHeight = undefined;
    }
    /**
     * 判断能否执行
     * @param height 
     * @param bottom 
     */
    public canRun(height: number, bottom: number): boolean {
       if (this.mode == LazyMode.once && this._lastHeight != undefined) {
           return false;
       }
       if (this.element.parent().length < 1) {
           // 判断元素是否被移除
           return false;
       }
       if (typeof this.diff == 'function') {
           return this.diff.call(this, height, bottom);
       }
       let top = this.element.offset().top;
       return top + this.diff >= height && top < bottom;
    }

    public run(height: number, bottom: number, index: number = 0): boolean {
       // if (!this.canRun(height, bottom)) {
       //     return false;
       // }
       this.callback.call(this, this.element, height, bottom, index);
       this._lastHeight = height;
       return true;
    }
}

class Lazy {
    constructor(
       public element: JQuery,
       options ? : LazyOptions
    ) {
       this.options = $.extend({}, new LazyDefaultOptions(), options);
       let $window = $(window);
       let instance = this;
       this._init();
       $window.scroll(function () {
           instance.scrollInvote();
       });
       // 首次执行
       this.scrollInvote();
    }

    public options: LazyOptions;

    private _data: Array<LazyItem>;

    /**
     * 页面滚动触发更新
     */
    public scrollInvote() {
       let $window = $(window);
       let height = $window.scrollTop();
       let bottom = $window.height() + height;
       this.run(height, bottom);
    }

    public run(height: number, bottom: number) {
       if (!this._data) {
           return;
       }
       let index: number = 0;
       for (let i = 0, length = this._data.length; i < length; i ++) {
           let item = this._data[i];
           if (item.canRun(height, bottom)) {
               item.run(height, bottom, index ++);
           }
           // if (item.run(height, bottom) && item.mode == LazyMode.once) {
           //     this._data.splice(i, 1);
           // }
       }
    }
    // 暂时只做一次
    private _init() {
       this._data = [];
       let instance = this;
       this.element.each(function (i, ele) {
           let item = new LazyItem(
               $(ele), 
               typeof instance.options.callback != 'function' ? Lazy.getMethod(instance.options.callback) : instance.options.callback,
               instance.options.mode, 
               instance.options.diff);
           instance._data.push(item);
       });
       $.each(this.options.data, (i, item: any) => {
           if (item instanceof LazyItem) {
               this._data.push(item);
               return;
           }
           if (typeof i == 'string') {
               item['tag'] = i;
           }
           $(item.tag).each(function (i, ele) {
               let lazyItem = new LazyItem(
                   $(ele), 
                   typeof item.callback != 'function' ? Lazy.getMethod(item.callback) : item.callback, 
                   item.mode || LazyMode.once, 
                   item.diff || 0 );
               instance._data.push(lazyItem);
           })
       });
    }

    /**
     * 全局方法集合
     */
    public static methods: {[name: string]: Function} = {};

    /**
     * 添加方法
     * @param name 
     * @param callback 
     */
    public static addMethod(name: string, callback: Function) {
        this.methods[name] = callback;
    }

    /**
     * 获取方法
     * @param name 
     */
    public static getMethod(name: string): Function {
        return this.methods[name];
    }
}
/**
 * 加载图片,如需加载动画控制请自定义
 */
Lazy.addMethod('img', function (imgEle: JQuery) {
   let img = imgEle.attr('data-src');
   $("<img />")
       .bind("load", function () {
           if (imgEle.is('img') || imgEle.is('video')) {
               imgEle.attr('src', img);
               return;
           }
           imgEle.css('background-image', 'url(' + img + ')');
       }).attr('src', img);
});
/**
 * 加载模板,需要引用 template 函数
 */
Lazy.addMethod('tpl', function (tplEle: JQuery) {
   let url = tplEle.attr('data-url');
   tplEle.addClass('lazy-loading');
   let templateId = tplEle.attr('data-tpl');
   $.get(url, data => {
       let html = '';
       if (typeof data === 'object') {
            if (data.code != 200) {
                return;
            }
            html = typeof data.data != 'string' ? template(templateId, data.data) : data.data;
       } else {
           html = data;
       }
       tplEle.removeClass('lazy-loading');
       tplEle.html(html);
       tplEle.trigger('lazyLoaded');
   }, typeof templateId === 'undefined' ? null : 'json');
});
/**
 * 滚动加载模板,需要引用 template 函数
 */
Lazy.addMethod('scroll', function (moreEle: JQuery) {
   let page: number = parseInt(moreEle.attr('data-page') || '0') + 1;
   let url = moreEle.attr('data-url');
   let templateId = moreEle.attr('data-tpl');
   let target = moreEle.attr('data-target');
   $.getJSON(url, {
       page: page
   }, function (data) {
       if (data.code != 200) {
           return;
       }
       if (typeof data.data != 'string') {
           data.data = template(templateId, data.data);
       }
       $(target).html(data.data);
       moreEle.attr('data-page', page);
   });
});

interface LazyOptions {
   [setting: string]: any,
   data ? : {[tag: string]: string | Object} | Array <Object> | Array < Lazy > ,
   tag ? : string | JQuery,
   callback ? : string | Function, // 回调
   mode ? : LazyMode, //执行模式
   diff ? : number|Function, //距离可视化区域的距离
}

class LazyDefaultOptions implements LazyOptions {
    mode: LazyMode = LazyMode.once;
    diff: number = 0
}

;
(function ($: any) {
    $.fn.lazyload = function (options ? : LazyOptions) {
        return new Lazy(this, options);
    };
})(jQuery);

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230

本插件使用 typescript 编写, js 请查看 GITHUB

本插件内置两个方法:

1.简单的图片加载。可以参考增加加载动画 给 img 的 src 设置一张 加载动态图片

<img src="loading.gif" data-src="image.jpg" class="lazy">

<script>
$("img.lazy").lazyload({
    callback: 'img'
});
</script>

1234567

2.局部加载。依赖 template 函数(参考 art-template

<div class="templateLazy lazy-loading" data-url="1" data-tpl="temp_tpl">div>

12

主要有两个参数 :

data-url   请求网址

data-tpl 模板元素id

lazy-loading 为加载动画)

<script id="temp_tpl" type="text/template">
<div>{{ id }}</div>
</script>

123

$(".templateLazy").lazyload({
    callback: 'tpl'
});

1234

请注意,本插件依赖 jquery

转载请保留原文链接: https://zodream.cn/blog/id/11.html