├── .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 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /example/libs/webp.lazy.min.js: -------------------------------------------------------------------------------- 1 | "use strict";!function(e,t,i,n){var o=e(t),r=function(){var e=!1;return function(){var t=new Image;t.onload=t.onerror=function(){e=2===t.height,t.onload=t.onerror=null,t=null},t.src="data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"}(),e};e.fn.webp=function(a){function l(){var t;s.each(function(){var i,n=e(this);if(!A.skip_invisible||n.is(":visible")){var o=n.attr(A.origSrc);i=o?n:n.find("["+A.origSrc+"*="+A.origDir+"]"),t&&t.length>0?t.concat(i):t=i}}),s=t}function f(){var t=0;s.each(function(){var i=e(this);if(!A.skip_invisible||i.is(":visible"))if(e.abovethetop(this,A)||e.leftofbegin(this,A));else if(e.belowthefold(this,A)||e.rightoffold(this,A)){if(++t>A.failure_limit)return!1}else i.trigger("appear"),t=0})}var c,s=this,A={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:t,origSrc:"lsrc",origDir:"images",webpDir:"webps",skip_invisible:!1,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return 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(A,a)),c=A.container===n||A.container===t?o:e(A.container),0===A.event.indexOf("scroll")&&c.bind(A.event,function(){return f()}),s.each(function(){var t=this,i=e(t);t.loaded=!1,(i.attr("src")===n||i.attr("src")===!1)&&i.is("img")&&i.attr("src",A.placeholder),i.one("appear",function(){if(!this.loaded){if(A.appear){var n=s.length;A.appear.call(t,n,A)}var o=i.attr(A.origSrc);r&&(o=o.replace(A.origDir,A.webpDir).replace(/\.(jpg|png|jpeg|gif)$/gi,".webp")),e("").bind("load",function(){i.hide(),i.is("img")?i.attr("src",o):i.css("background-image","url('"+o+"')"),i[A.effect](A.effect_speed),t.loaded=!0;var n=e.grep(s,function(e){return!e.loaded});if(s=e(n),A.load){var r=s.length;A.load.call(t,r,A)}}).attr("src",o)}}),0!==A.event.indexOf("scroll")&&i.bind(A.event,function(){t.loaded||i.trigger("appear")})}),o.bind("resize",function(){f()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&o.bind("pageshow",function(t){t.originalEvent&&t.originalEvent.persisted&&s.each(function(){e(this).trigger("appear")})}),e(i).ready(function(){f()}),this},e.belowthefold=function(i,r){var a;return a=r.container===n||r.container===t?(t.innerHeight?t.innerHeight:o.height())+o.scrollTop():e(r.container).offset().top+e(r.container).height(),console.log("belowthefold",a,e(i).offset().top-r.threshold),a<=e(i).offset().top-r.threshold},e.rightoffold=function(i,r){var a;return a=r.container===n||r.container===t?o.width()+o.scrollLeft():e(r.container).offset().left+e(r.container).width(),a<=e(i).offset().left-r.threshold},e.abovethetop=function(i,r){var a;return r.container===n||r.container===t?(a=o.scrollTop(),console.log(1)):(a=e(r.container).offset().top,console.log(2)),console.log(e(i).attr("lsrc"),a,e(i).offset().top+r.threshold+e(i).height()),a>=e(i).offset().top+r.threshold+e(i).height()},e.leftofbegin=function(i,r){var a;return a=r.container===n||r.container===t?o.scrollLeft():e(r.container).offset().left,a>=e(i).offset().left+r.threshold+e(i).width()},e.inviewport=function(t,i){return!(e.rightoffold(t,i)||e.leftofbegin(t,i)||e.belowthefold(t,i)||e.abovethetop(t,i))},e.extend(e,{webp:function(t){e(i).webp(t)}})}($,window,document); -------------------------------------------------------------------------------- /example/libs/webp.min.js: -------------------------------------------------------------------------------- 1 | "use strict";!function(i,r){var n=function(){var i=!1;return function(){var r=new Image;r.onload=r.onerror=function(){i=2===r.height,r.onload=r.onerror=null,r=null},r.src="data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"}(),i};r.fn.webp=function(i){function e(){var i=void 0;t.each(function(){var n=r(this),e=void 0;if(!a.skip_invisible||n.is(":visible")){var o=n.attr(a.origSrc);e=o?n:n.find("["+a.origSrc+"*="+a.origDir+"]"),i&&i.length>0?i.concat(e):i=e}}),t=i}function o(){t.each(function(){r(this).trigger("appear")})}var t=this,a={origSrc:"lsrc",origDir:"images",webpDir:"webps"};return e(),i&&r.extend(a,i),t.each(function(){var i=this,e=r(i);i.loaded=!1,e.one("appear",function(){this.loaded||!function(){var o=e.attr(a.origSrc);n&&(o=o.replace(a.origDir,a.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(t,function(i){return!i.loaded});t=r(n)}).attr("src",o)}()})}),o(),this},r.extend(r,{webp:function(i){r(document).ready(function(){r(document).webp(i)})}})}(window,$); -------------------------------------------------------------------------------- /example/libs/zepto.min.js: -------------------------------------------------------------------------------- 1 | /* Zepto v1.1.6 - zepto event ajax form ie - zeptojs.com/license */ 2 | var Zepto=(function(){var undefined,key,$,classList,emptyArray=[],slice=emptyArray.slice,filter=emptyArray.filter,document=window.document,elementDisplay={},classCache={},cssNumber={"column-count":1,"columns":1,"font-weight":1,"line-height":1,"opacity":1,"z-index":1,"zoom":1},fragmentRE=/^\s*<(\w+|!)[^>]*>/,singleTagRE=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,tagExpanderRE=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,rootNodeRE=/^(?:body|html)$/i,capitalRE=/([A-Z])/g,methodAttributes=["val","css","html","text","data","width","height","offset"],adjacencyOperators=["after","prepend","before","append"],table=document.createElement("table"),tableRow=document.createElement("tr"),containers={"tr":document.createElement("tbody"),"tbody":table,"thead":table,"tfoot":table,"td":tableRow,"th":tableRow,"*":document.createElement("div")},readyRE=/complete|loaded|interactive/,simpleSelectorRE=/^[\w-]*$/,class2type={},toString=class2type.toString,zepto={},camelize,uniq,tempParent=document.createElement("div"),propMap={"tabindex":"tabIndex","readonly":"readOnly","for":"htmlFor","class":"className","maxlength":"maxLength","cellspacing":"cellSpacing","cellpadding":"cellPadding","rowspan":"rowSpan","colspan":"colSpan","usemap":"useMap","frameborder":"frameBorder","contenteditable":"contentEditable"},isArray=Array.isArray||function(object){return object instanceof Array};zepto.matches=function(element,selector){if(!selector||!element||element.nodeType!==1){return false}var matchesSelector=element.webkitMatchesSelector||element.mozMatchesSelector||element.oMatchesSelector||element.matchesSelector;if(matchesSelector){return matchesSelector.call(element,selector)}var match,parent=element.parentNode,temp=!parent;if(temp){(parent=tempParent).appendChild(element)}match=~zepto.qsa(parent,selector).indexOf(element);temp&&tempParent.removeChild(element);return match};function type(obj){return obj==null?String(obj):class2type[toString.call(obj)]||"object"}function isFunction(value){return type(value)=="function"}function isWindow(obj){return obj!=null&&obj==obj.window}function isDocument(obj){return obj!=null&&obj.nodeType==obj.DOCUMENT_NODE}function isObject(obj){return type(obj)=="object"}function isPlainObject(obj){return isObject(obj)&&!isWindow(obj)&&Object.getPrototypeOf(obj)==Object.prototype}function likeArray(obj){return typeof obj.length=="number"}function compact(array){return filter.call(array,function(item){return item!=null})}function flatten(array){return array.length>0?$.fn.concat.apply([],array):array}camelize=function(str){return str.replace(/-+(.)?/g,function(match,chr){return chr?chr.toUpperCase():""})};function dasherize(str){return str.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}uniq=function(array){return filter.call(array,function(item,idx){return array.indexOf(item)==idx})};function classRE(name){return name in classCache?classCache[name]:(classCache[name]=new RegExp("(^|\\s)"+name+"(\\s|$)"))}function maybeAddPx(name,value){return(typeof value=="number"&&!cssNumber[dasherize(name)])?value+"px":value}function defaultDisplay(nodeName){var element,display;if(!elementDisplay[nodeName]){element=document.createElement(nodeName);document.body.appendChild(element);display=getComputedStyle(element,"").getPropertyValue("display");element.parentNode.removeChild(element);display=="none"&&(display="block");elementDisplay[nodeName]=display}return elementDisplay[nodeName]}function children(element){return"children" in element?slice.call(element.children):$.map(element.childNodes,function(node){if(node.nodeType==1){return node}})}zepto.fragment=function(html,name,properties){var dom,nodes,container;if(singleTagRE.test(html)){dom=$(document.createElement(RegExp.$1))}if(!dom){if(html.replace){html=html.replace(tagExpanderRE,"<$1>")}if(name===undefined){name=fragmentRE.test(html)&&RegExp.$1}if(!(name in containers)){name="*"}container=containers[name];container.innerHTML=""+html;dom=$.each(slice.call(container.childNodes),function(){container.removeChild(this)})}if(isPlainObject(properties)){nodes=$(dom);$.each(properties,function(key,value){if(methodAttributes.indexOf(key)>-1){nodes[key](value)}else{nodes.attr(key,value)}})}return dom};zepto.Z=function(dom,selector){dom=dom||[];dom.__proto__=$.fn;dom.selector=selector||"";return dom};zepto.isZ=function(object){return object instanceof zepto.Z};zepto.init=function(selector,context){var dom;if(!selector){return zepto.Z()}else{if(typeof selector=="string"){selector=selector.trim();if(selector[0]=="<"&&fragmentRE.test(selector)){dom=zepto.fragment(selector,RegExp.$1,context),selector=null}else{if(context!==undefined){return $(context).find(selector)}else{dom=zepto.qsa(document,selector)}}}else{if(isFunction(selector)){return $(document).ready(selector)}else{if(zepto.isZ(selector)){return selector}else{if(isArray(selector)){dom=compact(selector)}else{if(isObject(selector)){dom=[selector],selector=null}else{if(fragmentRE.test(selector)){dom=zepto.fragment(selector.trim(),RegExp.$1,context),selector=null}else{if(context!==undefined){return $(context).find(selector)}else{dom=zepto.qsa(document,selector)}}}}}}}}return zepto.Z(dom,selector)};$=function(selector,context){return zepto.init(selector,context)};function extend(target,source,deep){for(key in source){if(deep&&(isPlainObject(source[key])||isArray(source[key]))){if(isPlainObject(source[key])&&!isPlainObject(target[key])){target[key]={}}if(isArray(source[key])&&!isArray(target[key])){target[key]=[]}extend(target[key],source[key],deep)}else{if(source[key]!==undefined){target[key]=source[key]}}}}$.extend=function(target){var deep,args=slice.call(arguments,1);if(typeof target=="boolean"){deep=target;target=args.shift()}args.forEach(function(arg){extend(target,arg,deep)});return target};zepto.qsa=function(element,selector){var found,maybeID=selector[0]=="#",maybeClass=!maybeID&&selector[0]==".",nameOnly=maybeID||maybeClass?selector.slice(1):selector,isSimple=simpleSelectorRE.test(nameOnly);return(isDocument(element)&&isSimple&&maybeID)?((found=element.getElementById(nameOnly))?[found]:[]):(element.nodeType!==1&&element.nodeType!==9)?[]:slice.call(isSimple&&!maybeID?maybeClass?element.getElementsByClassName(nameOnly):element.getElementsByTagName(selector):element.querySelectorAll(selector))};function filtered(nodes,selector){return selector==null?$(nodes):$(nodes).filter(selector)}$.contains=document.documentElement.contains?function(parent,node){return parent!==node&&parent.contains(node)}:function(parent,node){while(node&&(node=node.parentNode)){if(node===parent){return true}}return false};function funcArg(context,arg,idx,payload){return isFunction(arg)?arg.call(context,idx,payload):arg}function setAttribute(node,name,value){value==null?node.removeAttribute(name):node.setAttribute(name,value)}function className(node,value){var klass=node.className||"",svg=klass&&klass.baseVal!==undefined;if(value===undefined){return svg?klass.baseVal:klass}svg?(klass.baseVal=value):(node.className=value)}function deserializeValue(value){try{return value?value=="true"||(value=="false"?false:value=="null"?null:+value+""==value?+value:/^[\[\{]/.test(value)?$.parseJSON(value):value):value}catch(e){return value}}$.type=type;$.isFunction=isFunction;$.isWindow=isWindow;$.isArray=isArray;$.isPlainObject=isPlainObject;$.isEmptyObject=function(obj){var name;for(name in obj){return false}return true};$.inArray=function(elem,array,i){return emptyArray.indexOf.call(array,elem,i)};$.camelCase=camelize;$.trim=function(str){return str==null?"":String.prototype.trim.call(str)};$.uuid=0;$.support={};$.expr={};$.map=function(elements,callback){var value,values=[],i,key;if(likeArray(elements)){for(i=0;i=0?idx:idx+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){if(this.parentNode!=null){this.parentNode.removeChild(this)}})},each:function(callback){emptyArray.every.call(this,function(el,idx){return callback.call(el,idx,el)!==false});return this},filter:function(selector){if(isFunction(selector)){return this.not(this.not(selector))}return $(filter.call(this,function(element){return zepto.matches(element,selector)}))},add:function(selector,context){return $(uniq(this.concat($(selector,context))))},is:function(selector){return this.length>0&&zepto.matches(this[0],selector)},not:function(selector){var nodes=[];if(isFunction(selector)&&selector.call!==undefined){this.each(function(idx){if(!selector.call(this,idx)){nodes.push(this)}})}else{var excludes=typeof selector=="string"?this.filter(selector):(likeArray(selector)&&isFunction(selector.item))?slice.call(selector):$(selector);this.forEach(function(el){if(excludes.indexOf(el)<0){nodes.push(el)}})}return $(nodes)},has:function(selector){return this.filter(function(){return isObject(selector)?$.contains(this,selector):$(this).find(selector).size()})},eq:function(idx){return idx===-1?this.slice(idx):this.slice(idx,+idx+1)},first:function(){var el=this[0];return el&&!isObject(el)?el:$(el)},last:function(){var el=this[this.length-1];return el&&!isObject(el)?el:$(el)},find:function(selector){var result,$this=this;if(!selector){result=$()}else{if(typeof selector=="object"){result=$(selector).filter(function(){var node=this;return emptyArray.some.call($this,function(parent){return $.contains(parent,node)})})}else{if(this.length==1){result=$(zepto.qsa(this[0],selector))}else{result=this.map(function(){return zepto.qsa(this,selector)})}}}return result},closest:function(selector,context){var node=this[0],collection=false;if(typeof selector=="object"){collection=$(selector)}while(node&&!(collection?collection.indexOf(node)>=0:zepto.matches(node,selector))){node=node!==context&&!isDocument(node)&&node.parentNode}return $(node)},parents:function(selector){var ancestors=[],nodes=this;while(nodes.length>0){nodes=$.map(nodes,function(node){if((node=node.parentNode)&&!isDocument(node)&&ancestors.indexOf(node)<0){ancestors.push(node);return node}})}return filtered(ancestors,selector)},parent:function(selector){return filtered(uniq(this.pluck("parentNode")),selector)},children:function(selector){return filtered(this.map(function(){return children(this)}),selector)},contents:function(){return this.map(function(){return slice.call(this.childNodes)})},siblings:function(selector){return filtered(this.map(function(i,el){return filter.call(children(el.parentNode),function(child){return child!==el})}),selector)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(property){return $.map(this,function(el){return el[property]})},show:function(){return this.each(function(){this.style.display=="none"&&(this.style.display="");if(getComputedStyle(this,"").getPropertyValue("display")=="none"){this.style.display=defaultDisplay(this.nodeName)}})},replaceWith:function(newContent){return this.before(newContent).remove()},wrap:function(structure){var func=isFunction(structure);if(this[0]&&!func){var dom=$(structure).get(0),clone=dom.parentNode||this.length>1}return this.each(function(index){$(this).wrapAll(func?structure.call(this,index):clone?dom.cloneNode(true):dom)})},wrapAll:function(structure){if(this[0]){$(this[0]).before(structure=$(structure));var children;while((children=structure.children()).length){structure=children.first()}$(structure).append(this)}return this},wrapInner:function(structure){var func=isFunction(structure);return this.each(function(index){var self=$(this),contents=self.contents(),dom=func?structure.call(this,index):structure;contents.length?contents.wrapAll(dom):self.append(dom)})},unwrap:function(){this.parent().each(function(){$(this).replaceWith($(this).children())});return this},clone:function(){return this.map(function(){return this.cloneNode(true)})},hide:function(){return this.css("display","none")},toggle:function(setting){return this.each(function(){var el=$(this);(setting===undefined?el.css("display")=="none":setting)?el.show():el.hide()})},prev:function(selector){return $(this.pluck("previousElementSibling")).filter(selector||"*")},next:function(selector){return $(this.pluck("nextElementSibling")).filter(selector||"*")},html:function(html){return 0 in arguments?this.each(function(idx){var originHtml=this.innerHTML;$(this).empty().append(funcArg(this,html,idx,originHtml))}):(0 in this?this[0].innerHTML:null)},text:function(text){return 0 in arguments?this.each(function(idx){var newText=funcArg(this,text,idx,this.textContent);this.textContent=newText==null?"":""+newText}):(0 in this?this[0].textContent:null)},attr:function(name,value){var result;return(typeof name=="string"&&!(1 in arguments))?(!this.length||this[0].nodeType!==1?undefined:(!(result=this[0].getAttribute(name))&&name in this[0])?this[0][name]:result):this.each(function(idx){if(this.nodeType!==1){return}if(isObject(name)){for(key in name){setAttribute(this,key,name[key])}}else{setAttribute(this,name,funcArg(this,value,idx,this.getAttribute(name)))}})},removeAttr:function(name){return this.each(function(){this.nodeType===1&&name.split(" ").forEach(function(attribute){setAttribute(this,attribute)},this)})},prop:function(name,value){name=propMap[name]||name;return(1 in arguments)?this.each(function(idx){this[name]=funcArg(this,value,idx,this[name])}):(this[0]&&this[0][name])},data:function(name,value){var attrName="data-"+name.replace(capitalRE,"-$1").toLowerCase();var data=(1 in arguments)?this.attr(attrName,value):this.attr(attrName);return data!==null?deserializeValue(data):undefined},val:function(value){return 0 in arguments?this.each(function(idx){this.value=funcArg(this,value,idx,this.value)}):(this[0]&&(this[0].multiple?$(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value))},offset:function(coordinates){if(coordinates){return this.each(function(index){var $this=$(this),coords=funcArg(this,coordinates,index,$this.offset()),parentOffset=$this.offsetParent().offset(),props={top:coords.top-parentOffset.top,left:coords.left-parentOffset.left};if($this.css("position")=="static"){props["position"]="relative"}$this.css(props)})}if(!this.length){return null}var obj=this[0].getBoundingClientRect();return{left:obj.left+window.pageXOffset,top:obj.top+window.pageYOffset,width:Math.round(obj.width),height:Math.round(obj.height)}},css:function(property,value){if(arguments.length<2){var computedStyle,element=this[0];if(!element){return}computedStyle=getComputedStyle(element,"");if(typeof property=="string"){return element.style[camelize(property)]||computedStyle.getPropertyValue(property)}else{if(isArray(property)){var props={};$.each(property,function(_,prop){props[prop]=(element.style[camelize(prop)]||computedStyle.getPropertyValue(prop))});return props}}}var css="";if(type(property)=="string"){if(!value&&value!==0){this.each(function(){this.style.removeProperty(dasherize(property))})}else{css=dasherize(property)+":"+maybeAddPx(property,value)}}else{for(key in property){if(!property[key]&&property[key]!==0){this.each(function(){this.style.removeProperty(dasherize(key))})}else{css+=dasherize(key)+":"+maybeAddPx(key,property[key])+";"}}}return this.each(function(){this.style.cssText+=";"+css})},index:function(element){return element?this.indexOf($(element)[0]):this.parent().children().indexOf(this[0])},hasClass:function(name){if(!name){return false}return emptyArray.some.call(this,function(el){return this.test(className(el))},classRE(name))},addClass:function(name){if(!name){return this}return this.each(function(idx){if(!("className" in this)){return}classList=[];var cls=className(this),newName=funcArg(this,name,idx,cls);newName.split(/\s+/g).forEach(function(klass){if(!$(this).hasClass(klass)){classList.push(klass)}},this);classList.length&&className(this,cls+(cls?" ":"")+classList.join(" "))})},removeClass:function(name){return this.each(function(idx){if(!("className" in this)){return}if(name===undefined){return className(this,"")}classList=className(this);funcArg(this,name,idx,classList).split(/\s+/g).forEach(function(klass){classList=classList.replace(classRE(klass)," ")});className(this,classList.trim())})},toggleClass:function(name,when){if(!name){return this}return this.each(function(idx){var $this=$(this),names=funcArg(this,name,idx,className(this));names.split(/\s+/g).forEach(function(klass){(when===undefined?!$this.hasClass(klass):when)?$this.addClass(klass):$this.removeClass(klass)})})},scrollTop:function(value){if(!this.length){return}var hasScrollTop="scrollTop" in this[0];if(value===undefined){return hasScrollTop?this[0].scrollTop:this[0].pageYOffset}return this.each(hasScrollTop?function(){this.scrollTop=value}:function(){this.scrollTo(this.scrollX,value)})},scrollLeft:function(value){if(!this.length){return}var hasScrollLeft="scrollLeft" in this[0];if(value===undefined){return hasScrollLeft?this[0].scrollLeft:this[0].pageXOffset}return this.each(hasScrollLeft?function(){this.scrollLeft=value}:function(){this.scrollTo(value,this.scrollY)})},position:function(){if(!this.length){return}var elem=this[0],offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=rootNodeRE.test(offsetParent[0].nodeName)?{top:0,left:0}:offsetParent.offset();offset.top-=parseFloat($(elem).css("margin-top"))||0;offset.left-=parseFloat($(elem).css("margin-left"))||0;parentOffset.top+=parseFloat($(offsetParent[0]).css("border-top-width"))||0;parentOffset.left+=parseFloat($(offsetParent[0]).css("border-left-width"))||0;return{top:offset.top-parentOffset.top,left:offset.left-parentOffset.left}},offsetParent:function(){return this.map(function(){var parent=this.offsetParent||document.body;while(parent&&!rootNodeRE.test(parent.nodeName)&&$(parent).css("position")=="static"){parent=parent.offsetParent}return parent})}};$.fn.detach=$.fn.remove;["width","height"].forEach(function(dimension){var dimensionProperty=dimension.replace(/./,function(m){return m[0].toUpperCase()});$.fn[dimension]=function(value){var offset,el=this[0];if(value===undefined){return isWindow(el)?el["inner"+dimensionProperty]:isDocument(el)?el.documentElement["scroll"+dimensionProperty]:(offset=this.offset())&&offset[dimension]}else{return this.each(function(idx){el=$(this);el.css(dimension,funcArg(this,value,idx,el[dimension]()))})}}});function traverseNode(node,fun){fun(node);for(var i=0,len=node.childNodes.length;i1;if(nodes.length<1){return this}return this.each(function(_,target){parent=inside?target:target.parentNode;target=operatorIndex==0?target.nextSibling:operatorIndex==1?target.firstChild:operatorIndex==2?target:null;var parentInDocument=$.contains(document.documentElement,parent);nodes.forEach(function(node){if(copyByClone){node=node.cloneNode(true)}else{if(!parent){return $(node).remove()}}parent.insertBefore(node,target);if(parentInDocument){traverseNode(node,function(el){if(el.nodeName!=null&&el.nodeName.toUpperCase()==="SCRIPT"&&(!el.type||el.type==="text/javascript")&&!el.src){window["eval"].call(window,el.innerHTML)}})}})})};$.fn[inside?operator+"To":"insert"+(operatorIndex?"Before":"After")]=function(html){$(html)[operator](this);return this}});zepto.Z.prototype=$.fn;zepto.uniq=uniq;zepto.deserializeValue=deserializeValue;$.zepto=zepto;return $})();window.Zepto=Zepto;window.$===undefined&&(window.$=Zepto);(function($){var _zid=1,undefined,slice=Array.prototype.slice,isFunction=$.isFunction,isString=function(obj){return typeof obj=="string"},handlers={},specialEvents={},focusinSupported="onfocusin" in window,focus={focus:"focusin",blur:"focusout"},hover={mouseenter:"mouseover",mouseleave:"mouseout"};specialEvents.click=specialEvents.mousedown=specialEvents.mouseup=specialEvents.mousemove="MouseEvents";function zid(element){return element._zid||(element._zid=_zid++)}function findHandlers(element,event,fn,selector){event=parse(event);if(event.ns){var matcher=matcherFor(event.ns)}return(handlers[zid(element)]||[]).filter(function(handler){return handler&&(!event.e||handler.e==event.e)&&(!event.ns||matcher.test(handler.ns))&&(!fn||zid(handler.fn)===zid(fn))&&(!selector||handler.sel==selector)})}function parse(event){var parts=(""+event).split(".");return{e:parts[0],ns:parts.slice(1).sort().join(" ")}}function matcherFor(ns){return new RegExp("(?:^| )"+ns.replace(" "," .* ?")+"(?: |$)")}function eventCapture(handler,captureSetting){return handler.del&&(!focusinSupported&&(handler.e in focus))||!!captureSetting}function realEvent(type){return hover[type]||(focusinSupported&&focus[type])||type}function add(element,events,fn,data,selector,delegator,capture){var id=zid(element),set=(handlers[id]||(handlers[id]=[]));events.split(/\s/).forEach(function(event){if(event=="ready"){return $(document).ready(fn)}var handler=parse(event);handler.fn=fn;handler.sel=selector;if(handler.e in hover){fn=function(e){var related=e.relatedTarget;if(!related||(related!==this&&!$.contains(this,related))){return handler.fn.apply(this,arguments)}}}handler.del=delegator;var callback=delegator||fn;handler.proxy=function(e){e=compatible(e);if(e.isImmediatePropagationStopped()){return}e.data=data;var result=callback.apply(element,e._args==undefined?[e]:[e].concat(e._args));if(result===false){e.preventDefault(),e.stopPropagation()}return result};handler.i=set.length;set.push(handler);if("addEventListener" in element){element.addEventListener(realEvent(handler.e),handler.proxy,eventCapture(handler,capture))}})}function remove(element,events,fn,selector,capture){var id=zid(element);(events||"").split(/\s/).forEach(function(event){findHandlers(element,event,fn,selector).forEach(function(handler){delete handlers[id][handler.i];if("removeEventListener" in element){element.removeEventListener(realEvent(handler.e),handler.proxy,eventCapture(handler,capture))}})})}$.event={add:add,remove:remove};$.proxy=function(fn,context){var args=(2 in arguments)&&slice.call(arguments,2);if(isFunction(fn)){var proxyFn=function(){return fn.apply(context,args?args.concat(slice.call(arguments)):arguments)};proxyFn._zid=zid(fn);return proxyFn}else{if(isString(context)){if(args){args.unshift(fn[context],fn);return $.proxy.apply(null,args)}else{return $.proxy(fn[context],fn)}}else{throw new TypeError("expected function")}}};$.fn.bind=function(event,data,callback){return this.on(event,data,callback)};$.fn.unbind=function(event,callback){return this.off(event,callback)};$.fn.one=function(event,selector,data,callback){return this.on(event,selector,data,callback,1)};var returnTrue=function(){return true},returnFalse=function(){return false},ignoreProperties=/^([A-Z]|returnValue$|layer[XY]$)/,eventMethods={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};function compatible(event,source){if(source||!event.isDefaultPrevented){source||(source=event);$.each(eventMethods,function(name,predicate){var sourceMethod=source[name];event[name]=function(){this[predicate]=returnTrue;return sourceMethod&&sourceMethod.apply(source,arguments)};event[predicate]=returnFalse});if(source.defaultPrevented!==undefined?source.defaultPrevented:"returnValue" in source?source.returnValue===false:source.getPreventDefault&&source.getPreventDefault()){event.isDefaultPrevented=returnTrue}}return event}function createProxy(event){var key,proxy={originalEvent:event};for(key in event){if(!ignoreProperties.test(key)&&event[key]!==undefined){proxy[key]=event[key]}}return compatible(proxy,event)}$.fn.delegate=function(selector,event,callback){return this.on(event,selector,callback)};$.fn.undelegate=function(selector,event,callback){return this.off(event,selector,callback)};$.fn.live=function(event,callback){$(document.body).delegate(this.selector,event,callback);return this};$.fn.die=function(event,callback){$(document.body).undelegate(this.selector,event,callback);return this};$.fn.on=function(event,selector,data,callback,one){var autoRemove,delegator,$this=this;if(event&&!isString(event)){$.each(event,function(type,fn){$this.on(type,selector,data,fn,one)});return $this}if(!isString(selector)&&!isFunction(callback)&&callback!==false){callback=data,data=selector,selector=undefined}if(isFunction(data)||data===false){callback=data,data=undefined}if(callback===false){callback=returnFalse}return $this.each(function(_,element){if(one){autoRemove=function(e){remove(element,e.type,callback);return callback.apply(this,arguments)}}if(selector){delegator=function(e){var evt,match=$(e.target).closest(selector,element).get(0);if(match&&match!==element){evt=$.extend(createProxy(e),{currentTarget:match,liveFired:element});return(autoRemove||callback).apply(match,[evt].concat(slice.call(arguments,1)))}}}add(element,event,callback,data,selector,delegator||autoRemove)})};$.fn.off=function(event,selector,callback){var $this=this;if(event&&!isString(event)){$.each(event,function(type,fn){$this.off(type,selector,fn)});return $this}if(!isString(selector)&&!isFunction(callback)&&callback!==false){callback=selector,selector=undefined}if(callback===false){callback=returnFalse}return $this.each(function(){remove(this,event,callback,selector)})};$.fn.trigger=function(event,args){event=(isString(event)||$.isPlainObject(event))?$.Event(event):compatible(event);event._args=args;return this.each(function(){if(event.type in focus&&typeof this[event.type]=="function"){this[event.type]()}else{if("dispatchEvent" in this){this.dispatchEvent(event)}else{$(this).triggerHandler(event,args)}}})};$.fn.triggerHandler=function(event,args){var e,result;this.each(function(i,element){e=createProxy(isString(event)?$.Event(event):event);e._args=args;e.target=element;$.each(findHandlers(element,event.type||event),function(i,handler){result=handler.proxy(e);if(e.isImmediatePropagationStopped()){return false}})});return result};("focusin focusout focus blur load resize scroll unload click dblclick "+"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "+"change select keydown keypress keyup error").split(" ").forEach(function(event){$.fn[event]=function(callback){return(0 in arguments)?this.bind(event,callback):this.trigger(event)}});$.Event=function(type,props){if(!isString(type)){props=type,type=props.type}var event=document.createEvent(specialEvents[type]||"Events"),bubbles=true;if(props){for(var name in props){(name=="bubbles")?(bubbles=!!props[name]):(event[name]=props[name])}}event.initEvent(type,bubbles,true);return compatible(event)}})(Zepto);(function($){var jsonpID=0,document=window.document,key,name,rscript=/)<[^<]*)*<\/script>/gi,scriptTypeRE=/^(?:text|application)\/javascript/i,xmlTypeRE=/^(?:text|application)\/xml/i,jsonType="application/json",htmlType="text/html",blankRE=/^\s*$/,originAnchor=document.createElement("a");originAnchor.href=window.location.href;function triggerAndReturn(context,eventName,data){var event=$.Event(eventName);$(context).trigger(event,data);return !event.isDefaultPrevented()}function triggerGlobal(settings,context,eventName,data){if(settings.global){return triggerAndReturn(context||document,eventName,data)}}$.active=0;function ajaxStart(settings){if(settings.global&&$.active++===0){triggerGlobal(settings,null,"ajaxStart")}}function ajaxStop(settings){if(settings.global&&!(--$.active)){triggerGlobal(settings,null,"ajaxStop")}}function ajaxBeforeSend(xhr,settings){var context=settings.context;if(settings.beforeSend.call(context,xhr,settings)===false||triggerGlobal(settings,context,"ajaxBeforeSend",[xhr,settings])===false){return false}triggerGlobal(settings,context,"ajaxSend",[xhr,settings])}function ajaxSuccess(data,xhr,settings,deferred){var context=settings.context,status="success";settings.success.call(context,data,status,xhr);if(deferred){deferred.resolveWith(context,[data,status,xhr])}triggerGlobal(settings,context,"ajaxSuccess",[xhr,settings,data]);ajaxComplete(status,xhr,settings)}function ajaxError(error,type,xhr,settings,deferred){var context=settings.context;settings.error.call(context,xhr,type,error);if(deferred){deferred.rejectWith(context,[xhr,type,error])}triggerGlobal(settings,context,"ajaxError",[xhr,settings,error||type]);ajaxComplete(type,xhr,settings)}function ajaxComplete(status,xhr,settings){var context=settings.context;settings.complete.call(context,xhr,status);triggerGlobal(settings,context,"ajaxComplete",[xhr,settings]);ajaxStop(settings)}function empty(){}$.ajaxJSONP=function(options,deferred){if(!("type" in options)){return $.ajax(options)}var _callbackName=options.jsonpCallback,callbackName=($.isFunction(_callbackName)?_callbackName():_callbackName)||("jsonp"+(++jsonpID)),script=document.createElement("script"),originalCallback=window[callbackName],responseData,abort=function(errorType){$(script).triggerHandler("error",errorType||"abort")},xhr={abort:abort},abortTimeout;if(deferred){deferred.promise(xhr)}$(script).on("load error",function(e,errorType){clearTimeout(abortTimeout);$(script).off().remove();if(e.type=="error"||!responseData){ajaxError(null,errorType||"error",xhr,options,deferred)}else{ajaxSuccess(responseData[0],xhr,options,deferred)}window[callbackName]=originalCallback;if(responseData&&$.isFunction(originalCallback)){originalCallback(responseData[0])}originalCallback=responseData=undefined});if(ajaxBeforeSend(xhr,options)===false){abort("abort");return xhr}window[callbackName]=function(){responseData=arguments};script.src=options.url.replace(/\?(.+)=\?/,"?$1="+callbackName);document.head.appendChild(script);if(options.timeout>0){abortTimeout=setTimeout(function(){abort("timeout")},options.timeout)}return xhr};$.ajaxSettings={type:"GET",beforeSend:empty,success:empty,error:empty,complete:empty,context:null,global:true,xhr:function(){return new window.XMLHttpRequest()},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:jsonType,xml:"application/xml, text/xml",html:htmlType,text:"text/plain"},crossDomain:false,timeout:0,processData:true,cache:true};function mimeToDataType(mime){if(mime){mime=mime.split(";",2)[0]}return mime&&(mime==htmlType?"html":mime==jsonType?"json":scriptTypeRE.test(mime)?"script":xmlTypeRE.test(mime)&&"xml")||"text"}function appendQuery(url,query){if(query==""){return url}return(url+"&"+query).replace(/[&?]{1,2}/,"?")}function serializeData(options){if(options.processData&&options.data&&$.type(options.data)!="string"){options.data=$.param(options.data,options.traditional)}if(options.data&&(!options.type||options.type.toUpperCase()=="GET")){options.url=appendQuery(options.url,options.data),options.data=undefined}}$.ajax=function(options){var settings=$.extend({},options||{}),deferred=$.Deferred&&$.Deferred(),urlAnchor;for(key in $.ajaxSettings){if(settings[key]===undefined){settings[key]=$.ajaxSettings[key]}}ajaxStart(settings);if(!settings.crossDomain){urlAnchor=document.createElement("a");urlAnchor.href=settings.url;urlAnchor.href=urlAnchor.href;settings.crossDomain=(originAnchor.protocol+"//"+originAnchor.host)!==(urlAnchor.protocol+"//"+urlAnchor.host)}if(!settings.url){settings.url=window.location.toString()}serializeData(settings);var dataType=settings.dataType,hasPlaceholder=/\?.+=\?/.test(settings.url);if(hasPlaceholder){dataType="jsonp"}if(settings.cache===false||((!options||options.cache!==true)&&("script"==dataType||"jsonp"==dataType))){settings.url=appendQuery(settings.url,"_="+Date.now())}if("jsonp"==dataType){if(!hasPlaceholder){settings.url=appendQuery(settings.url,settings.jsonp?(settings.jsonp+"=?"):settings.jsonp===false?"":"callback=?")}return $.ajaxJSONP(settings,deferred)}var mime=settings.accepts[dataType],headers={},setHeader=function(name,value){headers[name.toLowerCase()]=[name,value]},protocol=/^([\w-]+:)\/\//.test(settings.url)?RegExp.$1:window.location.protocol,xhr=settings.xhr(),nativeSetHeader=xhr.setRequestHeader,abortTimeout;if(deferred){deferred.promise(xhr)}if(!settings.crossDomain){setHeader("X-Requested-With","XMLHttpRequest")}setHeader("Accept",mime||"*/*");if(mime=settings.mimeType||mime){if(mime.indexOf(",")>-1){mime=mime.split(",",2)[0]}xhr.overrideMimeType&&xhr.overrideMimeType(mime)}if(settings.contentType||(settings.contentType!==false&&settings.data&&settings.type.toUpperCase()!="GET")){setHeader("Content-Type",settings.contentType||"application/x-www-form-urlencoded")}if(settings.headers){for(name in settings.headers){setHeader(name,settings.headers[name])}}xhr.setRequestHeader=setHeader;xhr.onreadystatechange=function(){if(xhr.readyState==4){xhr.onreadystatechange=empty;clearTimeout(abortTimeout);var result,error=false;if((xhr.status>=200&&xhr.status<300)||xhr.status==304||(xhr.status==0&&protocol=="file:")){dataType=dataType||mimeToDataType(settings.mimeType||xhr.getResponseHeader("content-type"));result=xhr.responseText;try{if(dataType=="script"){(1,eval)(result)}else{if(dataType=="xml"){result=xhr.responseXML}else{if(dataType=="json"){result=blankRE.test(result)?null:$.parseJSON(result)}}}}catch(e){error=e}if(error){ajaxError(error,"parsererror",xhr,settings,deferred)}else{ajaxSuccess(result,xhr,settings,deferred)}}else{ajaxError(xhr.statusText||null,xhr.status?"error":"abort",xhr,settings,deferred)}}};if(ajaxBeforeSend(xhr,settings)===false){xhr.abort();ajaxError(null,"abort",xhr,settings,deferred);return xhr}if(settings.xhrFields){for(name in settings.xhrFields){xhr[name]=settings.xhrFields[name]}}var async="async" in settings?settings.async:true;xhr.open(settings.type,settings.url,async,settings.username,settings.password);for(name in headers){nativeSetHeader.apply(xhr,headers[name])}if(settings.timeout>0){abortTimeout=setTimeout(function(){xhr.onreadystatechange=empty;xhr.abort();ajaxError(null,"timeout",xhr,settings,deferred)},settings.timeout)}xhr.send(settings.data?settings.data:null);return xhr};function parseArguments(url,data,success,dataType){if($.isFunction(data)){dataType=success,success=data,data=undefined}if(!$.isFunction(success)){dataType=success,success=undefined}return{url:url,data:data,success:success,dataType:dataType}}$.get=function(){return $.ajax(parseArguments.apply(null,arguments))};$.post=function(){var options=parseArguments.apply(null,arguments);options.type="POST";return $.ajax(options)};$.getJSON=function(){var options=parseArguments.apply(null,arguments);options.dataType="json";return $.ajax(options)};$.fn.load=function(url,data,success){if(!this.length){return this}var self=this,parts=url.split(/\s/),selector,options=parseArguments(url,data,success),callback=options.success;if(parts.length>1){options.url=parts[0],selector=parts[1]}options.success=function(response){self.html(selector?$("
").html(response.replace(rscript,"")).find(selector):response);callback&&callback.apply(self,arguments)};$.ajax(options);return this};var escape=encodeURIComponent;function serialize(params,obj,traditional,scope){var type,array=$.isArray(obj),hash=$.isPlainObject(obj);$.each(obj,function(key,value){type=$.type(value);if(scope){key=traditional?scope:scope+"["+(hash||type=="object"||type=="array"?key:"")+"]"}if(!scope&&array){params.add(value.name,value.value)}else{if(type=="array"||(!traditional&&type=="object")){serialize(params,value,traditional,key)}else{params.add(key,value)}}})}$.param=function(obj,traditional){var params=[];params.add=function(key,value){if($.isFunction(value)){value=value()}if(value==null){value=""}this.push(escape(key)+"="+escape(value))};serialize(params,obj,traditional);return params.join("&").replace(/%20/g,"+")}})(Zepto);(function($){$.fn.serializeArray=function(){var name,type,result=[],add=function(value){if(value.forEach){return value.forEach(add)}result.push({name:name,value:value})};if(this[0]){$.each(this[0].elements,function(_,field){type=field.type,name=field.name;if(name&&field.nodeName.toLowerCase()!="fieldset"&&!field.disabled&&type!="submit"&&type!="reset"&&type!="button"&&type!="file"&&((type!="radio"&&type!="checkbox")||field.checked)){add($(field).val())}})}return result};$.fn.serialize=function(){var result=[];this.serializeArray().forEach(function(elm){result.push(encodeURIComponent(elm.name)+"="+encodeURIComponent(elm.value))});return result.join("&")};$.fn.submit=function(callback){if(0 in arguments){this.bind("submit",callback)}else{if(this.length){var event=$.Event("submit");this.eq(0).trigger(event);if(!event.isDefaultPrevented()){this.get(0).submit()}}}return this}})(Zepto);(function($){if(!("__proto__" in {})){$.extend($.zepto,{Z:function(dom,selector){dom=dom||[];$.extend(dom,$.fn);dom.selector=selector||"";dom.__Z=true;return dom},isZ:function(object){return $.type(object)==="array"&&"__Z" in object}})}try{getComputedStyle(undefined)}catch(e){var nativeGetComputedStyle=getComputedStyle;window.getComputedStyle=function(element){try{return nativeGetComputedStyle(element)}catch(e){return null}}}})(Zepto);(function($){function detect(ua,platform){var os=this.os={},browser=this.browser={},webkit=ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/),android=ua.match(/(Android);?[\s\/]+([\d.]+)?/),osx=!!ua.match(/\(Macintosh\; Intel /),ipad=ua.match(/(iPad).*OS\s([\d_]+)/),ipod=ua.match(/(iPod)(.*OS\s([\d_]+))?/),iphone=!ipad&&ua.match(/(iPhone\sOS)\s([\d_]+)/),webos=ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),win=/Win\d{2}|Windows/.test(platform),wp=ua.match(/Windows Phone ([\d.]+)/),touchpad=webos&&ua.match(/TouchPad/),kindle=ua.match(/Kindle\/([\d.]+)/),silk=ua.match(/Silk\/([\d._]+)/),blackberry=ua.match(/(BlackBerry).*Version\/([\d.]+)/),bb10=ua.match(/(BB10).*Version\/([\d.]+)/),rimtabletos=ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),playbook=ua.match(/PlayBook/),chrome=ua.match(/Chrome\/([\d.]+)/)||ua.match(/CriOS\/([\d.]+)/),firefox=ua.match(/Firefox\/([\d.]+)/),firefoxos=ua.match(/\((?:Mobile|Tablet); rv:([\d.]+)\).*Firefox\/[\d.]+/),ie=ua.match(/MSIE\s([\d.]+)/)||ua.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/),webview=!chrome&&ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),safari=webview||ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/);if(browser.webkit=!!webkit){browser.version=webkit[1]}if(android){os.android=true,os.version=android[2]}if(iphone&&!ipod){os.ios=os.iphone=true,os.version=iphone[2].replace(/_/g,".")}if(ipad){os.ios=os.ipad=true,os.version=ipad[2].replace(/_/g,".")}if(ipod){os.ios=os.ipod=true,os.version=ipod[3]?ipod[3].replace(/_/g,"."):null}if(wp){os.wp=true,os.version=wp[1]}if(webos){os.webos=true,os.version=webos[2]}if(touchpad){os.touchpad=true}if(blackberry){os.blackberry=true,os.version=blackberry[2]}if(bb10){os.bb10=true,os.version=bb10[2]}if(rimtabletos){os.rimtabletos=true,os.version=rimtabletos[2]}if(playbook){browser.playbook=true}if(kindle){os.kindle=true,os.version=kindle[1]}if(silk){browser.silk=true,browser.version=silk[1]}if(!silk&&os.android&&ua.match(/Kindle Fire/)){browser.silk=true}if(chrome){browser.chrome=true,browser.version=chrome[1]}if(firefox){browser.firefox=true,browser.version=firefox[1]}if(firefoxos){os.firefoxos=true,os.version=firefoxos[1]}if(ie){browser.ie=true,browser.version=ie[1]}if(safari&&(osx||os.ios||win)){browser.safari=true;if(!os.ios){browser.version=safari[1]}}if(webview){browser.webview=true}os.tablet=!!(ipad||playbook||(android&&!ua.match(/Mobile/))||(firefox&&ua.match(/Tablet/))||(ie&&!ua.match(/Phone/)&&ua.match(/Touch/)));os.phone=!!(!os.tablet&&!os.ipod&&(android||iphone||webos||blackberry||bb10||(chrome&&ua.match(/Android/))||(chrome&&ua.match(/CriOS\/([\d.]+)/))||(firefox&&ua.match(/Mobile/))||(ie&&ua.match(/Touch/))))}detect.call($,navigator.userAgent,navigator.platform);$.__detect=detect})(Zepto);(function($,undefined){var document=window.document,docElem=document.documentElement,origShow=$.fn.show,origHide=$.fn.hide,origToggle=$.fn.toggle;function anim(el,speed,opacity,scale,callback){if(typeof speed=="function"&&!callback){callback=speed,speed=undefined}var props={opacity:opacity};if(scale){props.scale=scale;el.css($.fx.cssPrefix+"transform-origin","0 0")}return el.animate(props,speed,null,callback)}function hide(el,speed,scale,callback){return anim(el,speed,0,scale,function(){origHide.call($(this));callback&&callback.call(this)})}$.fn.show=function(speed,callback){origShow.call(this);if(speed===undefined){speed=0}else{this.css("opacity",0)}return anim(this,speed,1,"1,1",callback)};$.fn.hide=function(speed,callback){if(speed===undefined){return origHide.call(this)}else{return hide(this,speed,"0,0",callback)}};$.fn.toggle=function(speed,callback){if(speed===undefined||typeof speed=="boolean"){return origToggle.call(this,speed)}else{return this.each(function(){var el=$(this);el[el.css("display")=="none"?"show":"hide"](speed,callback)})}};$.fn.fadeTo=function(speed,opacity,callback){return anim(this,speed,opacity,null,callback)};$.fn.fadeIn=function(speed,callback){var target=this.css("opacity");if(target>0){this.css("opacity",0)}else{target=1}return origShow.call(this).fadeTo(speed,target,callback)};$.fn.fadeOut=function(speed,callback){return hide(this,speed,null,callback)};$.fn.fadeToggle=function(speed,callback){return this.each(function(){var el=$(this);el[(el.css("opacity")==0||el.css("display")=="none")?"fadeIn":"fadeOut"](speed,callback)})}})(Zepto);(function($){var data={},dataAttr=$.fn.data,camelize=$.camelCase,exp=$.expando="Zepto"+(+new Date()),emptyArray=[];function getData(node,name){var id=node[exp],store=id&&data[id];if(name===undefined){return store||setData(node)}else{if(store){if(name in store){return store[name]}var camelName=camelize(name);if(camelName in store){return store[camelName]}}return dataAttr.call($(node),name)}}function setData(node,name,value){var id=node[exp]||(node[exp]=++$.uuid),store=data[id]||(data[id]=attributeData(node));if(name!==undefined){store[camelize(name)]=value}return store}function attributeData(node){var store={};$.each(node.attributes||emptyArray,function(i,attr){if(attr.name.indexOf("data-")==0){store[camelize(attr.name.replace("data-",""))]=$.zepto.deserializeValue(attr.value)}});return store}$.fn.data=function(name,value){return value===undefined?$.isPlainObject(name)?this.each(function(i,node){$.each(name,function(key,value){setData(node,key,value)})}):(0 in this?getData(this[0],name):undefined):this.each(function(){setData(this,name,value)})};$.fn.removeData=function(names){if(typeof names=="string"){names=names.split(/\s+/)}return this.each(function(){var id=this[exp],store=id&&data[id];if(store){$.each(names||store,function(key){delete store[names?camelize(this):key]})}})};["remove","empty"].forEach(function(methodName){var origFn=$.fn[methodName];$.fn[methodName]=function(){var elements=this.find("*");if(methodName==="remove"){elements=elements.add(this)}elements.removeData();return origFn.call(this)}})})(Zepto);(function($){$.Callbacks=function(options){options=$.extend({},options);var memory,fired,firing,firingStart,firingLength,firingIndex,list=[],stack=!options.once&&[],fire=function(data){memory=options.memory&&data;fired=true;firingIndex=firingStart||0;firingStart=0;firingLength=list.length;firing=true;for(;list&&firingIndex-1){list.splice(index,1);if(firing){if(index<=firingLength){--firingLength}if(index<=firingIndex){--firingIndex}}}})}return this},has:function(fn){return !!(list&&(fn?$.inArray(fn,list)>-1:list.length))},empty:function(){firingLength=list.length=0;return this},disable:function(){list=stack=memory=undefined;return this},disabled:function(){return !list},lock:function(){stack=undefined;if(!memory){Callbacks.disable()}return this},locked:function(){return !stack},fireWith:function(context,args){if(list&&(!fired||stack)){args=args||[];args=[context,args.slice?args.slice():args];if(firing){stack.push(args)}else{fire(args)}}return this},fire:function(){return Callbacks.fireWith(this,arguments)},fired:function(){return !!fired}};return Callbacks}})(Zepto);(function($){var slice=Array.prototype.slice;function Deferred(func){var tuples=[["resolve","done",$.Callbacks({once:1,memory:1}),"resolved"],["reject","fail",$.Callbacks({once:1,memory:1}),"rejected"],["notify","progress",$.Callbacks({memory:1})]],state="pending",promise={state:function(){return state},always:function(){deferred.done(arguments).fail(arguments);return this},then:function(){var fns=arguments;return Deferred(function(defer){$.each(tuples,function(i,tuple){var fn=$.isFunction(fns[i])&&fns[i];deferred[tuple[1]](function(){var returned=fn&&fn.apply(this,arguments);if(returned&&$.isFunction(returned.promise)){returned.promise().done(defer.resolve).fail(defer.reject).progress(defer.notify)}else{var context=this===promise?defer.promise():this,values=fn?[returned]:arguments;defer[tuple[0]+"With"](context,values)}})});fns=null}).promise()},promise:function(obj){return obj!=null?$.extend(obj,promise):promise}},deferred={};$.each(tuples,function(i,tuple){var list=tuple[2],stateString=tuple[3];promise[tuple[1]]=list.add;if(stateString){list.add(function(){state=stateString},tuples[i^1][2].disable,tuples[2][2].lock)}deferred[tuple[0]]=function(){deferred[tuple[0]+"With"](this===deferred?promise:this,arguments);return this};deferred[tuple[0]+"With"]=list.fireWith});promise.promise(deferred);if(func){func.call(deferred,deferred)}return deferred}$.when=function(sub){var resolveValues=slice.call(arguments),len=resolveValues.length,i=0,remain=len!==1||(sub&&$.isFunction(sub.promise))?len:0,deferred=remain===1?sub:Deferred(),progressValues,progressContexts,resolveContexts,updateFn=function(i,ctx,val){return function(value){ctx[i]=this;val[i]=arguments.length>1?slice.call(arguments):value;if(val===progressValues){deferred.notifyWith(ctx,val)}else{if(!(--remain)){deferred.resolveWith(ctx,val)}}}};if(len>1){progressValues=new Array(len);progressContexts=new Array(len);resolveContexts=new Array(len);for(;i=Math.abs(y1-y2)?(x1-x2>0?"Left":"Right"):(y1-y2>0?"Up":"Down")}function longTap(){longTapTimeout=null;if(touch.last){touch.el.trigger("longTap");touch={}}}function cancelLongTap(){if(longTapTimeout){clearTimeout(longTapTimeout)}longTapTimeout=null}function cancelAll(){if(touchTimeout){clearTimeout(touchTimeout)}if(tapTimeout){clearTimeout(tapTimeout)}if(swipeTimeout){clearTimeout(swipeTimeout)}if(longTapTimeout){clearTimeout(longTapTimeout)}touchTimeout=tapTimeout=swipeTimeout=longTapTimeout=null;touch={}}function isPrimaryTouch(event){return(event.pointerType=="touch"||event.pointerType==event.MSPOINTER_TYPE_TOUCH)&&event.isPrimary}function isPointerEventType(e,type){return(e.type=="pointer"+type||e.type.toLowerCase()=="mspointer"+type)}$(document).ready(function(){var now,delta,deltaX=0,deltaY=0,firstTouch,_isPointerType;if("MSGesture" in window){gesture=new MSGesture();gesture.target=document.body}$(document).bind("MSGestureEnd",function(e){var swipeDirectionFromVelocity=e.velocityX>1?"Right":e.velocityX<-1?"Left":e.velocityY>1?"Down":e.velocityY<-1?"Up":null;if(swipeDirectionFromVelocity){touch.el.trigger("swipe");touch.el.trigger("swipe"+swipeDirectionFromVelocity)}}).on("touchstart MSPointerDown pointerdown",function(e){if((_isPointerType=isPointerEventType(e,"down"))&&!isPrimaryTouch(e)){return}firstTouch=_isPointerType?e:e.touches[0];if(e.touches&&e.touches.length===1&&touch.x2){touch.x2=undefined;touch.y2=undefined}now=Date.now();delta=now-(touch.last||now);touch.el=$("tagName" in firstTouch.target?firstTouch.target:firstTouch.target.parentNode);touchTimeout&&clearTimeout(touchTimeout);touch.x1=firstTouch.pageX;touch.y1=firstTouch.pageY;if(delta>0&&delta<=250){touch.isDoubleTap=true}touch.last=now;longTapTimeout=setTimeout(longTap,longTapDelay);if(gesture&&_isPointerType){gesture.addPointer(e.pointerId)}}).on("touchmove MSPointerMove pointermove",function(e){if((_isPointerType=isPointerEventType(e,"move"))&&!isPrimaryTouch(e)){return}firstTouch=_isPointerType?e:e.touches[0];cancelLongTap();touch.x2=firstTouch.pageX;touch.y2=firstTouch.pageY;deltaX+=Math.abs(touch.x1-touch.x2);deltaY+=Math.abs(touch.y1-touch.y2)}).on("touchend MSPointerUp pointerup",function(e){if((_isPointerType=isPointerEventType(e,"up"))&&!isPrimaryTouch(e)){return}cancelLongTap();if((touch.x2&&Math.abs(touch.x1-touch.x2)>30)||(touch.y2&&Math.abs(touch.y1-touch.y2)>30)){swipeTimeout=setTimeout(function(){touch.el.trigger("swipe");touch.el.trigger("swipe"+(swipeDirection(touch.x1,touch.x2,touch.y1,touch.y2)));touch={}},0)}else{if("last" in touch){if(deltaX<30&&deltaY<30){tapTimeout=setTimeout(function(){var event=$.Event("tap");event.cancelTouch=cancelAll;touch.el.trigger(event);if(touch.isDoubleTap){if(touch.el){touch.el.trigger("doubleTap")}touch={}}else{touchTimeout=setTimeout(function(){touchTimeout=null;if(touch.el){touch.el.trigger("singleTap")}touch={}},250)}},0)}else{touch={}}}}deltaX=deltaY=0}).on("touchcancel MSPointerCancel pointercancel",cancelAll);$(window).on("scroll",cancelAll)});["swipe","swipeLeft","swipeRight","swipeUp","swipeDown","doubleTap","tap","singleTap","longTap"].forEach(function(eventName){$.fn[eventName]=function(callback){return this.on(eventName,callback)}})})(Zepto);(function($,undefined){var prefix="",eventPrefix,vendors={Webkit:"webkit",Moz:"",O:"o"},testEl=document.createElement("div"),supportedTransforms=/^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,transform,transitionProperty,transitionDuration,transitionTiming,transitionDelay,animationName,animationDuration,animationTiming,animationDelay,cssReset={};function dasherize(str){return str.replace(/([a-z])([A-Z])/,"$1-$2").toLowerCase()}function normalizeEvent(name){return eventPrefix?eventPrefix+name:name.toLowerCase()}$.each(vendors,function(vendor,event){if(testEl.style[vendor+"TransitionProperty"]!==undefined){prefix="-"+vendor.toLowerCase()+"-";eventPrefix=event;return false}});transform=prefix+"transform";cssReset[transitionProperty=prefix+"transition-property"]=cssReset[transitionDuration=prefix+"transition-duration"]=cssReset[transitionDelay=prefix+"transition-delay"]=cssReset[transitionTiming=prefix+"transition-timing-function"]=cssReset[animationName=prefix+"animation-name"]=cssReset[animationDuration=prefix+"animation-duration"]=cssReset[animationDelay=prefix+"animation-delay"]=cssReset[animationTiming=prefix+"animation-timing-function"]="";$.fx={off:(eventPrefix===undefined&&testEl.style.transitionProperty===undefined),speeds:{_default:400,fast:200,slow:600},cssPrefix:prefix,transitionEnd:normalizeEvent("TransitionEnd"),animationEnd:normalizeEvent("AnimationEnd")};$.fn.animate=function(properties,duration,ease,callback,delay){if($.isFunction(duration)){callback=duration,ease=undefined,duration=undefined}if($.isFunction(ease)){callback=ease,ease=undefined}if($.isPlainObject(duration)){ease=duration.easing,callback=duration.complete,delay=duration.delay,duration=duration.duration}if(duration){duration=(typeof duration=="number"?duration:($.fx.speeds[duration]||$.fx.speeds._default))/1000}if(delay){delay=parseFloat(delay)/1000}return this.anim(properties,duration,ease,callback,delay)};$.fn.anim=function(properties,duration,ease,callback,delay){var key,cssValues={},cssProperties,transforms="",that=this,wrappedCallback,endEvent=$.fx.transitionEnd,fired=false;if(duration===undefined){duration=$.fx.speeds._default/1000}if(delay===undefined){delay=0}if($.fx.off){duration=0}if(typeof properties=="string"){cssValues[animationName]=properties;cssValues[animationDuration]=duration+"s";cssValues[animationDelay]=delay+"s";cssValues[animationTiming]=(ease||"linear");endEvent=$.fx.animationEnd}else{cssProperties=[];for(key in properties){if(supportedTransforms.test(key)){transforms+=key+"("+properties[key]+") "}else{cssValues[key]=properties[key],cssProperties.push(dasherize(key))}}if(transforms){cssValues[transform]=transforms,cssProperties.push(transform)}if(duration>0&&typeof properties==="object"){cssValues[transitionProperty]=cssProperties.join(", ");cssValues[transitionDuration]=duration+"s";cssValues[transitionDelay]=delay+"s";cssValues[transitionTiming]=(ease||"linear")}}wrappedCallback=function(event){if(typeof event!=="undefined"){if(event.target!==event.currentTarget){return}$(event.target).unbind(endEvent,wrappedCallback)}else{$(this).unbind(endEvent,wrappedCallback)}fired=true;$(this).css(cssReset);callback&&callback.call(this)};if(duration>0){this.bind(endEvent,wrappedCallback);setTimeout(function(){if(fired){return}wrappedCallback.call(that)},((duration+delay)*1000)+25)}this.size()&&this.get(0).clientLeft;this.css(cssValues);if(duration<=0){setTimeout(function(){that.each(function(){wrappedCallback.call(this)})},0)}return this};testEl=null})(Zepto);(function(a){a.extend(a.fn,{cookie:function(b,c,d){var e,f,g,h;if(arguments.length>1&&String(c)!=="[object Object]"){d=a.extend({},d);if(c===null||c===undefined){d.expires=-1}return typeof d.expires=="number"&&(e=d.expires*24*60*60*1000,f=d.expires=new Date,f.setTime(f.getTime()+e)),c=String(c),document.cookie=[encodeURIComponent(b),"=",d.raw?c:encodeURIComponent(c),d.expires?"; expires="+d.expires.toUTCString():"",d.path?"; path="+d.path:"",d.domain?"; domain="+d.domain:"",d.secure?"; secure":""].join("")}return d=c||{},h=d.raw?function(a){return a}:decodeURIComponent,(g=(new RegExp("(?:^|; )"+encodeURIComponent(b)+"=([^;]*)")).exec(document.cookie))?h(g[1]):null}})})(Zepto); -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "engines": { 4 | "node": ">=0.10.0" 5 | }, 6 | "devDependencies": { 7 | "browser-sync": "^1.5.4", 8 | "del": "^1.1.1", 9 | "gulp": "^3.6.0", 10 | "gulp-concat": "*", 11 | "gulp-imagemin": "^1.0.1", 12 | "gulp-load-plugins": "^0.7.0", 13 | "gulp-plumber": "^1.0.1", 14 | "gulp-uglify": "*", 15 | "gulp-util": "^3.0.1", 16 | "imagemin-pngquant": "^4.2.0", 17 | "imagemin-webp": "^3.1.0", 18 | "merge-stream": "^1.0.0", 19 | "vinyl-buffer": "^1.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/scripts/README.md: -------------------------------------------------------------------------------- 1 | # scripts 2 | -------------------------------------------------------------------------------- /example/scripts/index.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | /* --- webp start--- */ 4 | /** 5 | * webp插件 6 | * 调用方式1: 7 | * $.webp(); 8 | * 处理所有的有 lsrc 属性,且lsrc属性的目录中包含 images 目录的标签。 9 | * 如果是img标签,则赋值src属性,其他类型的标签修改background-image属性。 10 | * 11 | * 调用方式2: 12 | * $('.p3').webp({ 13 | * origSrc: "lsrc", // 用于存放图片原文件地址(png,jpg,jpeg,gif)的标签属性 14 | * origDir: "images",// 图片原文件根目录,会替换为webp的根目录 15 | * webpDir: "webps"// 图片原webp文件目录 16 | * }); 17 | * 查找处理 .page.p3 这个dom节点下所有有 lsrc 属性,且lsrc属性的目录中包含 images 目录的标签。 18 | * 处理过程同上。 19 | * 20 | * 注意:由于采用lsrc的形式,所以img标签不要设定src属性,防止重复加载。 21 | * 对于设置了背景图片的标签,请将css中的background-image单独拎出来注释掉。 22 | */ 23 | 24 | 25 | $.webp(); 26 | 27 | 28 | /* --- webp end--- */ 29 | 30 | 31 | })(); 32 | -------------------------------------------------------------------------------- /example/src/css/README.md: -------------------------------------------------------------------------------- 1 | # css files 2 | -------------------------------------------------------------------------------- /example/src/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #333; 3 | width: 100%; 4 | height: 100%; 5 | } -------------------------------------------------------------------------------- /example/src/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /example/src/images/p1-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/src/images/p1-bg.jpg -------------------------------------------------------------------------------- /example/src/images/p2-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/src/images/p2-bg.jpg -------------------------------------------------------------------------------- /example/src/images/p3-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/src/images/p3-bg.jpg -------------------------------------------------------------------------------- /example/src/images/p4-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/src/images/p4-bg.jpg -------------------------------------------------------------------------------- /example/src/images/p5-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/src/images/p5-bg.jpg -------------------------------------------------------------------------------- /example/src/images/p6-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/src/images/p6-bg.jpg -------------------------------------------------------------------------------- /example/src/images/p7-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hbxeagle/webpjs/0e484918fac211f9e623dfe2943e60de5e78b850/example/src/images/p7-bg.jpg -------------------------------------------------------------------------------- /example/src/js/index.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | /* --- webp start--- */ 4 | /** 5 | * webp插件 6 | * 调用方式1: 7 | * $.webp(); 8 | * 处理所有的有 lsrc 属性,且lsrc属性的目录中包含 images 目录的标签。 9 | * 如果是img标签,则赋值src属性,其他类型的标签修改background-image属性。 10 | * 11 | * 调用方式2: 12 | * $('.p3').webp({ 13 | * origSrc: "lsrc", // 用于存放图片原文件地址(png,jpg,jpeg,gif)的标签属性 14 | * origDir: "images",// 图片原文件根目录,会替换为webp的根目录,支持自定义配置,默认为空,即不需要替换目录,只替换后缀 15 | * webpDir: "images"// 图片原webp文件目录,支持自定义配置,默认为空,即不需要替换目录,只替换后缀 16 | * }); 17 | * 查找处理 .page.p3 这个dom节点下所有有 lsrc 属性,且lsrc属性的目录中包含 images 目录的标签。 18 | * 处理过程同上。 19 | * 20 | * 注意:由于采用lsrc的形式,所以img标签不要设定src属性,防止重复加载。 21 | * 对于设置了背景图片的标签,请将css中的background-image单独拎出来注释掉。 22 | */ 23 | 24 | 25 | $.webp(); 26 | 27 | 28 | /* --- webp end--- */ 29 | 30 | 31 | })(); 32 | -------------------------------------------------------------------------------- /example/styles/README.md: -------------------------------------------------------------------------------- 1 | # styles 2 | -------------------------------------------------------------------------------- /example/styles/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #333; 3 | width: 100%; 4 | height: 100%; 5 | } -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gulp = require('gulp'); 4 | 5 | // Load plugins 6 | var $ = require('gulp-load-plugins')(); 7 | 8 | 9 | /* es6 */ 10 | gulp.task('es6', function() { 11 | 12 | return gulp.src('src/*.js') 13 | .pipe($.plumber()) 14 | .pipe($.babel({ 15 | presets: ['es2015'] 16 | })) 17 | .pipe(gulp.dest('dist')) 18 | .pipe($.uglify()) 19 | .pipe($.rename({ 20 | extname: '.min.js' 21 | })) 22 | .pipe(gulp.dest('dist')); 23 | 24 | }); 25 | 26 | 27 | gulp.task('watch', ['es6'], function() { 28 | 29 | gulp.watch(['src/*.js'], ['es6']); 30 | 31 | }); 32 | 33 | 34 | gulp.task('default', function() { 35 | gulp.start('watch'); 36 | }); 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "engines": { 4 | "node": ">=0.10.0" 5 | }, 6 | "devDependencies": { 7 | "babel-preset-es2015": "*", 8 | "gulp": "^3.6.0", 9 | "gulp-babel": "*", 10 | "gulp-load-plugins": "^1.1.0", 11 | "gulp-plumber": "^1.0.1", 12 | "gulp-rename": "^1.2.2", 13 | "gulp-uglify": "*", 14 | "gulp-util": "^3.0.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/webp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * webp插件 3 | * 调用方式1: 4 | * $.webp(); 5 | * 处理所有的有 lsrc 属性,且lsrc属性的目录中包含 images 目录的标签。 6 | * 如果是img标签,则赋值src属性,其他类型的标签修改background-image属性。 7 | * 8 | * 调用方式2: 9 | * $('.p3').webp({ 10 | * origSrc: "lsrc", // 用于存放图片原文件地址(png,jpg,jpeg,gif)的标签属性 11 | * origDir: "images",// 图片原文件根目录,会替换为webp的根目录 12 | * webpDir: "webps"// 图片原webp文件目录 13 | * 14 | }); * 查找处理.page.p3 这个dom节点下所有有 lsrc 属性, 且lsrc属性的目录中包含 images 目录的标签。 15 | 16 | * 处理过程同上。 17 | * 18 | * 注意:由于采用lsrc的形式,所以img标签不要设定src属性,防止重复加载。 19 | * 对于设置了背景图片的标签,请将css中的background-image单独拎出来注释掉。 20 | */ 21 | 22 | (function(window, $) { 23 | 24 | let __supportwebp = false; 25 | 26 | let __checked = false; 27 | 28 | let supportWebp = function(callback) { 29 | 30 | if (__checked) { 31 | callback(); 32 | return; 33 | } 34 | 35 | (function() { 36 | let webp = new Image(); 37 | webp.onload = webp.onerror = function() { 38 | __checked = true; 39 | __supportwebp = webp.height === 2; 40 | webp.onload = webp.onerror = null; 41 | webp = null; 42 | callback(); 43 | }; 44 | //高度为2的一个webp图片 45 | webp.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA'; 46 | })(); 47 | 48 | }; 49 | 50 | $.fn.webp = function(options) { 51 | 52 | let elements = this; 53 | 54 | let settings = { 55 | origSrc: "lsrc", 56 | origDir: "", 57 | webpDir: "" 58 | }; 59 | 60 | /** 61 | * 先对elements进行处理,找到所以包含 origSrc 的子元素。 62 | */ 63 | function adjust() { 64 | 65 | let _elements; 66 | 67 | elements.each(function() { 68 | let $this = $(this), 69 | _tmp; 70 | if (settings.skip_invisible && !$this.is(":visible")) { 71 | return; 72 | } 73 | 74 | let original = $this.attr(settings.origSrc); 75 | 76 | // 如果当前对象没有origSrc属性,同时当前对象不是图片节点, 77 | // 则查找子节点中有origSrc属性的节点,进行webp处理 78 | if (!original) { 79 | _tmp = $this.find("[" + settings.origSrc + "*=" + settings.origDir + "]"); 80 | } else { 81 | _tmp = $this; 82 | } 83 | 84 | if (_elements && _elements.length > 0) { 85 | if ($.merge) { // jquery merge 86 | _elements = $.merge(_elements, _tmp); 87 | } else { // zepto merge 88 | _elements.concat(_tmp); 89 | } 90 | } else { 91 | _elements = _tmp; 92 | } 93 | 94 | }); 95 | 96 | elements = _elements; 97 | } 98 | 99 | adjust(); 100 | 101 | function update() { 102 | 103 | elements.each(function() { 104 | $(this).trigger("appear"); 105 | }); 106 | 107 | } 108 | 109 | if (options) { 110 | $.extend(settings, options); 111 | } 112 | if (options.origDir && !options.webpDir) { 113 | throw new Error('option webpDir undefined!'); 114 | } 115 | 116 | elements.each(function() { 117 | let self = this; 118 | let $self = $(self); 119 | 120 | self.loaded = false; 121 | 122 | /* 触发appear事件时,控制替换或直接显示原图片 */ 123 | $self.one("appear", function() { 124 | 125 | if (!this.loaded) { 126 | 127 | let original = $self.attr(settings.origSrc); 128 | 129 | // 替换webp目录和图片后缀 130 | if (__supportwebp) { 131 | original = original 132 | .replace(settings.origDir, settings.webpDir) 133 | .replace(/\.(jpg|png|jpeg|gif)$/ig, '.webp'); 134 | } 135 | 136 | $("") 137 | .bind("load", function() { 138 | 139 | if ($self.is("img")) { 140 | // 如果当前节点是图片,则赋值src属性 141 | $self.attr("src", original); 142 | } else { 143 | // 如果当前节点不是图片,则赋值background-image属性 144 | $self.css("background-image", "url('" + original + "')"); 145 | } 146 | 147 | self.loaded = true; 148 | 149 | /* Remove image from array so it is not looped next time. */ 150 | var temp = $.grep(elements, function(element) { 151 | return !element.loaded; 152 | }); 153 | elements = $(temp); 154 | 155 | }) 156 | .attr("src", original); 157 | } 158 | }); 159 | }); 160 | 161 | supportWebp(function(){ 162 | update(); 163 | }); 164 | 165 | return this; 166 | }; 167 | 168 | $.extend($, { 169 | webp: function(options) { 170 | $(document).ready(function() { 171 | $(document).webp(options); 172 | }); 173 | } 174 | }); 175 | 176 | })(window, $); 177 | -------------------------------------------------------------------------------- /src/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(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 | 42 | $.fn.webp = function(options) { 43 | 44 | var elements = this; 45 | var $container; 46 | var settings = { 47 | threshold: 0, 48 | failure_limit: 0, 49 | event: "scroll", 50 | effect: "show", 51 | container: window, 52 | origSrc: "lsrc", 53 | origDir: "", 54 | webpDir: "", 55 | skip_invisible: false, 56 | appear: null, 57 | load: null, 58 | placeholder: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" 59 | }; 60 | 61 | /** 62 | * 先对elements进行处理,找到所以包含 origSrc 的子元素。 63 | */ 64 | function adjust() { 65 | 66 | var _elements; 67 | 68 | elements.each(function() { 69 | var $this = $(this), 70 | _tmp; 71 | if (settings.skip_invisible && !$this.is(":visible")) { 72 | return; 73 | } 74 | var original = $this.attr(settings.origSrc); 75 | 76 | // 如果当前对象没有origSrc属性,同时当前对象不是图片节点, 77 | // 则查找子节点中有origSrc属性的节点,进行webp处理 78 | if (!original) { 79 | _tmp = $this.find("[" + settings.origSrc + "*=" + settings.origDir + "]"); 80 | } else { 81 | _tmp = $this; 82 | } 83 | 84 | if (_elements && _elements.length > 0) { 85 | if ($.merge) { 86 | // jquery merge 87 | _elements = $.merge(_elements, _tmp); 88 | } else { 89 | // zepto merge 90 | _elements.concat(_tmp); 91 | } 92 | } else { 93 | _elements = _tmp; 94 | } 95 | }); 96 | 97 | elements = _elements; 98 | } 99 | 100 | adjust(); 101 | 102 | function update() { 103 | var counter = 0; 104 | 105 | elements.each(function() { 106 | var $this = $(this); 107 | if (settings.skip_invisible && !$this.is(":visible")) { 108 | return; 109 | } 110 | 111 | if ($.abovethetop(this, settings) || $.leftofbegin(this, settings)) { 112 | /* Nothing. */ 113 | } else if (!$.belowthefold(this, settings) && !$.rightoffold(this, settings)) { 114 | $this.trigger("appear"); 115 | /* if we found an image we'll load, reset the counter */ 116 | counter = 0; 117 | } else { 118 | if (++counter > settings.failure_limit) { 119 | return false; 120 | } 121 | } 122 | }); 123 | } 124 | 125 | if (options) { 126 | /* Maintain BC for a couple of versions. */ 127 | if (undefined !== options.failurelimit) { 128 | options.failure_limit = options.failurelimit; 129 | delete options.failurelimit; 130 | } 131 | if (undefined !== options.effectspeed) { 132 | options.effect_speed = options.effectspeed; 133 | delete options.effectspeed; 134 | } 135 | 136 | $.extend(settings, options); 137 | } 138 | 139 | if (options.origDir && !options.webpDir) { 140 | throw new Error('option webpDir undefined!'); 141 | } 142 | 143 | /* Cache container as jQuery as object. */ 144 | $container = settings.container === undefined || settings.container === window ? $window : $(settings.container); 145 | 146 | /* Fire one scroll event per scroll. Not one scroll event per image. */ 147 | if (0 === settings.event.indexOf("scroll")) { 148 | $container.bind(settings.event, function() { 149 | return update(); 150 | }); 151 | } 152 | 153 | elements.each(function() { 154 | var self = this; 155 | var $self = $(self); 156 | 157 | self.loaded = false; 158 | 159 | /* If no src attribute given use data:uri. */ 160 | if ($self.attr("src") === undefined || $self.attr("src") === false) { 161 | if ($self.is("img")) { 162 | $self.attr("src", settings.placeholder); 163 | } 164 | } 165 | 166 | /* When appear is triggered load original image. */ 167 | $self.one("appear", function() { 168 | if (!this.loaded) { 169 | if (settings.appear) { 170 | var elements_left = elements.length; 171 | settings.appear.call(self, elements_left, settings); 172 | } 173 | 174 | var original = $self.attr(settings.origSrc); 175 | 176 | // 替换webp目录和图片后缀 177 | if (__supportwebp) { 178 | original = original.replace(settings.origDir, settings.webpDir).replace(/\.(jpg|png|jpeg|gif)$/ig, '.webp'); 179 | } 180 | 181 | $("").bind("load", function() { 182 | 183 | $self.hide(); 184 | if ($self.is("img")) { 185 | $self.attr("src", original); 186 | } else { 187 | $self.css("background-image", "url('" + original + "')"); 188 | } 189 | $self[settings.effect](settings.effect_speed); 190 | 191 | self.loaded = true; 192 | 193 | /* Remove image from array so it is not looped next time. */ 194 | var temp = $.grep(elements, function(element) { 195 | return !element.loaded; 196 | }); 197 | elements = $(temp); 198 | 199 | if (settings.load) { 200 | var elements_left = elements.length; 201 | settings.load.call(self, elements_left, settings); 202 | } 203 | }).attr("src", original); 204 | } 205 | }); 206 | 207 | /* When wanted event is triggered load original image */ 208 | /* by triggering appear. */ 209 | if (0 !== settings.event.indexOf("scroll")) { 210 | $self.bind(settings.event, function() { 211 | if (!self.loaded) { 212 | $self.trigger("appear"); 213 | } 214 | }); 215 | } 216 | }); 217 | 218 | /* Check if something appears when window is resized. */ 219 | $window.bind("resize", function() { 220 | update(); 221 | }); 222 | 223 | /* With IOS5 force loading images when navigating with back button. */ 224 | /* Non optimal workaround. */ 225 | if (/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)) { 226 | $window.bind("pageshow", function(event) { 227 | if (event.originalEvent && event.originalEvent.persisted) { 228 | elements.each(function() { 229 | $(this).trigger("appear"); 230 | }); 231 | } 232 | }); 233 | } 234 | 235 | /* Force initial check if images should appear. */ 236 | $(document).ready(function() { 237 | supportWebp(function() { 238 | update(); 239 | }); 240 | }); 241 | 242 | return this; 243 | }; 244 | 245 | /* Convenience methods in jQuery namespace. */ 246 | /* Use as $.belowthefold(element, {threshold : 100, container : window}) */ 247 | 248 | $.belowthefold = function(element, settings) { 249 | var fold; 250 | 251 | if (settings.container === undefined || settings.container === window) { 252 | fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop(); 253 | } else { 254 | fold = $(settings.container).offset().top + $(settings.container).height(); 255 | } 256 | return fold <= $(element).offset().top - settings.threshold; 257 | }; 258 | 259 | $.rightoffold = function(element, settings) { 260 | var fold; 261 | 262 | if (settings.container === undefined || settings.container === window) { 263 | fold = $window.width() + $window.scrollLeft(); 264 | } else { 265 | fold = $(settings.container).offset().left + $(settings.container).width(); 266 | } 267 | 268 | return fold <= $(element).offset().left - settings.threshold; 269 | }; 270 | 271 | $.abovethetop = function(element, settings) { 272 | var fold; 273 | 274 | if (settings.container === undefined || settings.container === window) { 275 | fold = $window.scrollTop(); 276 | } else { 277 | fold = $(settings.container).offset().top; 278 | } 279 | return fold >= $(element).offset().top + settings.threshold + $(element).height(); 280 | }; 281 | 282 | $.leftofbegin = function(element, settings) { 283 | var fold; 284 | 285 | if (settings.container === undefined || settings.container === window) { 286 | fold = $window.scrollLeft(); 287 | } else { 288 | fold = $(settings.container).offset().left; 289 | } 290 | 291 | return fold >= $(element).offset().left + settings.threshold + $(element).width(); 292 | }; 293 | 294 | $.inviewport = function(element, settings) { 295 | return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings); 296 | }; 297 | 298 | $.extend($, { 299 | webp: function webp(options) { 300 | $(document).webp(options); 301 | } 302 | }); 303 | })($, window, document); 304 | --------------------------------------------------------------------------------