mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-04 10:19:24 +02:00
Lazy load images: speed up page loading times and decrease traffic
This commit is contained in:
parent
1a4965c27a
commit
3be99ba74e
30 changed files with 3312 additions and 59 deletions
580
view/js/jquery.lazy/jquery.lazy.plugins.js
Normal file
580
view/js/jquery.lazy/jquery.lazy.plugins.js
Normal file
|
@ -0,0 +1,580 @@
|
|||
/*!
|
||||
* jQuery & Zepto Lazy - AJAX Plugin - v1.2
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
// load data by ajax request and pass them to elements inner html, like:
|
||||
// <div data-loader="ajax" data-src"url.html" data-method="post" data-type="html"></div>
|
||||
$.lazy("ajax", function(element, response) {
|
||||
ajaxRequest(this, element, response, element.attr("data-method"));
|
||||
});
|
||||
|
||||
// load data by ajax get request and pass them to elements inner html, like:
|
||||
// <div data-loader="get" data-src"url.html" data-type="html"></div>
|
||||
$.lazy("get", function(element, response) {
|
||||
ajaxRequest(this, element, response, "get");
|
||||
});
|
||||
|
||||
// load data by ajax post request and pass them to elements inner html, like:
|
||||
// <div data-loader="post" data-src"url.html" data-type="html"></div>
|
||||
$.lazy("post", function(element, response) {
|
||||
ajaxRequest(this, element, response, "post");
|
||||
});
|
||||
|
||||
/**
|
||||
* execute ajax request and handle response
|
||||
* @param {object} instance
|
||||
* @param {jQuery|object} element
|
||||
* @param {function} response
|
||||
* @param {string} [method]
|
||||
*/
|
||||
function ajaxRequest(instance, element, response, method) {
|
||||
$.ajax({
|
||||
url: element.attr("data-src"),
|
||||
type: method || "get",
|
||||
dataType: element.attr("data-type") || "html",
|
||||
|
||||
/**
|
||||
* success callback
|
||||
* @access private
|
||||
* @param {*} content
|
||||
* @return {void}
|
||||
*/
|
||||
success: function(content) {
|
||||
// set responded data to element's inner html
|
||||
element.html(content);
|
||||
|
||||
// use response function for Zepto
|
||||
response(true);
|
||||
|
||||
// remove attributes
|
||||
if( instance.config("removeAttribute") )
|
||||
element.removeAttr("data-src data-method data-type");
|
||||
},
|
||||
|
||||
/**
|
||||
* error callback
|
||||
* @access private
|
||||
* @return {void}
|
||||
*/
|
||||
error: function() {
|
||||
// pass error state to lazy
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
})(window.jQuery || window.Zepto);
|
||||
|
||||
/*!
|
||||
* jQuery & Zepto Lazy - AV Plugin - v1.4
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
// loads audio and video tags including tracks by two ways, like:
|
||||
// <audio>
|
||||
// <data-src src="audio.ogg" type="video/ogg"></data-src>
|
||||
// <data-src src="audio.mp3" type="video/mp3"></data-src>
|
||||
// </audio>
|
||||
// <video data-poster="poster.jpg">
|
||||
// <data-src src="video.ogv" type="video/ogv"></data-src>
|
||||
// <data-src src="video.webm" type="video/webm"></data-src>
|
||||
// <data-src src="video.mp4" type="video/mp4"></data-src>
|
||||
// <data-track kind="captions" src="captions.vtt" srclang="en"></data-track>
|
||||
// <data-track kind="descriptions" src="descriptions.vtt" srclang="en"></data-track>
|
||||
// <data-track kind="subtitles" src="subtitles.vtt" srclang="de"></data-track>
|
||||
// </video>
|
||||
//
|
||||
// or:
|
||||
// <audio data-src="audio.ogg|video/ogg,video.mp3|video/mp3"></video>
|
||||
// <video data-poster="poster.jpg" data-src="video.ogv|video/ogv,video.webm|video/webm,video.mp4|video/mp4">
|
||||
// <data-track kind="captions" src="captions.vtt" srclang="en"></data-track>
|
||||
// <data-track kind="descriptions" src="descriptions.vtt" srclang="en"></data-track>
|
||||
// <data-track kind="subtitles" src="subtitles.vtt" srclang="de"></data-track>
|
||||
// </video>
|
||||
$.lazy(["av", "audio", "video"], ["audio", "video"], function(element, response) {
|
||||
var elementTagName = element[0].tagName.toLowerCase();
|
||||
|
||||
if( elementTagName === "audio" || elementTagName === "video" ) {
|
||||
var srcAttr = "data-src",
|
||||
sources = element.find(srcAttr),
|
||||
tracks = element.find("data-track"),
|
||||
sourcesInError = 0,
|
||||
|
||||
// create on error callback for sources
|
||||
onError = function() {
|
||||
if( ++sourcesInError === sources.length )
|
||||
response(false);
|
||||
},
|
||||
|
||||
// create callback to handle a source or track entry
|
||||
handleSource = function() {
|
||||
var source = $(this),
|
||||
type = source[0].tagName.toLowerCase(),
|
||||
attributes = source.prop("attributes"),
|
||||
target = $(type === srcAttr ? "<source>" : "<track>");
|
||||
|
||||
if( type === srcAttr )
|
||||
target.one("error", onError);
|
||||
|
||||
$.each(attributes, function(index, attribute) {
|
||||
target.attr(attribute.name, attribute.value);
|
||||
});
|
||||
|
||||
source.replaceWith(target);
|
||||
};
|
||||
|
||||
// create event for successfull load
|
||||
element.one("loadedmetadata", function() {
|
||||
response(true);
|
||||
})
|
||||
|
||||
// remove default callbacks to ignore loading poster image
|
||||
.off("load error")
|
||||
|
||||
// load poster image
|
||||
.attr("poster", element.attr("data-poster"));
|
||||
|
||||
// load by child tags
|
||||
if( sources.length )
|
||||
sources.each(handleSource);
|
||||
|
||||
// load by attribute
|
||||
else if( element.attr(srcAttr) ) {
|
||||
// split for every entry by comma
|
||||
$.each(element.attr(srcAttr).split(","), function(index, value) {
|
||||
// split again for file and file type
|
||||
var parts = value.split("|");
|
||||
|
||||
// create a source entry
|
||||
element.append($("<source>")
|
||||
.one("error", onError)
|
||||
.attr({src: parts[0].trim(), type: parts[1].trim()}));
|
||||
});
|
||||
|
||||
// remove now obsolete attribute
|
||||
if( this.config("removeAttribute") )
|
||||
element.removeAttr(srcAttr);
|
||||
}
|
||||
|
||||
else {
|
||||
// pass error state
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
|
||||
// load optional tracks
|
||||
if( tracks.length )
|
||||
tracks.each(handleSource);
|
||||
}
|
||||
|
||||
else {
|
||||
// pass error state
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
})(window.jQuery || window.Zepto);
|
||||
|
||||
/*!
|
||||
* jQuery & Zepto Lazy - iFrame Plugin - v1.5
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
// load iframe content, like:
|
||||
// <iframe data-src="iframe.html"></iframe>
|
||||
//
|
||||
// enable content error check with:
|
||||
// <iframe data-src="iframe.html" data-error-detect="true"></iframe>
|
||||
$.lazy(["frame", "iframe"], "iframe", function(element, response) {
|
||||
var instance = this;
|
||||
|
||||
if( element[0].tagName.toLowerCase() === "iframe" ) {
|
||||
var srcAttr = "data-src",
|
||||
errorDetectAttr = "data-error-detect",
|
||||
errorDetect = element.attr(errorDetectAttr);
|
||||
|
||||
// default way, just replace the 'src' attribute
|
||||
if( errorDetect !== "true" && errorDetect !== "1" ) {
|
||||
// set iframe source
|
||||
element.attr("src", element.attr(srcAttr));
|
||||
|
||||
// remove attributes
|
||||
if( instance.config("removeAttribute") )
|
||||
element.removeAttr(srcAttr + " " + errorDetectAttr);
|
||||
}
|
||||
|
||||
// extended way, even check if the document is available
|
||||
else {
|
||||
$.ajax({
|
||||
url: element.attr(srcAttr),
|
||||
dataType: "html",
|
||||
crossDomain: true,
|
||||
xhrFields: {withCredentials: true},
|
||||
|
||||
/**
|
||||
* success callback
|
||||
* @access private
|
||||
* @param {*} content
|
||||
* @return {void}
|
||||
*/
|
||||
success: function(content) {
|
||||
// set responded data to element's inner html
|
||||
element.html(content)
|
||||
|
||||
// change iframe src
|
||||
.attr("src", element.attr(srcAttr));
|
||||
|
||||
// remove attributes
|
||||
if( instance.config("removeAttribute") )
|
||||
element.removeAttr(srcAttr + " " + errorDetectAttr);
|
||||
},
|
||||
|
||||
/**
|
||||
* error callback
|
||||
* @access private
|
||||
* @return {void}
|
||||
*/
|
||||
error: function() {
|
||||
// pass error state to lazy
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
// pass error state to lazy
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
})(window.jQuery || window.Zepto);
|
||||
|
||||
/*!
|
||||
* jQuery & Zepto Lazy - NOOP Plugin - v1.2
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
// will do nothing, used to disable elements or for development
|
||||
// use like:
|
||||
// <div data-loader="noop"></div>
|
||||
|
||||
// does not do anything, just a 'no-operation' helper ;)
|
||||
$.lazy("noop", function() {});
|
||||
|
||||
// does nothing, but response a successfull loading
|
||||
$.lazy("noop-success", function(element, response) {
|
||||
// use response function for Zepto
|
||||
response(true);
|
||||
});
|
||||
|
||||
// does nothing, but response a failed loading
|
||||
$.lazy("noop-error", function(element, response) {
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
});
|
||||
})(window.jQuery || window.Zepto);
|
||||
|
||||
/*!
|
||||
* jQuery & Zepto Lazy - Picture Plugin - v1.3
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
var srcAttr = "data-src",
|
||||
srcsetAttr = "data-srcset",
|
||||
mediaAttr = "data-media",
|
||||
sizesAttr = "data-sizes",
|
||||
typeAttr = "data-type";
|
||||
|
||||
// loads picture elements like:
|
||||
// <picture>
|
||||
// <data-src srcset="1x.jpg 1x, 2x.jpg 2x, 3x.jpg 3x" media="(min-width: 600px)" type="image/jpeg"></data-src>
|
||||
// <data-src srcset="1x.jpg 1x, 2x.jpg 2x, 3x.jpg 3x" media="(min-width: 400px)" type="image/jpeg"></data-src>
|
||||
// <data-img src="default.jpg" >
|
||||
// </picture>
|
||||
//
|
||||
// or:
|
||||
// <picture data-src="default.jpg">
|
||||
// <data-src srcset="1x.jpg 1x, 2x.jpg 2x, 3x.jpg 3x" media="(min-width: 600px)" type="image/jpeg"></data-src>
|
||||
// <data-src srcset="1x.jpg 1x, 2x.jpg 2x, 3x.jpg 3x" media="(min-width: 400px)" type="image/jpeg"></data-src>
|
||||
// </picture>
|
||||
//
|
||||
// or just with attributes in one line:
|
||||
// <picture data-src="default.jpg" data-srcset="1x.jpg 1x, 2x.jpg 2x, 3x.jpg 3x" data-media="(min-width: 600px)" data-sizes="" data-type="image/jpeg" />
|
||||
$.lazy(["pic", "picture"], ["picture"], function(element, response) {
|
||||
var elementTagName = element[0].tagName.toLowerCase();
|
||||
|
||||
if( elementTagName === "picture" ) {
|
||||
var sources = element.find(srcAttr),
|
||||
image = element.find("data-img"),
|
||||
imageBase = this.config("imageBase") || "";
|
||||
|
||||
// handle as child elements
|
||||
if( sources.length ) {
|
||||
sources.each(function() {
|
||||
renameElementTag($(this), "source", imageBase);
|
||||
});
|
||||
|
||||
// create img tag from child
|
||||
if( image.length === 1 ) {
|
||||
image = renameElementTag(image, "img", imageBase);
|
||||
|
||||
// bind event callbacks to new image tag
|
||||
image.on("load", function() {
|
||||
response(true);
|
||||
}).on("error", function() {
|
||||
response(false);
|
||||
});
|
||||
|
||||
image.attr("src", image.attr(srcAttr));
|
||||
|
||||
if( this.config("removeAttribute") ) {
|
||||
image.removeAttr(srcAttr);
|
||||
}
|
||||
}
|
||||
|
||||
// create img tag from attribute
|
||||
else if( element.attr(srcAttr) ) {
|
||||
// create image tag
|
||||
createImageObject(element, imageBase + element.attr(srcAttr), response);
|
||||
|
||||
if( this.config("removeAttribute") )
|
||||
element.removeAttr(srcAttr);
|
||||
}
|
||||
|
||||
// pass error state
|
||||
else {
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
}
|
||||
|
||||
// handle as attributes
|
||||
else if( element.attr(srcsetAttr) ) {
|
||||
// create source elements before img tag
|
||||
$("<source>").attr({
|
||||
media: element.attr(mediaAttr),
|
||||
sizes: element.attr(sizesAttr),
|
||||
type: element.attr(typeAttr),
|
||||
srcset: getCorrectedSrcSet(element.attr(srcsetAttr), imageBase)
|
||||
})
|
||||
.appendTo(element);
|
||||
|
||||
// create image tag
|
||||
createImageObject(element, imageBase + element.attr(srcAttr), response);
|
||||
|
||||
// remove attributes from parent picture element
|
||||
if( this.config("removeAttribute") ) {
|
||||
element.removeAttr(srcAttr + " " + srcsetAttr + " " + mediaAttr + " " + sizesAttr + " " + typeAttr);
|
||||
}
|
||||
}
|
||||
|
||||
// pass error state
|
||||
else {
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
// pass error state
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* create a new child element and copy attributes
|
||||
* @param {jQuery|object} element
|
||||
* @param {string} toType
|
||||
* @param {string} imageBase
|
||||
* @return {jQuery|object}
|
||||
*/
|
||||
function renameElementTag(element, toType, imageBase) {
|
||||
var attributes = element.prop("attributes"),
|
||||
target = $("<" + toType + ">");
|
||||
|
||||
$.each(attributes, function(index, attribute) {
|
||||
// build srcset with image base
|
||||
if( attribute.name === "srcset" || attribute.name === srcAttr ) {
|
||||
attribute.value = getCorrectedSrcSet(attribute.value, imageBase);
|
||||
}
|
||||
|
||||
target.attr(attribute.name, attribute.value);
|
||||
});
|
||||
|
||||
element.replaceWith(target);
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new image element inside parent element
|
||||
* @param {jQuery|object} parent
|
||||
* @param {string} src
|
||||
* @param {function} response
|
||||
* @return void
|
||||
*/
|
||||
function createImageObject(parent, src, response) {
|
||||
// create image tag
|
||||
var imageObj = $("<img>")
|
||||
|
||||
// create image tag an bind callbacks for correct response
|
||||
.one("load", function() {
|
||||
response(true);
|
||||
})
|
||||
.one("error", function() {
|
||||
response(false);
|
||||
})
|
||||
|
||||
// set into picture element
|
||||
.appendTo(parent)
|
||||
|
||||
// set src attribute at last to prevent early kick-in
|
||||
.attr("src", src);
|
||||
|
||||
// call after load even on cached image
|
||||
imageObj.complete && imageObj.load(); // jshint ignore : line
|
||||
}
|
||||
|
||||
/**
|
||||
* prepend image base to all srcset entries
|
||||
* @param {string} srcset
|
||||
* @param {string} imageBase
|
||||
* @returns {string}
|
||||
*/
|
||||
function getCorrectedSrcSet(srcset, imageBase) {
|
||||
if( imageBase ) {
|
||||
// trim, remove unnecessary spaces and split entries
|
||||
var entries = srcset.split(",");
|
||||
srcset = "";
|
||||
|
||||
for( var i = 0, l = entries.length; i < l; i++ ) {
|
||||
srcset += imageBase + entries[i].trim() + (i !== l - 1 ? "," : "");
|
||||
}
|
||||
}
|
||||
|
||||
return srcset;
|
||||
}
|
||||
})(window.jQuery || window.Zepto);
|
||||
|
||||
/*!
|
||||
* jQuery & Zepto Lazy - Script Plugin - v1.2
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
// loads javascript files for script tags, like:
|
||||
// <script data-src="file.js" type="text/javascript"></script>
|
||||
$.lazy(["js", "javascript", "script"], "script", function(element, response) {
|
||||
if( element[0].tagName.toLowerCase() == "script" ) {
|
||||
element.attr("src", element.attr("data-src"));
|
||||
|
||||
// remove attribute
|
||||
if( this.config("removeAttribute") )
|
||||
element.removeAttr("data-src");
|
||||
}
|
||||
else {
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
})(window.jQuery || window.Zepto);
|
||||
|
||||
/*!
|
||||
* jQuery & Zepto Lazy - Vimeo Plugin - v1.1
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
// load vimeo video iframe, like:
|
||||
// <iframe data-loader="vimeo" data-src="176894130" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
$.lazy("vimeo", function(element, response) {
|
||||
if( element[0].tagName.toLowerCase() === "iframe" ) {
|
||||
// pass source to iframe
|
||||
element.attr("src", "https://player.vimeo.com/video/" + element.attr("data-src"));
|
||||
|
||||
// remove attribute
|
||||
if( this.config("removeAttribute") )
|
||||
element.removeAttr("data-src");
|
||||
}
|
||||
|
||||
else {
|
||||
// pass error state
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
})(window.jQuery || window.Zepto);
|
||||
|
||||
/*!
|
||||
* jQuery & Zepto Lazy - YouTube Plugin - v1.4
|
||||
* http://jquery.eisbehr.de/lazy/
|
||||
*
|
||||
* Copyright 2012 - 2017, Daniel 'Eisbehr' Kern
|
||||
*
|
||||
* Dual licensed under the MIT and GPL-2.0 licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
;(function($) {
|
||||
// load youtube video iframe, like:
|
||||
// <iframe data-loader="yt" data-src="1AYGnw6MwFM" width="560" height="315" frameborder="0" allowfullscreen></iframe>
|
||||
$.lazy(["yt", "youtube"], function(element, response) {
|
||||
if( element[0].tagName.toLowerCase() === "iframe" ) {
|
||||
// pass source to iframe
|
||||
element.attr("src", "https://www.youtube.com/embed/" + element.attr("data-src") + "?rel=0&showinfo=0");
|
||||
|
||||
// remove attribute
|
||||
if( this.config("removeAttribute") )
|
||||
element.removeAttr("data-src");
|
||||
}
|
||||
|
||||
else {
|
||||
// pass error state
|
||||
// use response function for Zepto
|
||||
response(false);
|
||||
}
|
||||
});
|
||||
})(window.jQuery || window.Zepto);
|
Loading…
Add table
Add a link
Reference in a new issue