├── .csslintrc
├── .efesconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── README.md
├── dist
├── webp.js
├── webp.lazy.js
├── webp.lazy.min.js
└── webp.min.js
├── example
├── .csslintrc
├── .efesconfig
├── .eslintignore
├── .eslintrc
├── README.md
├── concatfile.json
├── gulpfile.js
├── images
│ ├── README.md
│ ├── arrow.png
│ ├── p1-bg.jpg
│ ├── p2-bg.jpg
│ ├── p3-bg.jpg
│ ├── p4-bg.jpg
│ ├── p5-bg.jpg
│ ├── p6-bg.jpg
│ ├── p7-bg.jpg
│ └── share.jpg
├── index.html
├── libs
│ ├── webp.lazy.min.js
│ ├── webp.min.js
│ └── zepto.min.js
├── package.json
├── scripts
│ ├── README.md
│ └── index.js
├── src
│ ├── css
│ │ ├── README.md
│ │ └── index.css
│ ├── html
│ │ └── index.html
│ ├── images
│ │ ├── p1-bg.jpg
│ │ ├── p2-bg.jpg
│ │ ├── p3-bg.jpg
│ │ ├── p4-bg.jpg
│ │ ├── p5-bg.jpg
│ │ ├── p6-bg.jpg
│ │ └── p7-bg.jpg
│ └── js
│ │ └── index.js
└── styles
│ ├── README.md
│ └── index.css
├── gulpfile.js
├── package.json
└── src
├── webp.js
└── webp.lazy.js
/.csslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "box-model": false,
3 | "display-property-grouping": false,
4 | "duplicate-properties": true,
5 | "empty-rules": true,
6 | "known-properties": true,
7 | "non-link-hover": true,
8 |
9 | "adjoining-classes": false,
10 | "box-sizing": false,
11 | "compatible-vendor-prefixes": false,
12 | "gradients": true,
13 | "text-indent": false,
14 | "vendor-prefix": true,
15 | "fallback-colors": true,
16 | "star-property-hack": false,
17 | "underscore-property-hack": false,
18 | "bulletproof-font-face": true,
19 |
20 | "font-faces": true,
21 | "import": false,
22 | "regex-selectors": true,
23 | "universal-selector": true,
24 | "unqualified-attributes": true,
25 | "zero-units": true,
26 | "overqualified-elements": false,
27 | "shorthand": true,
28 | "duplicate-background-images": false,
29 |
30 | "floats": false,
31 | "font-sizes": false,
32 | "ids": false,
33 | "important": true,
34 |
35 | "outline-none": false,
36 |
37 | "qualified-headings": false,
38 | "unique-headings": false
39 | }
40 |
--------------------------------------------------------------------------------
/.efesconfig:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpjs",
3 | "description": "auto load webp image",
4 | "id" : "webpjs",
5 | "publish_url" : "",
6 | "dev_url" : "",
7 | "lint": {
8 | "js": {
9 | "engine": "eslint",
10 | "config": ".eslintrc",
11 | "ignore": ".eslintignore"
12 | },
13 | "css": {
14 | "engine": "csslint",
15 | "config": ".csslintrc"
16 | }
17 | },
18 | "test": {}
19 | }
20 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | script/**/*.js
2 | libs/**/*.js
3 | .tmp/**/*.js
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 |
4 | "env": {
5 | "browser": true,
6 | "node": true,
7 | "amd": true,
8 | "es6": true
9 | },
10 |
11 | "extends": "eslint:recommended",
12 |
13 | "globals": {
14 | "edj": true,
15 | "jQuery": true,
16 | "console": true,
17 | "$": true
18 | },
19 |
20 | "rules": {
21 | "no-console": 0,
22 | "no-constant-condition": 1,
23 | "no-unreachable": 1,
24 |
25 | "complexity": [2, 10],
26 | "curly": [1, "all"],
27 | "eqeqeq": 1,
28 | "guard-for-in": 1,
29 | "no-empty-label": 2,
30 | "no-floating-decimal": 2,
31 | "no-iterator": 2,
32 | "no-lone-blocks": 2,
33 | "no-loop-func": 1,
34 | "no-multi-str": 2,
35 | "no-native-reassign": 2,
36 | "no-octal": 2,
37 | "no-octal-escape": 2,
38 | "no-proto": 2,
39 | "no-redeclare": 2,
40 | "no-self-compare": 2,
41 | "no-unused-expressions": 2,
42 | "wrap-iife": [2, "any"],
43 |
44 | "no-catch-shadow": 2,
45 | "no-label-var": 2,
46 | "no-shadow-restricted-names": 2,
47 | "no-undef": 2,
48 | "no-undef-init": 2,
49 | "no-unused-vars": [1, "all"],
50 | "no-use-before-define": 2,
51 | "no-undefined": 2,
52 |
53 | "camelcase": 1,
54 | "new-cap": 2,
55 | "no-array-constructor": 2,
56 | "no-new-object": 1,
57 | "no-spaced-func": 1,
58 | "semi-spacing": 1,
59 | "no-extra-parens": 2,
60 | "semi": [1, "always"],
61 | "space-return-throw-case": 2,
62 | "max-nested-callbacks": [2, 8]
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 | .*.swp
4 | .grunt
5 | .project
6 | .svn
7 | .tmp
8 | .maps
9 | .map
10 | .sass-cache
11 | .idea
12 | Thumbs.db
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # webpjs
2 |
3 | 此插件是针对移动平台做的,考虑到移动平台的特殊性,所以提供两个版本:
4 | 一个是没有lazy效果的webp.js,需要通过手动调用。
5 | 另一个是有lazy效果的webp.lazy.js(基于jquery.lazy.js修改)。
6 | 可视情况选择不同的版本。
7 |
8 | ## 2016.02.16更新
9 | 1、修改目录替换规则,当不配置orgDir和webpDir时,不替换目录,只提换后缀。
10 | 2、修改example中的gulp文件,将webp文件生成至image同目录。
11 |
12 | ## jquery/zepto webp插件
13 |
14 | ### 调用方式1:
15 |
16 | // 简化方式
17 | $.webp();
18 |
19 | 处理所有的有 lsrc 属性,且lsrc属性的目录中包含 images 目录的标签。
20 | 如果是img标签,则赋值src属性,其他类型的标签修改background-image属性。
21 |
22 | ### 调用方式2:
23 |
24 | $('.p3').webp();
25 |
26 | 查找处理.page.p3 这个dom节点下所有有 lsrc 属性, 且lsrc属性的目录中包含 images 目录的标签。
27 | 处理过程同上。
28 |
29 | ### options
30 | #### origSrc
31 | 用于存放图片原文件地址(png,jpg,jpeg,gif)的标签属性,默认为 lsrc
32 | #### origDir
33 | 图片原文件根目录,会替换为webp的根目录,支持自定义配置,默认为空,即不需要替换目录,只替换后缀
34 | #### webpDir
35 | 图片原webp文件目录,支持自定义配置,默认为空,即不需要替换目录,只替换后缀
36 |
37 | ## 注意1
38 | 由于采用lsrc的形式,所以img标签不要设定src属性,防止重复加载。
39 | 对于设置了背景图片的标签,请将css中的background-image单独拎出来注释掉。
40 |
41 | ## 注意2
42 | 由于是采用替换目录的方式修改webp图片的路径,所以必须保证orgDir和webpDir两个目录结构是相同的。
43 | 建议使用gulp之类的工具自动生成文件。example中有具体示例。
44 |
45 |
46 |
--------------------------------------------------------------------------------
/dist/webp.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /**
4 | * webp插件
5 | * 调用方式1:
6 | * $.webp();
7 | * 处理所有的有 lsrc 属性,且lsrc属性的目录中包含 images 目录的标签。
8 | * 如果是img标签,则赋值src属性,其他类型的标签修改background-image属性。
9 | *
10 | * 调用方式2:
11 | * $('.p3').webp({
12 | * origSrc: "lsrc", // 用于存放图片原文件地址(png,jpg,jpeg,gif)的标签属性
13 | * origDir: "images",// 图片原文件根目录,会替换为webp的根目录
14 | * webpDir: "webps"// 图片原webp文件目录
15 | *
16 | }); * 查找处理.page.p3 这个dom节点下所有有 lsrc 属性, 且lsrc属性的目录中包含 images 目录的标签。
17 |
18 | * 处理过程同上。
19 | *
20 | * 注意:由于采用lsrc的形式,所以img标签不要设定src属性,防止重复加载。
21 | * 对于设置了背景图片的标签,请将css中的background-image单独拎出来注释掉。
22 | */
23 |
24 | (function (window, $) {
25 |
26 | var __supportwebp = false;
27 |
28 | var __checked = false;
29 |
30 | var supportWebp = function supportWebp(callback) {
31 |
32 | if (__checked) {
33 | callback();
34 | return;
35 | }
36 |
37 | (function () {
38 | var webp = new Image();
39 | webp.onload = webp.onerror = function () {
40 | __checked = true;
41 | __supportwebp = webp.height === 2;
42 | webp.onload = webp.onerror = null;
43 | webp = null;
44 | callback();
45 | };
46 | //高度为2的一个webp图片
47 | webp.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
48 | })();
49 | };
50 |
51 | $.fn.webp = function (options) {
52 |
53 | var elements = this;
54 |
55 | var settings = {
56 | origSrc: "lsrc",
57 | origDir: "",
58 | webpDir: ""
59 | };
60 |
61 | /**
62 | * 先对elements进行处理,找到所以包含 origSrc 的子元素。
63 | */
64 | function adjust() {
65 |
66 | var _elements = undefined;
67 |
68 | elements.each(function () {
69 | var $this = $(this),
70 | _tmp = undefined;
71 | if (settings.skip_invisible && !$this.is(":visible")) {
72 | return;
73 | }
74 |
75 | var original = $this.attr(settings.origSrc);
76 |
77 | // 如果当前对象没有origSrc属性,同时当前对象不是图片节点,
78 | // 则查找子节点中有origSrc属性的节点,进行webp处理
79 | if (!original) {
80 | _tmp = $this.find("[" + settings.origSrc + "*=" + settings.origDir + "]");
81 | } else {
82 | _tmp = $this;
83 | }
84 |
85 | if (_elements && _elements.length > 0) {
86 | if ($.merge) {
87 | // jquery merge
88 | _elements = $.merge(_elements, _tmp);
89 | } else {
90 | // zepto merge
91 | _elements.concat(_tmp);
92 | }
93 | } else {
94 | _elements = _tmp;
95 | }
96 | });
97 |
98 | elements = _elements;
99 | }
100 |
101 | adjust();
102 |
103 | function update() {
104 |
105 | elements.each(function () {
106 | $(this).trigger("appear");
107 | });
108 | }
109 |
110 | if (options) {
111 | $.extend(settings, options);
112 | }
113 | if (options.origDir && !options.webpDir) {
114 | throw new Error('option webpDir undefined!');
115 | }
116 |
117 | elements.each(function () {
118 | var self = this;
119 | var $self = $(self);
120 |
121 | self.loaded = false;
122 |
123 | /* 触发appear事件时,控制替换或直接显示原图片 */
124 | $self.one("appear", function () {
125 |
126 | if (!this.loaded) {
127 | (function () {
128 |
129 | var original = $self.attr(settings.origSrc);
130 |
131 | // 替换webp目录和图片后缀
132 | if (__supportwebp) {
133 | original = original.replace(settings.origDir, settings.webpDir).replace(/\.(jpg|png|jpeg|gif)$/ig, '.webp');
134 | }
135 |
136 | $("").bind("load", function () {
137 |
138 | if ($self.is("img")) {
139 | // 如果当前节点是图片,则赋值src属性
140 | $self.attr("src", original);
141 | } else {
142 | // 如果当前节点不是图片,则赋值background-image属性
143 | $self.css("background-image", "url('" + original + "')");
144 | }
145 |
146 | self.loaded = true;
147 |
148 | /* Remove image from array so it is not looped next time. */
149 | var temp = $.grep(elements, function (element) {
150 | return !element.loaded;
151 | });
152 | elements = $(temp);
153 | }).attr("src", original);
154 | })();
155 | }
156 | });
157 | });
158 |
159 | supportWebp(function () {
160 | update();
161 | });
162 |
163 | return this;
164 | };
165 |
166 | $.extend($, {
167 | webp: function webp(options) {
168 | $(document).ready(function () {
169 | $(document).webp(options);
170 | });
171 | }
172 | });
173 | })(window, $);
--------------------------------------------------------------------------------
/dist/webp.lazy.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /*!
4 | * Webp Lazy Load - jQuery plugin for lazy loading webp images
5 | *
6 | * 修改自 jquery.lazy.js,删除了一些zepto不支持的代码。
7 | *
8 | * Licensed under the MIT license:
9 | * http://www.opensource.org/licenses/mit-license.php
10 | *
11 | */
12 |
13 | (function ($, window, document, undefined) {
14 | var $window = $(window);
15 |
16 | var __supportwebp = false;
17 |
18 | var __checked = false;
19 |
20 | var supportWebp = function supportWebp(callback) {
21 |
22 | if (__checked) {
23 | callback();
24 | return;
25 | }
26 |
27 | (function () {
28 | var webp = new Image();
29 | webp.onload = webp.onerror = function () {
30 | __checked = true;
31 | __supportwebp = webp.height === 2;
32 | webp.onload = webp.onerror = null;
33 | webp = null;
34 | callback();
35 | };
36 | //高度为2的一个webp图片
37 | webp.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
38 | })();
39 | };
40 |
41 | $.fn.webp = function (options) {
42 |
43 | var elements = this;
44 | var $container;
45 | var settings = {
46 | threshold: 0,
47 | failure_limit: 0,
48 | event: "scroll",
49 | effect: "show",
50 | container: window,
51 | origSrc: "lsrc",
52 | origDir: "",
53 | webpDir: "",
54 | skip_invisible: false,
55 | appear: null,
56 | load: null,
57 | placeholder: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
58 | };
59 |
60 | /**
61 | * 先对elements进行处理,找到所以包含 origSrc 的子元素。
62 | */
63 | function adjust() {
64 |
65 | var _elements;
66 |
67 | elements.each(function () {
68 | var $this = $(this),
69 | _tmp;
70 | if (settings.skip_invisible && !$this.is(":visible")) {
71 | return;
72 | }
73 | var original = $this.attr(settings.origSrc);
74 |
75 | // 如果当前对象没有origSrc属性,同时当前对象不是图片节点,
76 | // 则查找子节点中有origSrc属性的节点,进行webp处理
77 | if (!original) {
78 | _tmp = $this.find("[" + settings.origSrc + "*=" + settings.origDir + "]");
79 | } else {
80 | _tmp = $this;
81 | }
82 |
83 | if (_elements && _elements.length > 0) {
84 | if ($.merge) {
85 | // jquery merge
86 | _elements = $.merge(_elements, _tmp);
87 | } else {
88 | // zepto merge
89 | _elements.concat(_tmp);
90 | }
91 | } else {
92 | _elements = _tmp;
93 | }
94 | });
95 |
96 | elements = _elements;
97 | }
98 |
99 | adjust();
100 |
101 | function update() {
102 | var counter = 0;
103 |
104 | elements.each(function () {
105 | var $this = $(this);
106 | if (settings.skip_invisible && !$this.is(":visible")) {
107 | return;
108 | }
109 |
110 | if ($.abovethetop(this, settings) || $.leftofbegin(this, settings)) {
111 | /* Nothing. */
112 | } else if (!$.belowthefold(this, settings) && !$.rightoffold(this, settings)) {
113 | $this.trigger("appear");
114 | /* if we found an image we'll load, reset the counter */
115 | counter = 0;
116 | } else {
117 | if (++counter > settings.failure_limit) {
118 | return false;
119 | }
120 | }
121 | });
122 | }
123 |
124 | if (options) {
125 | /* Maintain BC for a couple of versions. */
126 | if (undefined !== options.failurelimit) {
127 | options.failure_limit = options.failurelimit;
128 | delete options.failurelimit;
129 | }
130 | if (undefined !== options.effectspeed) {
131 | options.effect_speed = options.effectspeed;
132 | delete options.effectspeed;
133 | }
134 |
135 | $.extend(settings, options);
136 | }
137 |
138 | if (options.origDir && !options.webpDir) {
139 | throw new Error('option webpDir undefined!');
140 | }
141 |
142 | /* Cache container as jQuery as object. */
143 | $container = settings.container === undefined || settings.container === window ? $window : $(settings.container);
144 |
145 | /* Fire one scroll event per scroll. Not one scroll event per image. */
146 | if (0 === settings.event.indexOf("scroll")) {
147 | $container.bind(settings.event, function () {
148 | return update();
149 | });
150 | }
151 |
152 | elements.each(function () {
153 | var self = this;
154 | var $self = $(self);
155 |
156 | self.loaded = false;
157 |
158 | /* If no src attribute given use data:uri. */
159 | if ($self.attr("src") === undefined || $self.attr("src") === false) {
160 | if ($self.is("img")) {
161 | $self.attr("src", settings.placeholder);
162 | }
163 | }
164 |
165 | /* When appear is triggered load original image. */
166 | $self.one("appear", function () {
167 | if (!this.loaded) {
168 | if (settings.appear) {
169 | var elements_left = elements.length;
170 | settings.appear.call(self, elements_left, settings);
171 | }
172 |
173 | var original = $self.attr(settings.origSrc);
174 |
175 | // 替换webp目录和图片后缀
176 | if (__supportwebp) {
177 | original = original.replace(settings.origDir, settings.webpDir).replace(/\.(jpg|png|jpeg|gif)$/ig, '.webp');
178 | }
179 |
180 | $("
").bind("load", function () {
181 |
182 | $self.hide();
183 | if ($self.is("img")) {
184 | $self.attr("src", original);
185 | } else {
186 | $self.css("background-image", "url('" + original + "')");
187 | }
188 | $self[settings.effect](settings.effect_speed);
189 |
190 | self.loaded = true;
191 |
192 | /* Remove image from array so it is not looped next time. */
193 | var temp = $.grep(elements, function (element) {
194 | return !element.loaded;
195 | });
196 | elements = $(temp);
197 |
198 | if (settings.load) {
199 | var elements_left = elements.length;
200 | settings.load.call(self, elements_left, settings);
201 | }
202 | }).attr("src", original);
203 | }
204 | });
205 |
206 | /* When wanted event is triggered load original image */
207 | /* by triggering appear. */
208 | if (0 !== settings.event.indexOf("scroll")) {
209 | $self.bind(settings.event, function () {
210 | if (!self.loaded) {
211 | $self.trigger("appear");
212 | }
213 | });
214 | }
215 | });
216 |
217 | /* Check if something appears when window is resized. */
218 | $window.bind("resize", function () {
219 | update();
220 | });
221 |
222 | /* With IOS5 force loading images when navigating with back button. */
223 | /* Non optimal workaround. */
224 | if (/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)) {
225 | $window.bind("pageshow", function (event) {
226 | if (event.originalEvent && event.originalEvent.persisted) {
227 | elements.each(function () {
228 | $(this).trigger("appear");
229 | });
230 | }
231 | });
232 | }
233 |
234 | /* Force initial check if images should appear. */
235 | $(document).ready(function () {
236 | supportWebp(function () {
237 | update();
238 | });
239 | });
240 |
241 | return this;
242 | };
243 |
244 | /* Convenience methods in jQuery namespace. */
245 | /* Use as $.belowthefold(element, {threshold : 100, container : window}) */
246 |
247 | $.belowthefold = function (element, settings) {
248 | var fold;
249 |
250 | if (settings.container === undefined || settings.container === window) {
251 | fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
252 | } else {
253 | fold = $(settings.container).offset().top + $(settings.container).height();
254 | }
255 | return fold <= $(element).offset().top - settings.threshold;
256 | };
257 |
258 | $.rightoffold = function (element, settings) {
259 | var fold;
260 |
261 | if (settings.container === undefined || settings.container === window) {
262 | fold = $window.width() + $window.scrollLeft();
263 | } else {
264 | fold = $(settings.container).offset().left + $(settings.container).width();
265 | }
266 |
267 | return fold <= $(element).offset().left - settings.threshold;
268 | };
269 |
270 | $.abovethetop = function (element, settings) {
271 | var fold;
272 |
273 | if (settings.container === undefined || settings.container === window) {
274 | fold = $window.scrollTop();
275 | } else {
276 | fold = $(settings.container).offset().top;
277 | }
278 | return fold >= $(element).offset().top + settings.threshold + $(element).height();
279 | };
280 |
281 | $.leftofbegin = function (element, settings) {
282 | var fold;
283 |
284 | if (settings.container === undefined || settings.container === window) {
285 | fold = $window.scrollLeft();
286 | } else {
287 | fold = $(settings.container).offset().left;
288 | }
289 |
290 | return fold >= $(element).offset().left + settings.threshold + $(element).width();
291 | };
292 |
293 | $.inviewport = function (element, settings) {
294 | return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
295 | };
296 |
297 | $.extend($, {
298 | webp: function webp(options) {
299 | $(document).webp(options);
300 | }
301 | });
302 | })($, window, document);
--------------------------------------------------------------------------------
/dist/webp.lazy.min.js:
--------------------------------------------------------------------------------
1 | "use strict";!function(e,i,t,n){var r=e(i),o=!1,a=!1,f=function(e){return a?void e():void function(){var i=new Image;i.onload=i.onerror=function(){a=!0,o=2===i.height,i.onload=i.onerror=null,i=null,e()},i.src="data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"}()};e.fn.webp=function(a){function l(){var i;A.each(function(){var t,n=e(this);if(!d.skip_invisible||n.is(":visible")){var r=n.attr(d.origSrc);t=r?n:n.find("["+d.origSrc+"*="+d.origDir+"]"),i&&i.length>0?e.merge?i=e.merge(i,t):i.concat(t):i=t}}),A=i}function c(){var i=0;A.each(function(){var t=e(this);if(!d.skip_invisible||t.is(":visible"))if(e.abovethetop(this,d)||e.leftofbegin(this,d));else if(e.belowthefold(this,d)||e.rightoffold(this,d)){if(++i>d.failure_limit)return!1}else t.trigger("appear"),i=0})}var s,A=this,d={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:i,origSrc:"lsrc",origDir:"",webpDir:"",skip_invisible:!1,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};if(l(),a&&(n!==a.failurelimit&&(a.failure_limit=a.failurelimit,delete a.failurelimit),n!==a.effectspeed&&(a.effect_speed=a.effectspeed,delete a.effectspeed),e.extend(d,a)),a.origDir&&!a.webpDir)throw new Error("option webpDir undefined!");return s=d.container===n||d.container===i?r:e(d.container),0===d.event.indexOf("scroll")&&s.bind(d.event,function(){return c()}),A.each(function(){var i=this,t=e(i);i.loaded=!1,(t.attr("src")===n||t.attr("src")===!1)&&t.is("img")&&t.attr("src",d.placeholder),t.one("appear",function(){if(!this.loaded){if(d.appear){var n=A.length;d.appear.call(i,n,d)}var r=t.attr(d.origSrc);o&&(r=r.replace(d.origDir,d.webpDir).replace(/\.(jpg|png|jpeg|gif)$/gi,".webp")),e("
").bind("load",function(){t.hide(),t.is("img")?t.attr("src",r):t.css("background-image","url('"+r+"')"),t[d.effect](d.effect_speed),i.loaded=!0;var n=e.grep(A,function(e){return!e.loaded});if(A=e(n),d.load){var o=A.length;d.load.call(i,o,d)}}).attr("src",r)}}),0!==d.event.indexOf("scroll")&&t.bind(d.event,function(){i.loaded||t.trigger("appear")})}),r.bind("resize",function(){c()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&r.bind("pageshow",function(i){i.originalEvent&&i.originalEvent.persisted&&A.each(function(){e(this).trigger("appear")})}),e(t).ready(function(){f(function(){c()})}),this},e.belowthefold=function(t,o){var a;return a=o.container===n||o.container===i?(i.innerHeight?i.innerHeight:r.height())+r.scrollTop():e(o.container).offset().top+e(o.container).height(),a<=e(t).offset().top-o.threshold},e.rightoffold=function(t,o){var a;return a=o.container===n||o.container===i?r.width()+r.scrollLeft():e(o.container).offset().left+e(o.container).width(),a<=e(t).offset().left-o.threshold},e.abovethetop=function(t,o){var a;return a=o.container===n||o.container===i?r.scrollTop():e(o.container).offset().top,a>=e(t).offset().top+o.threshold+e(t).height()},e.leftofbegin=function(t,o){var a;return a=o.container===n||o.container===i?r.scrollLeft():e(o.container).offset().left,a>=e(t).offset().left+o.threshold+e(t).width()},e.inviewport=function(i,t){return!(e.rightoffold(i,t)||e.leftofbegin(i,t)||e.belowthefold(i,t)||e.abovethetop(i,t))},e.extend(e,{webp:function(i){e(t).webp(i)}})}($,window,document);
--------------------------------------------------------------------------------
/dist/webp.min.js:
--------------------------------------------------------------------------------
1 | "use strict";!function(i,r){var n=!1,e=!1,o=function(i){return e?void i():void function(){var r=new Image;r.onload=r.onerror=function(){e=!0,n=2===r.height,r.onload=r.onerror=null,r=null,i()},r.src="data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"}()};r.fn.webp=function(i){function e(){var i=void 0;a.each(function(){var n=r(this),e=void 0;if(!c.skip_invisible||n.is(":visible")){var o=n.attr(c.origSrc);e=o?n:n.find("["+c.origSrc+"*="+c.origDir+"]"),i&&i.length>0?r.merge?i=r.merge(i,e):i.concat(e):i=e}}),a=i}function t(){a.each(function(){r(this).trigger("appear")})}var a=this,c={origSrc:"lsrc",origDir:"",webpDir:""};if(e(),i&&r.extend(c,i),i.origDir&&!i.webpDir)throw new Error("option webpDir undefined!");return a.each(function(){var i=this,e=r(i);i.loaded=!1,e.one("appear",function(){this.loaded||!function(){var o=e.attr(c.origSrc);n&&(o=o.replace(c.origDir,c.webpDir).replace(/\.(jpg|png|jpeg|gif)$/gi,".webp")),r("
").bind("load",function(){e.is("img")?e.attr("src",o):e.css("background-image","url('"+o+"')"),i.loaded=!0;var n=r.grep(a,function(i){return!i.loaded});a=r(n)}).attr("src",o)}()})}),o(function(){t()}),this},r.extend(r,{webp:function(i){r(document).ready(function(){r(document).webp(i)})}})}(window,$);
--------------------------------------------------------------------------------
/example/.csslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "box-model": false,
3 | "display-property-grouping": false,
4 | "duplicate-properties": true,
5 | "empty-rules": true,
6 | "known-properties": true,
7 | "non-link-hover": true,
8 |
9 | "adjoining-classes": false,
10 | "box-sizing": false,
11 | "compatible-vendor-prefixes": false,
12 | "gradients": true,
13 | "text-indent": false,
14 | "vendor-prefix": true,
15 | "fallback-colors": true,
16 | "star-property-hack": false,
17 | "underscore-property-hack": false,
18 | "bulletproof-font-face": true,
19 |
20 | "font-faces": true,
21 | "import": false,
22 | "regex-selectors": true,
23 | "universal-selector": true,
24 | "unqualified-attributes": true,
25 | "zero-units": true,
26 | "overqualified-elements": false,
27 | "shorthand": true,
28 | "duplicate-background-images": false,
29 |
30 | "floats": false,
31 | "font-sizes": false,
32 | "ids": false,
33 | "important": true,
34 |
35 | "outline-none": false,
36 |
37 | "qualified-headings": false,
38 | "unique-headings": false
39 | }
40 |
--------------------------------------------------------------------------------
/example/.efesconfig:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpjs",
3 | "description": "webpjs example",
4 | "id" : "webpjs",
5 | "publish_url" : "",
6 | "dev_url" : "",
7 | "lint": {
8 | "js": {
9 | "engine": "eslint",
10 | "config": ".eslintrc",
11 | "ignore": ".eslintignore"
12 | },
13 | "css": {
14 | "engine": "csslint",
15 | "config": ".csslintrc"
16 | }
17 | },
18 | "test": {}
19 | }
20 |
--------------------------------------------------------------------------------
/example/.eslintignore:
--------------------------------------------------------------------------------
1 | script/**/*.js
2 | libs/**/*.js
3 | .tmp/**/*.js
--------------------------------------------------------------------------------
/example/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 |
4 | "env": {
5 | "browser": true,
6 | "node": true,
7 | "amd": true,
8 | "es6": true
9 | },
10 |
11 | "extends": "eslint:recommended",
12 |
13 | "globals": {
14 | "edj": true,
15 | "jQuery": true,
16 | "console": true
17 | },
18 |
19 | "rules": {
20 | "no-console": 0,
21 | "no-constant-condition": 1,
22 | "no-unreachable": 1,
23 |
24 | "complexity": [2, 10],
25 | "curly": [1, "all"],
26 | "eqeqeq": 1,
27 | "guard-for-in": 1,
28 | "no-empty-label": 2,
29 | "no-floating-decimal": 2,
30 | "no-iterator": 2,
31 | "no-lone-blocks": 2,
32 | "no-loop-func": 1,
33 | "no-multi-str": 2,
34 | "no-native-reassign": 2,
35 | "no-octal": 2,
36 | "no-octal-escape": 2,
37 | "no-proto": 2,
38 | "no-redeclare": 2,
39 | "no-self-compare": 2,
40 | "no-unused-expressions": 2,
41 | "wrap-iife": [2, "any"],
42 |
43 | "no-catch-shadow": 2,
44 | "no-label-var": 2,
45 | "no-shadow-restricted-names": 2,
46 | "no-undef": 2,
47 | "no-undef-init": 2,
48 | "no-unused-vars": [1, "all"],
49 | "no-use-before-define": 2,
50 | "no-undefined": 2,
51 |
52 | "camelcase": 1,
53 | "new-cap": 2,
54 | "no-array-constructor": 2,
55 | "no-new-object": 1,
56 | "no-spaced-func": 1,
57 | "semi-spacing": 1,
58 | "no-extra-parens": 2,
59 | "semi": [1, "always"],
60 | "space-return-throw-case": 2,
61 | "max-nested-callbacks": [2, 8]
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | #webp js example
--------------------------------------------------------------------------------
/example/concatfile.json:
--------------------------------------------------------------------------------
1 | {
2 | "example": "https://github.com/edaijia-fe/efes-scaffold-example",
3 | "pkg": {
4 | "scripts/index.js": [
5 | "src/js/index.js"
6 | ],
7 | "styles/index.css": [
8 | "src/css/index.css"
9 | ]
10 | },
11 | "imgMinIgnore":[]
12 | }
13 |
--------------------------------------------------------------------------------
/example/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | browserSync = require('browser-sync'),
5 | pngquant = require('imagemin-pngquant'),
6 | imageminWebp = require('imagemin-webp'),
7 | merge = require('merge-stream'),
8 | fs = require('fs');
9 |
10 | var concatfile = JSON.parse(fs.readFileSync('./concatfile.json'));
11 | var efes = JSON.parse(fs.readFileSync('./.efesconfig'));
12 |
13 | // Load plugins
14 | var $ = require('gulp-load-plugins')();
15 | var ccDeps = [];
16 | var imgDeps = [];
17 |
18 | /* imagemin */
19 | gulp.task('imagemin', function() {
20 | var srcs = ['src/images/**/*'];
21 | if (concatfile.imgMinIgnore&&concatfile.imgMinIgnore.length > 0) { //获取不需要压缩的图片列表,从压缩目录中排除。
22 | for (var i = 0; i < concatfile.imgMinIgnore.length; i++) {
23 | srcs.push("!" + concatfile.imgMinIgnore[i]);
24 | }
25 |
26 | //将不需要压缩的图片copy到images目录
27 | gulp.src(concatfile.imgMinIgnore)
28 | .pipe(gulp.dest('images'))
29 | .pipe(browserSync.reload({
30 | stream: true
31 | }));
32 | }
33 |
34 | return gulp.src(srcs)
35 | .pipe($.imagemin({
36 | progressive: true,
37 | svgoPlugins: [{
38 | removeViewBox: false
39 | }],
40 | use: [pngquant()]
41 | }))
42 | .pipe(gulp.dest('images'))
43 | .pipe(browserSync.reload({
44 | stream: true
45 | }));
46 | });
47 | ccDeps.push('imagemin');
48 | imgDeps.push('imagemin');
49 |
50 |
51 | /* webp */
52 | gulp.task('webp', function() {
53 | var srcs = ['src/images/**/*'];
54 |
55 | return gulp.src(srcs)
56 | .pipe($.plumber())
57 | .pipe(imageminWebp({
58 | quality: 50
59 | })())
60 | .pipe(gulp.dest('images'))
61 | .pipe(browserSync.reload({
62 | stream: true
63 | }));
64 | });
65 | ccDeps.push('webp');
66 | imgDeps.push('webp');
67 |
68 |
69 | /*html*/
70 | gulp.task('html', function() {
71 | return gulp.src('src/html/**/*.html')
72 | .pipe(gulp.dest('.'))
73 | .pipe(browserSync.reload({
74 | stream: true
75 | }));
76 | });
77 | ccDeps.push('html');
78 |
79 |
80 | /* js-concat */
81 | gulp.task('js-concat',[], function() {
82 |
83 | var merges = [];
84 |
85 | Object.keys(concatfile.pkg).forEach(function(item) {
86 |
87 | if (/\.js$/i.test(item)) {
88 | var srcs = concatfile.pkg[item];
89 | var publish = item;
90 | var conc = gulp.src(srcs)
91 | .pipe($.concat(publish))
92 | .pipe(gulp.dest('.'))
93 | .pipe(browserSync.reload({
94 | stream: true
95 | }));
96 |
97 | merges.push(conc);
98 | }
99 |
100 | });
101 |
102 | return merge.apply(this, merges);
103 |
104 | });
105 |
106 | /* css-concat */
107 | gulp.task('css-concat', [], function() {
108 |
109 | var merges = [];
110 |
111 | Object.keys(concatfile.pkg).forEach(function(item) {
112 |
113 | if (/\.css$/i.test(item)) {
114 | var srcs = concatfile.pkg[item];
115 |
116 | var publish = item;
117 | var conc = gulp.src(srcs)
118 | .pipe($.concat(publish))
119 | .pipe(gulp.dest('.'))
120 | .pipe(browserSync.reload({
121 | stream: true
122 | }));
123 |
124 | merges.push(conc);
125 | }
126 |
127 |
128 | });
129 |
130 | return merge.apply(this, merges);
131 |
132 | });
133 |
134 | /* concat */
135 | gulp.task('concat', ccDeps, function() {
136 |
137 | var merges = [];
138 |
139 | Object.keys(concatfile.pkg).forEach(function(item) {
140 | var srcs = concatfile.pkg[item];
141 |
142 | var publish = item;
143 | var conc = gulp.src(srcs)
144 | .pipe($.concat(publish))
145 | .pipe(gulp.dest('.'))
146 | .pipe(browserSync.reload({
147 | stream: true
148 | }));
149 |
150 | merges.push(conc);
151 | });
152 |
153 | return merge.apply(this, merges);
154 |
155 | });
156 |
157 |
158 | gulp.task('browser-sync', function() {
159 |
160 | if (efes.dev_url.trim()) {
161 | return browserSync({
162 | open: 'external',
163 | proxy: efes.dev_url
164 | });
165 | }
166 |
167 | return browserSync({
168 | open: 'external',
169 | server: {
170 | baseDir: '.'
171 | }
172 | });
173 |
174 | });
175 |
176 |
177 | gulp.task('reload-concatfile',function(){
178 |
179 | concatfile = JSON.parse(fs.readFileSync('./concatfile.json'));
180 |
181 | });
182 |
183 |
184 | gulp.task('watch', ['concat'], function() {
185 |
186 | gulp.watch(['src/js/**/*.*'], ['js-concat']);
187 | gulp.watch(['src/css/**/*.*'], ['css-concat']);
188 | gulp.watch(['src/images/**/*.*'], imgDeps);
189 | gulp.watch(['src/html/**/*.*'], ['html']);
190 |
191 | gulp.watch('concatfile.json', ['reload-concatfile','concat']);
192 |
193 | gulp.start('browser-sync');
194 | });
195 |
196 |
197 | gulp.task('default', function() {
198 | gulp.start('watch');
199 | });
200 |
--------------------------------------------------------------------------------
/example/images/README.md:
--------------------------------------------------------------------------------
1 | # images
2 |
--------------------------------------------------------------------------------
/example/images/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/arrow.png
--------------------------------------------------------------------------------
/example/images/p1-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/p1-bg.jpg
--------------------------------------------------------------------------------
/example/images/p2-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/p2-bg.jpg
--------------------------------------------------------------------------------
/example/images/p3-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/p3-bg.jpg
--------------------------------------------------------------------------------
/example/images/p4-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/p4-bg.jpg
--------------------------------------------------------------------------------
/example/images/p5-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/p5-bg.jpg
--------------------------------------------------------------------------------
/example/images/p6-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/p6-bg.jpg
--------------------------------------------------------------------------------
/example/images/p7-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/p7-bg.jpg
--------------------------------------------------------------------------------
/example/images/share.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/images/share.jpg
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |