Version Description
- Added Lazy Load feature to improve the web page loading times of your images.
- Added an option to remove all rss feed links from WP Head.
- Added plugin options informations to the footer, visible in page source, useful for debugging.
Download this release
Release Info
| Developer | tiguan |
| Plugin | |
| Version | 1.5 |
| Comparing to | |
| See all releases | |
Code changes from version 1.4 to 1.5
- images/1x1.trans.gif +0 -0
- inc/core.php +20 -4
- inc/images/1x1.trans.gif +0 -0
- inc/js/jquery.sonar.js +421 -0
- inc/js/jquery.sonar.min.js +1 -0
- inc/js/sbp-lazy-load.js +30 -0
- inc/lazy-load.php +52 -0
- inc/template/options.php +5 -0
- js/jquery.sonar.js +421 -0
- js/jquery.sonar.min.js +1 -0
- js/sbp-lazy-load.js +30 -0
- readme.txt +11 -3
- speed-booster-pack.php +20 -4
images/1x1.trans.gif
ADDED
|
Binary file
|
inc/core.php
CHANGED
|
@@ -19,6 +19,11 @@ if( !class_exists( 'Speed_Booster_Pack_Core' ) ) {
|
|
| 19 |
$this->sbp_use_google_libraries();
|
| 20 |
}
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
// Defer parsing of JavaScript
|
| 23 |
if ( !is_admin() and isset( $sbp_options['defer_parsing'] ) ) {
|
| 24 |
add_filter( 'clean_url', array( $this, 'sbp_defer_parsing_of_js' ), 11, 1 );
|
|
@@ -89,16 +94,27 @@ function sbp_show_page_load_stats() {
|
|
| 89 |
|
| 90 |
function sbp_use_google_libraries() {
|
| 91 |
|
| 92 |
-
|
| 93 |
|
| 94 |
-
|
| 95 |
-
|
| 96 |
|
| 97 |
-
|
| 98 |
|
| 99 |
} // End function sbp_use_google_libraries()
|
| 100 |
|
| 101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
/*----------------------------------------------
|
| 103 |
Defer parsing of JavaScript
|
| 104 |
-----------------------------------------------*/
|
| 19 |
$this->sbp_use_google_libraries();
|
| 20 |
}
|
| 21 |
|
| 22 |
+
// Use Google Libraries
|
| 23 |
+
if ( !is_admin() and isset( $sbp_options['lazy_load'] ) ) {
|
| 24 |
+
$this->sbp_lazy_load_for_images();
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
// Defer parsing of JavaScript
|
| 28 |
if ( !is_admin() and isset( $sbp_options['defer_parsing'] ) ) {
|
| 29 |
add_filter( 'clean_url', array( $this, 'sbp_defer_parsing_of_js' ), 11, 1 );
|
| 94 |
|
| 95 |
function sbp_use_google_libraries() {
|
| 96 |
|
| 97 |
+
require_once( SPEED_BOOSTER_PACK_PATH . 'inc/use-google-libraries.php' );
|
| 98 |
|
| 99 |
+
if ( class_exists( 'JCP_UseGoogleLibraries' ) ) {
|
| 100 |
+
JCP_UseGoogleLibraries::configure_plugin();
|
| 101 |
|
| 102 |
+
}
|
| 103 |
|
| 104 |
} // End function sbp_use_google_libraries()
|
| 105 |
|
| 106 |
|
| 107 |
+
/*----------------------------------------------
|
| 108 |
+
Lazy Load for images
|
| 109 |
+
-----------------------------------------------*/
|
| 110 |
+
|
| 111 |
+
function sbp_lazy_load_for_images() {
|
| 112 |
+
|
| 113 |
+
require_once( SPEED_BOOSTER_PACK_PATH . 'inc/lazy-load.php' );
|
| 114 |
+
|
| 115 |
+
} // End function sbp_lazy_load_for_images()
|
| 116 |
+
|
| 117 |
+
|
| 118 |
/*----------------------------------------------
|
| 119 |
Defer parsing of JavaScript
|
| 120 |
-----------------------------------------------*/
|
inc/images/1x1.trans.gif
ADDED
|
Binary file
|
inc/js/jquery.sonar.js
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
An elem for determining if an elem is within a certain
|
| 3 |
+
distance from the edge above or below the screen, and attaching
|
| 4 |
+
a function to execute once the elem is in view.
|
| 5 |
+
|
| 6 |
+
General Usage:
|
| 7 |
+
|
| 8 |
+
* Place the library anywhere in your JavaScript code before you
|
| 9 |
+
intend to call the function.
|
| 10 |
+
|
| 11 |
+
* To initialize Sonar with a different default distance, modify
|
| 12 |
+
the sonar = Sonar() line immediately following the Sonar
|
| 13 |
+
library definition. Example:
|
| 14 |
+
|
| 15 |
+
sonar=Sonar(100); // Initializes Sonar with a 100px default distance.
|
| 16 |
+
|
| 17 |
+
Note:
|
| 18 |
+
|
| 19 |
+
* The default distance is 0 pixels.
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
sonar.detect() Usage
|
| 23 |
+
|
| 24 |
+
* Use sonar.detect(elem, distance) to check if the
|
| 25 |
+
elem is within screen boundaries.
|
| 26 |
+
|
| 27 |
+
@elem - The elem you want to detect visibility.
|
| 28 |
+
@distance - The distance from the screen edge that should
|
| 29 |
+
count in the check. Uses default distance if not specified.
|
| 30 |
+
|
| 31 |
+
* Note: sonar.detect() adds a property to
|
| 32 |
+
ojbects called sonarElemTop. Test to ensure there
|
| 33 |
+
aren't any conflicts with your code. If there
|
| 34 |
+
are, rename sonarElemTop to something else in the code.
|
| 35 |
+
|
| 36 |
+
* sonar.detect() returns:
|
| 37 |
+
true if the elem is within the screen boundaries
|
| 38 |
+
false if th elem is out of the screen boundaries
|
| 39 |
+
|
| 40 |
+
Example:
|
| 41 |
+
|
| 42 |
+
Here's how to check if an advertisment is visible on a
|
| 43 |
+
page that has the id, "ad".
|
| 44 |
+
|
| 45 |
+
if (sonar.detect(document.getElementById("ad")))
|
| 46 |
+
{
|
| 47 |
+
alert('The ad is visible on screen!');
|
| 48 |
+
}
|
| 49 |
+
else
|
| 50 |
+
{
|
| 51 |
+
alert ('The ad is not on screen!);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
sonar.add() Usage
|
| 55 |
+
|
| 56 |
+
* This method stores elems that are then polled
|
| 57 |
+
on user scroll by the Sonar.detect() method.
|
| 58 |
+
|
| 59 |
+
* Polling initializes once the sonar.add() method is passed
|
| 60 |
+
an elem with the following properties:
|
| 61 |
+
|
| 62 |
+
obj : A reference to the elem to observe until it is within
|
| 63 |
+
the specified distance (px).
|
| 64 |
+
|
| 65 |
+
id : An alternative to the obj parameter, an "id" can be used
|
| 66 |
+
to grab the elem to observe.
|
| 67 |
+
|
| 68 |
+
call: The function to call when the elem is within the
|
| 69 |
+
specified distance (px). The @elem argument will
|
| 70 |
+
include the elem that triggered the callback.
|
| 71 |
+
|
| 72 |
+
px : The specified distance to include as being visible on
|
| 73 |
+
screen. This property is optional (default is 0).
|
| 74 |
+
|
| 75 |
+
Example:
|
| 76 |
+
|
| 77 |
+
sonar.add(
|
| 78 |
+
{
|
| 79 |
+
obj: document.getElementById("0026-get-out-the-way"),
|
| 80 |
+
call: function(elem) // elem will include the elem that triggered the function.
|
| 81 |
+
{
|
| 82 |
+
swfelem.embedSWF("../player.swf", "0026-get-out-the-way", "640", "500", "9.0.0",
|
| 83 |
+
{}, {file: "0026-get-out-the-way.flv", fullscreen: true},
|
| 84 |
+
{allowfullscreen: true, allowscriptaccess: "always"});
|
| 85 |
+
},
|
| 86 |
+
px: 400
|
| 87 |
+
});
|
| 88 |
+
|
| 89 |
+
You can also specify an id tag to be grabbed instead of the elem:
|
| 90 |
+
|
| 91 |
+
sonar.add(
|
| 92 |
+
{
|
| 93 |
+
id: "0026-get-out-the-way",
|
| 94 |
+
call: function(elem) // elem will include the elem that triggered the function.
|
| 95 |
+
{
|
| 96 |
+
swfelem.embedSWF("../player.swf", "0026-get-out-the-way", "640", "500", "9.0.0",
|
| 97 |
+
{}, {file: "0026-get-out-the-way.flv", fullscreen: true},
|
| 98 |
+
{allowfullscreen: true, allowscriptaccess: "always"});
|
| 99 |
+
},
|
| 100 |
+
px: 400
|
| 101 |
+
});
|
| 102 |
+
|
| 103 |
+
Notes:
|
| 104 |
+
|
| 105 |
+
* Setting the body or html of your page to 100% will cause sonar to have
|
| 106 |
+
an invalid height calculation in Firefox. It is recommended that you
|
| 107 |
+
do not set this CSS property.
|
| 108 |
+
|
| 109 |
+
Example:
|
| 110 |
+
|
| 111 |
+
html, body {
|
| 112 |
+
height:100%; // Do not do this.
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
* If you want to set the default distance to something other
|
| 116 |
+
than 0, either update the property directly in the code or
|
| 117 |
+
you can do this:
|
| 118 |
+
|
| 119 |
+
sonar.blip.d = 100; // Where 100 = 100 pixels above and below the screen edge.
|
| 120 |
+
|
| 121 |
+
* Sleep well at night knowing Sonar automatically cleans up the
|
| 122 |
+
event listeners on the scroll event once all calls have executed.
|
| 123 |
+
|
| 124 |
+
Code History:
|
| 125 |
+
|
| 126 |
+
v3 :: 8/14/2009 - David Artz (david.artz@corp.aol.com)
|
| 127 |
+
* Fixed a bug in the polling code where splicing caused our
|
| 128 |
+
for loop to skip over the next iteration in the loop. This
|
| 129 |
+
caused some images in the poll to be detected when they
|
| 130 |
+
should have been.
|
| 131 |
+
* Re-factored Sonar to use the "Module" JavaScript library
|
| 132 |
+
pattern, making our private variables and functions more
|
| 133 |
+
private and inaccessible from the public interface.
|
| 134 |
+
* Updated the sonar.add() function to return true or false,
|
| 135 |
+
useful for determining if Sonar added the elem to the
|
| 136 |
+
poll or executed its callback immediately.
|
| 137 |
+
|
| 138 |
+
v2 :: 3/24/2009 - David Artz (david.artz@corp.aol.com)
|
| 139 |
+
* Added support for IE 8.
|
| 140 |
+
* Updated the way scroll top and screen height are detected, now
|
| 141 |
+
works in IE/FF/Safari quirks mode.
|
| 142 |
+
* Added null check for IE, it was polling for an elem that had recently
|
| 143 |
+
been spliced out of the array. Nasty.
|
| 144 |
+
* Modified for loop to use standard syntax. for (i in x) is known to be
|
| 145 |
+
buggy with JS frameworks that override arrays.
|
| 146 |
+
* Added sonar.b property to cache the body element (improving lookup time).
|
| 147 |
+
|
| 148 |
+
v1 :: 11/18/2008 - David Artz (david.artz@corp.aol.com)
|
| 149 |
+
* Officially released code for general use.
|
| 150 |
+
|
| 151 |
+
*/
|
| 152 |
+
|
| 153 |
+
(function( $, win, doc, undefined ){
|
| 154 |
+
|
| 155 |
+
$.fn.sonar = function( distance, full ){
|
| 156 |
+
// No callbacks, return the results from Sonar for
|
| 157 |
+
// the first element in the stack.
|
| 158 |
+
if ( typeof distance === "boolean" ) {
|
| 159 |
+
full = distance;
|
| 160 |
+
distance = undefined;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
return $.sonar( this[0], distance, full );
|
| 164 |
+
};
|
| 165 |
+
|
| 166 |
+
var body = doc.body,
|
| 167 |
+
$win = $(win),
|
| 168 |
+
|
| 169 |
+
onScreenEvent = "scrollin",
|
| 170 |
+
offScreenEvent = "scrollout",
|
| 171 |
+
|
| 172 |
+
detect = function( elem, distance, full ){
|
| 173 |
+
|
| 174 |
+
if ( elem ) {
|
| 175 |
+
|
| 176 |
+
// Cache the body elem in our private global.
|
| 177 |
+
body || ( body = doc.body );
|
| 178 |
+
|
| 179 |
+
var parentElem = elem, // Clone the elem for use in our loop.
|
| 180 |
+
|
| 181 |
+
elemTop = 0, // The resets the calculated elem top to 0.
|
| 182 |
+
|
| 183 |
+
// Used to recalculate elem.sonarElemTop if body height changes.
|
| 184 |
+
bodyHeight = body.offsetHeight,
|
| 185 |
+
|
| 186 |
+
// NCZ: I don't think you need innerHeight, I believe all major browsers support clientHeight.
|
| 187 |
+
screenHeight = win.innerHeight || doc.documentElement.clientHeight || body.clientHeight || 0, // Height of the screen.
|
| 188 |
+
|
| 189 |
+
// NCZ: I don't think you need pageYOffset, I believe all major browsers support scrollTop.
|
| 190 |
+
scrollTop = doc.documentElement.scrollTop || win.pageYOffset || body.scrollTop || 0, // How far the user scrolled down.
|
| 191 |
+
elemHeight = elem.offsetHeight || 0; // Height of the element.
|
| 192 |
+
|
| 193 |
+
// If our custom "sonarTop" variable is undefined, or the document body
|
| 194 |
+
// height has changed since the last time we ran sonar.detect()...
|
| 195 |
+
if ( !elem.sonarElemTop || elem.sonarBodyHeight !== bodyHeight ) {
|
| 196 |
+
|
| 197 |
+
// Loop through the offsetParents to calculate it.
|
| 198 |
+
if ( parentElem.offsetParent ) {
|
| 199 |
+
do {
|
| 200 |
+
elemTop += parentElem.offsetTop;
|
| 201 |
+
}
|
| 202 |
+
while ( parentElem = parentElem.offsetParent );
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
// Set the custom property (sonarTop) to avoid future attempts to calculate
|
| 206 |
+
// the distance on this elem from the top of the page.
|
| 207 |
+
elem.sonarElemTop = elemTop;
|
| 208 |
+
|
| 209 |
+
// Along the same lines, store the body height when we calculated
|
| 210 |
+
// the elem's top.
|
| 211 |
+
elem.sonarBodyHeight = bodyHeight;
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
// If no distance was given, assume 0.
|
| 215 |
+
distance = distance === undefined ? 0 : distance;
|
| 216 |
+
|
| 217 |
+
// Dump all calculated variables.
|
| 218 |
+
/*
|
| 219 |
+
console.dir({
|
| 220 |
+
elem: elem,
|
| 221 |
+
sonarElemTop: elem.sonarElemTop,
|
| 222 |
+
elemHeight: elemHeight,
|
| 223 |
+
scrollTop: scrollTop,
|
| 224 |
+
screenHeight: screenHeight,
|
| 225 |
+
distance: distance,
|
| 226 |
+
full: full
|
| 227 |
+
});
|
| 228 |
+
*/
|
| 229 |
+
|
| 230 |
+
// If elem bottom is above the screen top and
|
| 231 |
+
// the elem top is below the screen bottom, it's false.
|
| 232 |
+
// If full is specified, it si subtracted or added
|
| 233 |
+
// as needed from the element's height.
|
| 234 |
+
return (!(elem.sonarElemTop + (full ? 0 : elemHeight) < scrollTop - distance) &&
|
| 235 |
+
!(elem.sonarElemTop + (full ? elemHeight : 0) > scrollTop + screenHeight + distance));
|
| 236 |
+
}
|
| 237 |
+
},
|
| 238 |
+
|
| 239 |
+
// Container for elems needing to be polled.
|
| 240 |
+
pollQueue = {},
|
| 241 |
+
|
| 242 |
+
// Indicates if scroll events are bound to the poll.
|
| 243 |
+
pollActive = 0,
|
| 244 |
+
|
| 245 |
+
// Used for debouncing.
|
| 246 |
+
pollId,
|
| 247 |
+
|
| 248 |
+
// Function that handles polling when the user scrolls.
|
| 249 |
+
poll = function(){
|
| 250 |
+
|
| 251 |
+
// Debouncing speed optimization. Essentially prevents
|
| 252 |
+
// poll requests from queue'ing up and overloading
|
| 253 |
+
// the scroll event listener.
|
| 254 |
+
pollId && clearTimeout( pollId );
|
| 255 |
+
pollId = setTimeout(function(){
|
| 256 |
+
|
| 257 |
+
var elem,
|
| 258 |
+
elems,
|
| 259 |
+
screenEvent,
|
| 260 |
+
options,
|
| 261 |
+
detected,
|
| 262 |
+
i, l;
|
| 263 |
+
|
| 264 |
+
for ( screenEvent in pollQueue ) {
|
| 265 |
+
|
| 266 |
+
elems = pollQueue[ screenEvent ];
|
| 267 |
+
|
| 268 |
+
for (i = 0, l = elems.length; i < l; i++) {
|
| 269 |
+
|
| 270 |
+
options = elems[i];
|
| 271 |
+
elem = options.elem;
|
| 272 |
+
|
| 273 |
+
// console.log("Polling " + elem.id);
|
| 274 |
+
|
| 275 |
+
detected = detect( elem, options.px, options.full );
|
| 276 |
+
|
| 277 |
+
// If the elem is not detected (offscreen) or detected (onscreen)
|
| 278 |
+
// remove the elem from the queue and fire the callback.
|
| 279 |
+
if ( screenEvent === offScreenEvent ? !detected : detected ) {
|
| 280 |
+
// // console.log(screenEvent);
|
| 281 |
+
if (!options.tr) {
|
| 282 |
+
|
| 283 |
+
if ( elem[ screenEvent ] ) {
|
| 284 |
+
// console.log("triggered:" + elem.id);
|
| 285 |
+
// Trigger the onscreen or offscreen event depending
|
| 286 |
+
// on the desired event.
|
| 287 |
+
$(elem).trigger( screenEvent );
|
| 288 |
+
|
| 289 |
+
options.tr = 1;
|
| 290 |
+
|
| 291 |
+
// removeSonar was called on this element, clean it up
|
| 292 |
+
// instead of triggering the event.
|
| 293 |
+
} else {
|
| 294 |
+
// console.log("Deleting " + elem.id);
|
| 295 |
+
|
| 296 |
+
// Remove this object from the elem poll container.
|
| 297 |
+
elems.splice(i, 1);
|
| 298 |
+
|
| 299 |
+
// Decrement the counter and length because we just removed
|
| 300 |
+
// one from it.
|
| 301 |
+
i--;
|
| 302 |
+
l--;
|
| 303 |
+
}
|
| 304 |
+
}
|
| 305 |
+
} else {
|
| 306 |
+
options.tr = 0;
|
| 307 |
+
}
|
| 308 |
+
}
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
}, 0 ); // End setTimeout performance tweak.
|
| 312 |
+
},
|
| 313 |
+
|
| 314 |
+
removeSonar = function( elem, screenEvent ){
|
| 315 |
+
// console.log("Removing " + elem.id);
|
| 316 |
+
elem[ screenEvent ] = 0;
|
| 317 |
+
},
|
| 318 |
+
|
| 319 |
+
addSonar = function( elem, options ) {
|
| 320 |
+
// console.log("Really adding " + elem.id);
|
| 321 |
+
// Prepare arguments.
|
| 322 |
+
var distance = options.px,
|
| 323 |
+
full = options.full,
|
| 324 |
+
screenEvent = options.evt,
|
| 325 |
+
parent = win, // Getting ready to accept parents: options.parent || win,
|
| 326 |
+
detected = detect( elem, distance, full /*, parent */ ),
|
| 327 |
+
triggered = 0;
|
| 328 |
+
|
| 329 |
+
elem[ screenEvent ] = 1;
|
| 330 |
+
|
| 331 |
+
// If the elem is not detected (offscreen) or detected (onscreen)
|
| 332 |
+
// trigger the event and fire the callback immediately.
|
| 333 |
+
if ( screenEvent === offScreenEvent ? !detected : detected ) {
|
| 334 |
+
// console.log("Triggering " + elem.id + " " + screenEvent );
|
| 335 |
+
// Trigger the onscreen event at the next possible cycle.
|
| 336 |
+
// Artz: Ask the jQuery team why I needed to do this.
|
| 337 |
+
setTimeout(function(){
|
| 338 |
+
$(elem).trigger( screenEvent === offScreenEvent ? offScreenEvent : onScreenEvent );
|
| 339 |
+
}, 0);
|
| 340 |
+
triggered = 1;
|
| 341 |
+
// Otherwise, add it to the polling queue.
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
// console.log("Adding " + elem.id + " to queue.");
|
| 345 |
+
// Push the element and its callback into the poll queue.
|
| 346 |
+
pollQueue[ screenEvent ].push({
|
| 347 |
+
elem: elem,
|
| 348 |
+
px: distance,
|
| 349 |
+
full: full,
|
| 350 |
+
tr: triggered/* ,
|
| 351 |
+
parent: parent */
|
| 352 |
+
});
|
| 353 |
+
|
| 354 |
+
// Activate the poll if not currently activated.
|
| 355 |
+
if ( !pollActive ) {
|
| 356 |
+
$win.bind( "scroll", poll );
|
| 357 |
+
pollActive = 1;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
|
| 361 |
+
// Call the prepare function if there, used to
|
| 362 |
+
// prepare the element if we detected it.
|
| 363 |
+
// Artz: Not implemented yet...used to preprocess elements in same loop.
|
| 364 |
+
/*
|
| 365 |
+
if ( prepCallback ) {
|
| 366 |
+
prepCallback.call( elem, elem, detected );
|
| 367 |
+
}
|
| 368 |
+
*/
|
| 369 |
+
};
|
| 370 |
+
|
| 371 |
+
// Open sonar function up to the public.
|
| 372 |
+
$.sonar = detect;
|
| 373 |
+
|
| 374 |
+
pollQueue[ onScreenEvent ] = [];
|
| 375 |
+
$.event.special[ onScreenEvent ] = {
|
| 376 |
+
|
| 377 |
+
add: function( handleObj ) {
|
| 378 |
+
var data = handleObj.data || {},
|
| 379 |
+
elem = this;
|
| 380 |
+
|
| 381 |
+
if (!elem[onScreenEvent]){
|
| 382 |
+
addSonar(this, {
|
| 383 |
+
px: data.distance,
|
| 384 |
+
full: data.full,
|
| 385 |
+
evt: onScreenEvent /*,
|
| 386 |
+
parent: data.parent */
|
| 387 |
+
});
|
| 388 |
+
}
|
| 389 |
+
},
|
| 390 |
+
|
| 391 |
+
remove: function( handleObj ) {
|
| 392 |
+
removeSonar( this, onScreenEvent );
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
};
|
| 396 |
+
|
| 397 |
+
pollQueue[ offScreenEvent ] = [];
|
| 398 |
+
$.event.special[ offScreenEvent ] = {
|
| 399 |
+
|
| 400 |
+
add: function( handleObj ) {
|
| 401 |
+
|
| 402 |
+
var data = handleObj.data || {},
|
| 403 |
+
elem = this;
|
| 404 |
+
|
| 405 |
+
if (!elem[offScreenEvent]){
|
| 406 |
+
addSonar(elem, {
|
| 407 |
+
px: data.distance,
|
| 408 |
+
full: data.full,
|
| 409 |
+
evt: offScreenEvent /*,
|
| 410 |
+
parent: data.parent */
|
| 411 |
+
});
|
| 412 |
+
}
|
| 413 |
+
},
|
| 414 |
+
|
| 415 |
+
remove: function( handleObj ) {
|
| 416 |
+
removeSonar( this, offScreenEvent );
|
| 417 |
+
}
|
| 418 |
+
};
|
| 419 |
+
|
| 420 |
+
// console.log(pollQueue);
|
| 421 |
+
})( jQuery, window, document );
|
inc/js/jquery.sonar.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
(function(e,h,l,c){e.fn.sonar=function(o,n){if(typeof o==="boolean"){n=o;o=c}return e.sonar(this[0],o,n)};var f=l.body,a="scrollin",m="scrollout",b=function(r,n,t){if(r){f||(f=l.body);var s=r,u=0,v=f.offsetHeight,o=h.innerHeight||l.documentElement.clientHeight||f.clientHeight||0,q=l.documentElement.scrollTop||h.pageYOffset||f.scrollTop||0,p=r.offsetHeight||0;if(!r.sonarElemTop||r.sonarBodyHeight!==v){if(s.offsetParent){do{u+=s.offsetTop}while(s=s.offsetParent)}r.sonarElemTop=u;r.sonarBodyHeight=v}n=n===c?0:n;return(!(r.sonarElemTop+(t?0:p)<q-n)&&!(r.sonarElemTop+(t?p:0)>q+o+n))}},d={},j=0,i=function(){setTimeout(function(){var s,o,t,q,p,r,n;for(t in d){o=d[t];for(r=0,n=o.length;r<n;r++){q=o[r];s=q.elem;p=b(s,q.px,q.full);if(t===m?!p:p){if(!q.tr){if(s[t]){e(s).trigger(t);q.tr=1}else{o.splice(r,1);r--;n--}}}else{q.tr=0}}}},25)},k=function(n,o){n[o]=0},g=function(r,p){var t=p.px,q=p.full,s=p.evt,o=b(r,t,q),n=0;r[s]=1;if(s===m?!o:o){setTimeout(function(){e(r).trigger(s===m?m:a)},0);n=1}d[s].push({elem:r,px:t,full:q,tr:n});if(!j){e(h).bind("scroll",i);j=1}};e.sonar=b;d[a]=[];e.event.special[a]={add:function(n){var p=n.data||{},o=this;if(!o[a]){g(this,{px:p.distance,full:p.full,evt:a})}},remove:function(n){k(this,a)}};d[m]=[];e.event.special[m]={add:function(n){var p=n.data||{},o=this;if(!o[m]){g(o,{px:p.distance,full:p.full,evt:m})}},remove:function(n){k(this,m)}}})(jQuery,window,document);
|
inc/js/sbp-lazy-load.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
(function($) {
|
| 2 |
+
lazy_load_init();
|
| 3 |
+
$( 'body' ).bind( 'post-load', lazy_load_init ); // Work with WP.com infinite scroll
|
| 4 |
+
|
| 5 |
+
function lazy_load_init() {
|
| 6 |
+
$( 'img[data-lazy-src]' ).bind( 'scrollin', { distance: 200 }, function() {
|
| 7 |
+
sbp_lazy_load_init( this );
|
| 8 |
+
});
|
| 9 |
+
|
| 10 |
+
// We need to force load gallery images in Jetpack Carousel and give up lazy-loading otherwise images don't show up correctly
|
| 11 |
+
$( '[data-carousel-extra]' ).each( function() {
|
| 12 |
+
$( this ).find( 'img[data-lazy-src]' ).each( function() {
|
| 13 |
+
sbp_lazy_load_init( this );
|
| 14 |
+
} );
|
| 15 |
+
} );
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
function sbp_lazy_load_init( img ) {
|
| 19 |
+
var $img = jQuery( img ),
|
| 20 |
+
src = $img.attr( 'data-lazy-src' );
|
| 21 |
+
|
| 22 |
+
$img.unbind( 'scrollin' ) // remove event binding
|
| 23 |
+
.hide()
|
| 24 |
+
.removeAttr( 'data-lazy-src' )
|
| 25 |
+
.attr( 'data-lazy-loaded', 'true' );
|
| 26 |
+
|
| 27 |
+
img.src = src;
|
| 28 |
+
$img.fadeIn();
|
| 29 |
+
}
|
| 30 |
+
})(jQuery);
|
inc/lazy-load.php
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/* Lazy Load v. 0.5 => Lazy load images to improve page load times. Uses jQuery.sonar to only load an image when it's visible in the viewport.
|
| 3 |
+
* http://wordpress.org/plugins/lazy-load/
|
| 4 |
+
* Author & copyright WordPress.com VIP team, TechCrunch 2011 Redesign team, and Jake Goldman (10up LLC).
|
| 5 |
+
* Uses jQuery.sonar by Dave Artz (AOL): http://www.artzstudio.com/files/jquery-boston-2010/jquery.sonar/
|
| 6 |
+
* License: GPL2 */
|
| 7 |
+
|
| 8 |
+
if ( ! class_exists( 'Speed_Booster_Pack_Lazy_Load' ) ) :
|
| 9 |
+
|
| 10 |
+
class Speed_Booster_Pack_Lazy_Load {
|
| 11 |
+
|
| 12 |
+
static function init() {
|
| 13 |
+
if ( is_admin() )
|
| 14 |
+
return;
|
| 15 |
+
|
| 16 |
+
add_filter( 'the_content', array( __CLASS__, 'add_sbp_image_placeholders' ), 99 ); // run this later, so other content filters have run, including image_add_wh on WP.com
|
| 17 |
+
add_filter( 'post_thumbnail_html', array( __CLASS__, 'add_sbp_image_placeholders' ), 11 );
|
| 18 |
+
add_filter( 'get_avatar', array( __CLASS__, 'add_sbp_image_placeholders' ), 11 );
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
static function add_sbp_image_placeholders( $content ) {
|
| 24 |
+
// Don't lazyload for feeds, previews, mobile
|
| 25 |
+
if( is_feed() || is_preview() || ( function_exists( 'is_mobile' ) && is_mobile() ) )
|
| 26 |
+
return $content;
|
| 27 |
+
|
| 28 |
+
// Don't lazy-load if the content has already been run through previously
|
| 29 |
+
if ( false !== strpos( $content, 'data-lazy-src' ) )
|
| 30 |
+
return $content;
|
| 31 |
+
|
| 32 |
+
// In case you want to change the placeholder image
|
| 33 |
+
$sbp_placeholder_image = apply_filters( 'lazyload_images_placeholder_image', self::get_url( 'images/1x1.trans.gif' ) );
|
| 34 |
+
|
| 35 |
+
// This is a pretty simple regex, but it works
|
| 36 |
+
$content = preg_replace( '#<img([^>]+?)src=[\'"]?([^\'"\s>]+)[\'"]?([^>]*)>#', sprintf( '<img${1}src="%s" data-lazy-src="${2}"${3}><noscript><img${1}src="${2}"${3}></noscript>', $sbp_placeholder_image ), $content );
|
| 37 |
+
|
| 38 |
+
return $content;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
static function get_url( $path = '' ) {
|
| 42 |
+
return plugins_url( ltrim( $path, '/' ), __FILE__ );
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
function sbp_lazyload_images_add_placeholders( $content ) {
|
| 47 |
+
return Speed_Booster_Pack_Lazy_Load::add_sbp_image_placeholders( $content );
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
Speed_Booster_Pack_Lazy_Load::init();
|
| 51 |
+
|
| 52 |
+
endif;
|
inc/template/options.php
CHANGED
|
@@ -45,6 +45,11 @@
|
|
| 45 |
<label for="sbp_settings[font_awesome]"><?php _e( 'Removes additional Font Awesome stylesheets', 'sb-pack' ); ?></label>
|
| 46 |
</p>
|
| 47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
</div> <!-- END welcome-panel-column -->
|
| 49 |
|
| 50 |
|
| 45 |
<label for="sbp_settings[font_awesome]"><?php _e( 'Removes additional Font Awesome stylesheets', 'sb-pack' ); ?></label>
|
| 46 |
</p>
|
| 47 |
|
| 48 |
+
<p>
|
| 49 |
+
<input id="sbp_settings[lazy_load]" name="sbp_settings[lazy_load]" type="checkbox" value="1" <?php checked( 1, isset( $sbp_options['lazy_load'] ) ); ?> />
|
| 50 |
+
<label for="sbp_settings[lazy_load]"><?php _e( 'Lazy load images to improve page load times', 'sb-pack' ); ?></label>
|
| 51 |
+
</p>
|
| 52 |
+
|
| 53 |
</div> <!-- END welcome-panel-column -->
|
| 54 |
|
| 55 |
|
js/jquery.sonar.js
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
An elem for determining if an elem is within a certain
|
| 3 |
+
distance from the edge above or below the screen, and attaching
|
| 4 |
+
a function to execute once the elem is in view.
|
| 5 |
+
|
| 6 |
+
General Usage:
|
| 7 |
+
|
| 8 |
+
* Place the library anywhere in your JavaScript code before you
|
| 9 |
+
intend to call the function.
|
| 10 |
+
|
| 11 |
+
* To initialize Sonar with a different default distance, modify
|
| 12 |
+
the sonar = Sonar() line immediately following the Sonar
|
| 13 |
+
library definition. Example:
|
| 14 |
+
|
| 15 |
+
sonar=Sonar(100); // Initializes Sonar with a 100px default distance.
|
| 16 |
+
|
| 17 |
+
Note:
|
| 18 |
+
|
| 19 |
+
* The default distance is 0 pixels.
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
sonar.detect() Usage
|
| 23 |
+
|
| 24 |
+
* Use sonar.detect(elem, distance) to check if the
|
| 25 |
+
elem is within screen boundaries.
|
| 26 |
+
|
| 27 |
+
@elem - The elem you want to detect visibility.
|
| 28 |
+
@distance - The distance from the screen edge that should
|
| 29 |
+
count in the check. Uses default distance if not specified.
|
| 30 |
+
|
| 31 |
+
* Note: sonar.detect() adds a property to
|
| 32 |
+
ojbects called sonarElemTop. Test to ensure there
|
| 33 |
+
aren't any conflicts with your code. If there
|
| 34 |
+
are, rename sonarElemTop to something else in the code.
|
| 35 |
+
|
| 36 |
+
* sonar.detect() returns:
|
| 37 |
+
true if the elem is within the screen boundaries
|
| 38 |
+
false if th elem is out of the screen boundaries
|
| 39 |
+
|
| 40 |
+
Example:
|
| 41 |
+
|
| 42 |
+
Here's how to check if an advertisment is visible on a
|
| 43 |
+
page that has the id, "ad".
|
| 44 |
+
|
| 45 |
+
if (sonar.detect(document.getElementById("ad")))
|
| 46 |
+
{
|
| 47 |
+
alert('The ad is visible on screen!');
|
| 48 |
+
}
|
| 49 |
+
else
|
| 50 |
+
{
|
| 51 |
+
alert ('The ad is not on screen!);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
sonar.add() Usage
|
| 55 |
+
|
| 56 |
+
* This method stores elems that are then polled
|
| 57 |
+
on user scroll by the Sonar.detect() method.
|
| 58 |
+
|
| 59 |
+
* Polling initializes once the sonar.add() method is passed
|
| 60 |
+
an elem with the following properties:
|
| 61 |
+
|
| 62 |
+
obj : A reference to the elem to observe until it is within
|
| 63 |
+
the specified distance (px).
|
| 64 |
+
|
| 65 |
+
id : An alternative to the obj parameter, an "id" can be used
|
| 66 |
+
to grab the elem to observe.
|
| 67 |
+
|
| 68 |
+
call: The function to call when the elem is within the
|
| 69 |
+
specified distance (px). The @elem argument will
|
| 70 |
+
include the elem that triggered the callback.
|
| 71 |
+
|
| 72 |
+
px : The specified distance to include as being visible on
|
| 73 |
+
screen. This property is optional (default is 0).
|
| 74 |
+
|
| 75 |
+
Example:
|
| 76 |
+
|
| 77 |
+
sonar.add(
|
| 78 |
+
{
|
| 79 |
+
obj: document.getElementById("0026-get-out-the-way"),
|
| 80 |
+
call: function(elem) // elem will include the elem that triggered the function.
|
| 81 |
+
{
|
| 82 |
+
swfelem.embedSWF("../player.swf", "0026-get-out-the-way", "640", "500", "9.0.0",
|
| 83 |
+
{}, {file: "0026-get-out-the-way.flv", fullscreen: true},
|
| 84 |
+
{allowfullscreen: true, allowscriptaccess: "always"});
|
| 85 |
+
},
|
| 86 |
+
px: 400
|
| 87 |
+
});
|
| 88 |
+
|
| 89 |
+
You can also specify an id tag to be grabbed instead of the elem:
|
| 90 |
+
|
| 91 |
+
sonar.add(
|
| 92 |
+
{
|
| 93 |
+
id: "0026-get-out-the-way",
|
| 94 |
+
call: function(elem) // elem will include the elem that triggered the function.
|
| 95 |
+
{
|
| 96 |
+
swfelem.embedSWF("../player.swf", "0026-get-out-the-way", "640", "500", "9.0.0",
|
| 97 |
+
{}, {file: "0026-get-out-the-way.flv", fullscreen: true},
|
| 98 |
+
{allowfullscreen: true, allowscriptaccess: "always"});
|
| 99 |
+
},
|
| 100 |
+
px: 400
|
| 101 |
+
});
|
| 102 |
+
|
| 103 |
+
Notes:
|
| 104 |
+
|
| 105 |
+
* Setting the body or html of your page to 100% will cause sonar to have
|
| 106 |
+
an invalid height calculation in Firefox. It is recommended that you
|
| 107 |
+
do not set this CSS property.
|
| 108 |
+
|
| 109 |
+
Example:
|
| 110 |
+
|
| 111 |
+
html, body {
|
| 112 |
+
height:100%; // Do not do this.
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
* If you want to set the default distance to something other
|
| 116 |
+
than 0, either update the property directly in the code or
|
| 117 |
+
you can do this:
|
| 118 |
+
|
| 119 |
+
sonar.blip.d = 100; // Where 100 = 100 pixels above and below the screen edge.
|
| 120 |
+
|
| 121 |
+
* Sleep well at night knowing Sonar automatically cleans up the
|
| 122 |
+
event listeners on the scroll event once all calls have executed.
|
| 123 |
+
|
| 124 |
+
Code History:
|
| 125 |
+
|
| 126 |
+
v3 :: 8/14/2009 - David Artz (david.artz@corp.aol.com)
|
| 127 |
+
* Fixed a bug in the polling code where splicing caused our
|
| 128 |
+
for loop to skip over the next iteration in the loop. This
|
| 129 |
+
caused some images in the poll to be detected when they
|
| 130 |
+
should have been.
|
| 131 |
+
* Re-factored Sonar to use the "Module" JavaScript library
|
| 132 |
+
pattern, making our private variables and functions more
|
| 133 |
+
private and inaccessible from the public interface.
|
| 134 |
+
* Updated the sonar.add() function to return true or false,
|
| 135 |
+
useful for determining if Sonar added the elem to the
|
| 136 |
+
poll or executed its callback immediately.
|
| 137 |
+
|
| 138 |
+
v2 :: 3/24/2009 - David Artz (david.artz@corp.aol.com)
|
| 139 |
+
* Added support for IE 8.
|
| 140 |
+
* Updated the way scroll top and screen height are detected, now
|
| 141 |
+
works in IE/FF/Safari quirks mode.
|
| 142 |
+
* Added null check for IE, it was polling for an elem that had recently
|
| 143 |
+
been spliced out of the array. Nasty.
|
| 144 |
+
* Modified for loop to use standard syntax. for (i in x) is known to be
|
| 145 |
+
buggy with JS frameworks that override arrays.
|
| 146 |
+
* Added sonar.b property to cache the body element (improving lookup time).
|
| 147 |
+
|
| 148 |
+
v1 :: 11/18/2008 - David Artz (david.artz@corp.aol.com)
|
| 149 |
+
* Officially released code for general use.
|
| 150 |
+
|
| 151 |
+
*/
|
| 152 |
+
|
| 153 |
+
(function( $, win, doc, undefined ){
|
| 154 |
+
|
| 155 |
+
$.fn.sonar = function( distance, full ){
|
| 156 |
+
// No callbacks, return the results from Sonar for
|
| 157 |
+
// the first element in the stack.
|
| 158 |
+
if ( typeof distance === "boolean" ) {
|
| 159 |
+
full = distance;
|
| 160 |
+
distance = undefined;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
return $.sonar( this[0], distance, full );
|
| 164 |
+
};
|
| 165 |
+
|
| 166 |
+
var body = doc.body,
|
| 167 |
+
$win = $(win),
|
| 168 |
+
|
| 169 |
+
onScreenEvent = "scrollin",
|
| 170 |
+
offScreenEvent = "scrollout",
|
| 171 |
+
|
| 172 |
+
detect = function( elem, distance, full ){
|
| 173 |
+
|
| 174 |
+
if ( elem ) {
|
| 175 |
+
|
| 176 |
+
// Cache the body elem in our private global.
|
| 177 |
+
body || ( body = doc.body );
|
| 178 |
+
|
| 179 |
+
var parentElem = elem, // Clone the elem for use in our loop.
|
| 180 |
+
|
| 181 |
+
elemTop = 0, // The resets the calculated elem top to 0.
|
| 182 |
+
|
| 183 |
+
// Used to recalculate elem.sonarElemTop if body height changes.
|
| 184 |
+
bodyHeight = body.offsetHeight,
|
| 185 |
+
|
| 186 |
+
// NCZ: I don't think you need innerHeight, I believe all major browsers support clientHeight.
|
| 187 |
+
screenHeight = win.innerHeight || doc.documentElement.clientHeight || body.clientHeight || 0, // Height of the screen.
|
| 188 |
+
|
| 189 |
+
// NCZ: I don't think you need pageYOffset, I believe all major browsers support scrollTop.
|
| 190 |
+
scrollTop = doc.documentElement.scrollTop || win.pageYOffset || body.scrollTop || 0, // How far the user scrolled down.
|
| 191 |
+
elemHeight = elem.offsetHeight || 0; // Height of the element.
|
| 192 |
+
|
| 193 |
+
// If our custom "sonarTop" variable is undefined, or the document body
|
| 194 |
+
// height has changed since the last time we ran sonar.detect()...
|
| 195 |
+
if ( !elem.sonarElemTop || elem.sonarBodyHeight !== bodyHeight ) {
|
| 196 |
+
|
| 197 |
+
// Loop through the offsetParents to calculate it.
|
| 198 |
+
if ( parentElem.offsetParent ) {
|
| 199 |
+
do {
|
| 200 |
+
elemTop += parentElem.offsetTop;
|
| 201 |
+
}
|
| 202 |
+
while ( parentElem = parentElem.offsetParent );
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
// Set the custom property (sonarTop) to avoid future attempts to calculate
|
| 206 |
+
// the distance on this elem from the top of the page.
|
| 207 |
+
elem.sonarElemTop = elemTop;
|
| 208 |
+
|
| 209 |
+
// Along the same lines, store the body height when we calculated
|
| 210 |
+
// the elem's top.
|
| 211 |
+
elem.sonarBodyHeight = bodyHeight;
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
// If no distance was given, assume 0.
|
| 215 |
+
distance = distance === undefined ? 0 : distance;
|
| 216 |
+
|
| 217 |
+
// Dump all calculated variables.
|
| 218 |
+
/*
|
| 219 |
+
console.dir({
|
| 220 |
+
elem: elem,
|
| 221 |
+
sonarElemTop: elem.sonarElemTop,
|
| 222 |
+
elemHeight: elemHeight,
|
| 223 |
+
scrollTop: scrollTop,
|
| 224 |
+
screenHeight: screenHeight,
|
| 225 |
+
distance: distance,
|
| 226 |
+
full: full
|
| 227 |
+
});
|
| 228 |
+
*/
|
| 229 |
+
|
| 230 |
+
// If elem bottom is above the screen top and
|
| 231 |
+
// the elem top is below the screen bottom, it's false.
|
| 232 |
+
// If full is specified, it si subtracted or added
|
| 233 |
+
// as needed from the element's height.
|
| 234 |
+
return (!(elem.sonarElemTop + (full ? 0 : elemHeight) < scrollTop - distance) &&
|
| 235 |
+
!(elem.sonarElemTop + (full ? elemHeight : 0) > scrollTop + screenHeight + distance));
|
| 236 |
+
}
|
| 237 |
+
},
|
| 238 |
+
|
| 239 |
+
// Container for elems needing to be polled.
|
| 240 |
+
pollQueue = {},
|
| 241 |
+
|
| 242 |
+
// Indicates if scroll events are bound to the poll.
|
| 243 |
+
pollActive = 0,
|
| 244 |
+
|
| 245 |
+
// Used for debouncing.
|
| 246 |
+
pollId,
|
| 247 |
+
|
| 248 |
+
// Function that handles polling when the user scrolls.
|
| 249 |
+
poll = function(){
|
| 250 |
+
|
| 251 |
+
// Debouncing speed optimization. Essentially prevents
|
| 252 |
+
// poll requests from queue'ing up and overloading
|
| 253 |
+
// the scroll event listener.
|
| 254 |
+
pollId && clearTimeout( pollId );
|
| 255 |
+
pollId = setTimeout(function(){
|
| 256 |
+
|
| 257 |
+
var elem,
|
| 258 |
+
elems,
|
| 259 |
+
screenEvent,
|
| 260 |
+
options,
|
| 261 |
+
detected,
|
| 262 |
+
i, l;
|
| 263 |
+
|
| 264 |
+
for ( screenEvent in pollQueue ) {
|
| 265 |
+
|
| 266 |
+
elems = pollQueue[ screenEvent ];
|
| 267 |
+
|
| 268 |
+
for (i = 0, l = elems.length; i < l; i++) {
|
| 269 |
+
|
| 270 |
+
options = elems[i];
|
| 271 |
+
elem = options.elem;
|
| 272 |
+
|
| 273 |
+
// console.log("Polling " + elem.id);
|
| 274 |
+
|
| 275 |
+
detected = detect( elem, options.px, options.full );
|
| 276 |
+
|
| 277 |
+
// If the elem is not detected (offscreen) or detected (onscreen)
|
| 278 |
+
// remove the elem from the queue and fire the callback.
|
| 279 |
+
if ( screenEvent === offScreenEvent ? !detected : detected ) {
|
| 280 |
+
// // console.log(screenEvent);
|
| 281 |
+
if (!options.tr) {
|
| 282 |
+
|
| 283 |
+
if ( elem[ screenEvent ] ) {
|
| 284 |
+
// console.log("triggered:" + elem.id);
|
| 285 |
+
// Trigger the onscreen or offscreen event depending
|
| 286 |
+
// on the desired event.
|
| 287 |
+
$(elem).trigger( screenEvent );
|
| 288 |
+
|
| 289 |
+
options.tr = 1;
|
| 290 |
+
|
| 291 |
+
// removeSonar was called on this element, clean it up
|
| 292 |
+
// instead of triggering the event.
|
| 293 |
+
} else {
|
| 294 |
+
// console.log("Deleting " + elem.id);
|
| 295 |
+
|
| 296 |
+
// Remove this object from the elem poll container.
|
| 297 |
+
elems.splice(i, 1);
|
| 298 |
+
|
| 299 |
+
// Decrement the counter and length because we just removed
|
| 300 |
+
// one from it.
|
| 301 |
+
i--;
|
| 302 |
+
l--;
|
| 303 |
+
}
|
| 304 |
+
}
|
| 305 |
+
} else {
|
| 306 |
+
options.tr = 0;
|
| 307 |
+
}
|
| 308 |
+
}
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
}, 0 ); // End setTimeout performance tweak.
|
| 312 |
+
},
|
| 313 |
+
|
| 314 |
+
removeSonar = function( elem, screenEvent ){
|
| 315 |
+
// console.log("Removing " + elem.id);
|
| 316 |
+
elem[ screenEvent ] = 0;
|
| 317 |
+
},
|
| 318 |
+
|
| 319 |
+
addSonar = function( elem, options ) {
|
| 320 |
+
// console.log("Really adding " + elem.id);
|
| 321 |
+
// Prepare arguments.
|
| 322 |
+
var distance = options.px,
|
| 323 |
+
full = options.full,
|
| 324 |
+
screenEvent = options.evt,
|
| 325 |
+
parent = win, // Getting ready to accept parents: options.parent || win,
|
| 326 |
+
detected = detect( elem, distance, full /*, parent */ ),
|
| 327 |
+
triggered = 0;
|
| 328 |
+
|
| 329 |
+
elem[ screenEvent ] = 1;
|
| 330 |
+
|
| 331 |
+
// If the elem is not detected (offscreen) or detected (onscreen)
|
| 332 |
+
// trigger the event and fire the callback immediately.
|
| 333 |
+
if ( screenEvent === offScreenEvent ? !detected : detected ) {
|
| 334 |
+
// console.log("Triggering " + elem.id + " " + screenEvent );
|
| 335 |
+
// Trigger the onscreen event at the next possible cycle.
|
| 336 |
+
// Artz: Ask the jQuery team why I needed to do this.
|
| 337 |
+
setTimeout(function(){
|
| 338 |
+
$(elem).trigger( screenEvent === offScreenEvent ? offScreenEvent : onScreenEvent );
|
| 339 |
+
}, 0);
|
| 340 |
+
triggered = 1;
|
| 341 |
+
// Otherwise, add it to the polling queue.
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
// console.log("Adding " + elem.id + " to queue.");
|
| 345 |
+
// Push the element and its callback into the poll queue.
|
| 346 |
+
pollQueue[ screenEvent ].push({
|
| 347 |
+
elem: elem,
|
| 348 |
+
px: distance,
|
| 349 |
+
full: full,
|
| 350 |
+
tr: triggered/* ,
|
| 351 |
+
parent: parent */
|
| 352 |
+
});
|
| 353 |
+
|
| 354 |
+
// Activate the poll if not currently activated.
|
| 355 |
+
if ( !pollActive ) {
|
| 356 |
+
$win.bind( "scroll", poll );
|
| 357 |
+
pollActive = 1;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
|
| 361 |
+
// Call the prepare function if there, used to
|
| 362 |
+
// prepare the element if we detected it.
|
| 363 |
+
// Artz: Not implemented yet...used to preprocess elements in same loop.
|
| 364 |
+
/*
|
| 365 |
+
if ( prepCallback ) {
|
| 366 |
+
prepCallback.call( elem, elem, detected );
|
| 367 |
+
}
|
| 368 |
+
*/
|
| 369 |
+
};
|
| 370 |
+
|
| 371 |
+
// Open sonar function up to the public.
|
| 372 |
+
$.sonar = detect;
|
| 373 |
+
|
| 374 |
+
pollQueue[ onScreenEvent ] = [];
|
| 375 |
+
$.event.special[ onScreenEvent ] = {
|
| 376 |
+
|
| 377 |
+
add: function( handleObj ) {
|
| 378 |
+
var data = handleObj.data || {},
|
| 379 |
+
elem = this;
|
| 380 |
+
|
| 381 |
+
if (!elem[onScreenEvent]){
|
| 382 |
+
addSonar(this, {
|
| 383 |
+
px: data.distance,
|
| 384 |
+
full: data.full,
|
| 385 |
+
evt: onScreenEvent /*,
|
| 386 |
+
parent: data.parent */
|
| 387 |
+
});
|
| 388 |
+
}
|
| 389 |
+
},
|
| 390 |
+
|
| 391 |
+
remove: function( handleObj ) {
|
| 392 |
+
removeSonar( this, onScreenEvent );
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
};
|
| 396 |
+
|
| 397 |
+
pollQueue[ offScreenEvent ] = [];
|
| 398 |
+
$.event.special[ offScreenEvent ] = {
|
| 399 |
+
|
| 400 |
+
add: function( handleObj ) {
|
| 401 |
+
|
| 402 |
+
var data = handleObj.data || {},
|
| 403 |
+
elem = this;
|
| 404 |
+
|
| 405 |
+
if (!elem[offScreenEvent]){
|
| 406 |
+
addSonar(elem, {
|
| 407 |
+
px: data.distance,
|
| 408 |
+
full: data.full,
|
| 409 |
+
evt: offScreenEvent /*,
|
| 410 |
+
parent: data.parent */
|
| 411 |
+
});
|
| 412 |
+
}
|
| 413 |
+
},
|
| 414 |
+
|
| 415 |
+
remove: function( handleObj ) {
|
| 416 |
+
removeSonar( this, offScreenEvent );
|
| 417 |
+
}
|
| 418 |
+
};
|
| 419 |
+
|
| 420 |
+
// console.log(pollQueue);
|
| 421 |
+
})( jQuery, window, document );
|
js/jquery.sonar.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
(function(e,h,l,c){e.fn.sonar=function(o,n){if(typeof o==="boolean"){n=o;o=c}return e.sonar(this[0],o,n)};var f=l.body,a="scrollin",m="scrollout",b=function(r,n,t){if(r){f||(f=l.body);var s=r,u=0,v=f.offsetHeight,o=h.innerHeight||l.documentElement.clientHeight||f.clientHeight||0,q=l.documentElement.scrollTop||h.pageYOffset||f.scrollTop||0,p=r.offsetHeight||0;if(!r.sonarElemTop||r.sonarBodyHeight!==v){if(s.offsetParent){do{u+=s.offsetTop}while(s=s.offsetParent)}r.sonarElemTop=u;r.sonarBodyHeight=v}n=n===c?0:n;return(!(r.sonarElemTop+(t?0:p)<q-n)&&!(r.sonarElemTop+(t?p:0)>q+o+n))}},d={},j=0,i=function(){setTimeout(function(){var s,o,t,q,p,r,n;for(t in d){o=d[t];for(r=0,n=o.length;r<n;r++){q=o[r];s=q.elem;p=b(s,q.px,q.full);if(t===m?!p:p){if(!q.tr){if(s[t]){e(s).trigger(t);q.tr=1}else{o.splice(r,1);r--;n--}}}else{q.tr=0}}}},25)},k=function(n,o){n[o]=0},g=function(r,p){var t=p.px,q=p.full,s=p.evt,o=b(r,t,q),n=0;r[s]=1;if(s===m?!o:o){setTimeout(function(){e(r).trigger(s===m?m:a)},0);n=1}d[s].push({elem:r,px:t,full:q,tr:n});if(!j){e(h).bind("scroll",i);j=1}};e.sonar=b;d[a]=[];e.event.special[a]={add:function(n){var p=n.data||{},o=this;if(!o[a]){g(this,{px:p.distance,full:p.full,evt:a})}},remove:function(n){k(this,a)}};d[m]=[];e.event.special[m]={add:function(n){var p=n.data||{},o=this;if(!o[m]){g(o,{px:p.distance,full:p.full,evt:m})}},remove:function(n){k(this,m)}}})(jQuery,window,document);
|
js/sbp-lazy-load.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
(function($) {
|
| 2 |
+
lazy_load_init();
|
| 3 |
+
$( 'body' ).bind( 'post-load', lazy_load_init ); // Work with WP.com infinite scroll
|
| 4 |
+
|
| 5 |
+
function lazy_load_init() {
|
| 6 |
+
$( 'img[data-lazy-src]' ).bind( 'scrollin', { distance: 200 }, function() {
|
| 7 |
+
sbp_lazy_load_init( this );
|
| 8 |
+
});
|
| 9 |
+
|
| 10 |
+
// We need to force load gallery images in Jetpack Carousel and give up lazy-loading otherwise images don't show up correctly
|
| 11 |
+
$( '[data-carousel-extra]' ).each( function() {
|
| 12 |
+
$( this ).find( 'img[data-lazy-src]' ).each( function() {
|
| 13 |
+
sbp_lazy_load_init( this );
|
| 14 |
+
} );
|
| 15 |
+
} );
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
function sbp_lazy_load_init( img ) {
|
| 19 |
+
var $img = jQuery( img ),
|
| 20 |
+
src = $img.attr( 'data-lazy-src' );
|
| 21 |
+
|
| 22 |
+
$img.unbind( 'scrollin' ) // remove event binding
|
| 23 |
+
.hide()
|
| 24 |
+
.removeAttr( 'data-lazy-src' )
|
| 25 |
+
.attr( 'data-lazy-loaded', 'true' );
|
| 26 |
+
|
| 27 |
+
img.src = src;
|
| 28 |
+
$img.fadeIn();
|
| 29 |
+
}
|
| 30 |
+
})(jQuery);
|
readme.txt
CHANGED
|
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
|
| 4 |
Tags: speed, optimization, performance, speed booster, scripts to the footer, Google Libraries, CDN, defer parsing of javascript, remove query strings, GTmetrix, Google PageSpeed, YSlow
|
| 5 |
Requires at least: 3.6
|
| 6 |
Tested up to: 3.9.1
|
| 7 |
-
Stable tag: 1.
|
| 8 |
License: GPLv2 or later
|
| 9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 10 |
|
|
@@ -29,6 +29,7 @@ When visitors lands on your site for the first time, you only have 3 seconds to
|
|
| 29 |
* **Loads javascript files from Google Libraries** rather than serving them from your WordPress install directly, to reduce latency, increase parallelism and improve caching.
|
| 30 |
* **Defers parsing of javascript files** to reduce the initial load time of your page.
|
| 31 |
* **Removes query strings from static resources** to improve your speed scores.
|
|
|
|
| 32 |
* **Removes extra Font Awesome stylesheets** added to your theme by certain plugins, if *Font Awesome* is already used in your theme.
|
| 33 |
* **Removes junk header tags** to clean up your WordPress Header.
|
| 34 |
|
|
@@ -48,11 +49,12 @@ Page Load Stats is a brief statistic displayed in the plugin options page. It di
|
|
| 48 |
* *orange* if there were between 100 and 200 queries
|
| 49 |
* *red* if the page required more than 200 queries
|
| 50 |
|
| 51 |
-
|
| 52 |
= Other Notes =
|
| 53 |
|
| 54 |
* For complete usage instructions visit [Plugin Documentation](http://tiguandesign.com/docs/speed-booster/)
|
| 55 |
* Thanks to [Jason Penney](http://jasonpenney.net/) for Google Libraries feature.
|
|
|
|
|
|
|
| 56 |
|
| 57 |
== Installation ==
|
| 58 |
|
|
@@ -67,8 +69,14 @@ Page Load Stats is a brief statistic displayed in the plugin options page. It di
|
|
| 67 |
|
| 68 |
== Changelog ==
|
| 69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
= 1.4 =
|
| 71 |
-
* Added
|
|
|
|
| 72 |
|
| 73 |
= 1.3 =
|
| 74 |
* Fixed strict standards error: redefining already defined constructor for class.
|
| 4 |
Tags: speed, optimization, performance, speed booster, scripts to the footer, Google Libraries, CDN, defer parsing of javascript, remove query strings, GTmetrix, Google PageSpeed, YSlow
|
| 5 |
Requires at least: 3.6
|
| 6 |
Tested up to: 3.9.1
|
| 7 |
+
Stable tag: 1.5
|
| 8 |
License: GPLv2 or later
|
| 9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 10 |
|
| 29 |
* **Loads javascript files from Google Libraries** rather than serving them from your WordPress install directly, to reduce latency, increase parallelism and improve caching.
|
| 30 |
* **Defers parsing of javascript files** to reduce the initial load time of your page.
|
| 31 |
* **Removes query strings from static resources** to improve your speed scores.
|
| 32 |
+
* **Lazy load images** to improve page load times and save bandwidth.
|
| 33 |
* **Removes extra Font Awesome stylesheets** added to your theme by certain plugins, if *Font Awesome* is already used in your theme.
|
| 34 |
* **Removes junk header tags** to clean up your WordPress Header.
|
| 35 |
|
| 49 |
* *orange* if there were between 100 and 200 queries
|
| 50 |
* *red* if the page required more than 200 queries
|
| 51 |
|
|
|
|
| 52 |
= Other Notes =
|
| 53 |
|
| 54 |
* For complete usage instructions visit [Plugin Documentation](http://tiguandesign.com/docs/speed-booster/)
|
| 55 |
* Thanks to [Jason Penney](http://jasonpenney.net/) for Google Libraries feature.
|
| 56 |
+
* Credits for Lazy Load feature belongs to: WordPress.com VIP team at Automattic, the TechCrunch 2011 Redesign team, and Jake Goldman (10up LLC).
|
| 57 |
+
* Uses [jQuery.sonar](http://www.artzstudio.com/files/jquery-boston-2010/jquery.sonar/) by Dave Artz (AOL).
|
| 58 |
|
| 59 |
== Installation ==
|
| 60 |
|
| 69 |
|
| 70 |
== Changelog ==
|
| 71 |
|
| 72 |
+
= 1.5 =
|
| 73 |
+
* Added Lazy Load feature to improve the web page loading times of your images.
|
| 74 |
+
* Added an option to remove all rss feed links from WP Head.
|
| 75 |
+
* Added plugin options informations to the footer, visible in page source, useful for debugging.
|
| 76 |
+
|
| 77 |
= 1.4 =
|
| 78 |
+
* Added a new option to remove extra Font Awesome stylesheets added to your theme by certain plugins, if Font Awesome is already used in your theme.
|
| 79 |
+
* Added a new option to remove WordPress Version Number.
|
| 80 |
|
| 81 |
= 1.3 =
|
| 82 |
* Fixed strict standards error: redefining already defined constructor for class.
|
speed-booster-pack.php
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
* Plugin Name: Speed Booster Pack
|
| 4 |
-
* Plugin URI: http://
|
| 5 |
* Description: Speed Booster Pack allows you to improve your page loading speed and get a higher score on the major speed testing services such as <a href="http://gtmetrix.com/">GTmetrix</a>, <a href="http://developers.google.com/speed/pagespeed/insights/">Google PageSpeed</a> or other speed testing tools.
|
| 6 |
-
* Version: 1.
|
| 7 |
* Author: Tiguan
|
| 8 |
-
* Author URI: http://
|
| 9 |
* License: GPLv2
|
| 10 |
*/
|
| 11 |
|
|
@@ -38,7 +38,7 @@ $sbp_options = get_option( 'sbp_settings', 'checked' ); // retrieve the plugin s
|
|
| 38 |
|
| 39 |
define( 'SPEED_BOOSTER_PACK_RELEASE_DATE', date_i18n( 'F j, Y', '1400569200' ) ); // Defining plugin release date
|
| 40 |
define( 'SPEED_BOOSTER_PACK_PATH', plugin_dir_path( __FILE__ ) ); // Defining plugin dir path
|
| 41 |
-
define( 'SPEED_BOOSTER_PACK_VERSION', 'v1.
|
| 42 |
|
| 43 |
|
| 44 |
/*----------------------------------------------
|
|
@@ -70,6 +70,9 @@ define( 'SPEED_BOOSTER_PACK_VERSION', 'v1.4'); // Defining plugin versi
|
|
| 70 |
// Enqueue admin style
|
| 71 |
add_action( 'admin_enqueue_scripts', array( $this, 'sbp_enqueue_styles' ) );
|
| 72 |
|
|
|
|
|
|
|
|
|
|
| 73 |
// Filters
|
| 74 |
$this->path = plugin_basename( __FILE__ );
|
| 75 |
add_filter( "plugin_action_links_$this->path", array( $this, 'sbp_settings_link' ) );
|
|
@@ -121,6 +124,19 @@ define( 'SPEED_BOOSTER_PACK_VERSION', 'v1.4'); // Defining plugin versi
|
|
| 121 |
} // End function sbp_enqueue_styles
|
| 122 |
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
/*----------------------------------------------
|
| 125 |
Add settings link on plugins page
|
| 126 |
----------------------------------------------*/
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
* Plugin Name: Speed Booster Pack
|
| 4 |
+
* Plugin URI: http://wordpress.org/plugins/speed-booster-pack/
|
| 5 |
* Description: Speed Booster Pack allows you to improve your page loading speed and get a higher score on the major speed testing services such as <a href="http://gtmetrix.com/">GTmetrix</a>, <a href="http://developers.google.com/speed/pagespeed/insights/">Google PageSpeed</a> or other speed testing tools.
|
| 6 |
+
* Version: 1.5
|
| 7 |
* Author: Tiguan
|
| 8 |
+
* Author URI: http://tiguandesign.com
|
| 9 |
* License: GPLv2
|
| 10 |
*/
|
| 11 |
|
| 38 |
|
| 39 |
define( 'SPEED_BOOSTER_PACK_RELEASE_DATE', date_i18n( 'F j, Y', '1400569200' ) ); // Defining plugin release date
|
| 40 |
define( 'SPEED_BOOSTER_PACK_PATH', plugin_dir_path( __FILE__ ) ); // Defining plugin dir path
|
| 41 |
+
define( 'SPEED_BOOSTER_PACK_VERSION', 'v1.5'); // Defining plugin version
|
| 42 |
|
| 43 |
|
| 44 |
/*----------------------------------------------
|
| 70 |
// Enqueue admin style
|
| 71 |
add_action( 'admin_enqueue_scripts', array( $this, 'sbp_enqueue_styles' ) );
|
| 72 |
|
| 73 |
+
// Enqueue frontend scripts
|
| 74 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'sbp_enqueue_scripts' ) );
|
| 75 |
+
|
| 76 |
// Filters
|
| 77 |
$this->path = plugin_basename( __FILE__ );
|
| 78 |
add_filter( "plugin_action_links_$this->path", array( $this, 'sbp_settings_link' ) );
|
| 124 |
} // End function sbp_enqueue_styles
|
| 125 |
|
| 126 |
|
| 127 |
+
/*----------------------------------------------
|
| 128 |
+
Enqueue Lazy Load scripts
|
| 129 |
+
----------------------------------------------*/
|
| 130 |
+
|
| 131 |
+
static function sbp_enqueue_scripts() {
|
| 132 |
+
|
| 133 |
+
if ( !is_admin() and isset( $sbp_options['lazy_load'] ) ) {
|
| 134 |
+
|
| 135 |
+
wp_enqueue_script( 'sbp-lazy-load-images', plugin_dir_url( __FILE__ ) . 'js/sbp-lazy-load.js', array( 'jquery', 'sbp-jquery-sonar' ), SPEED_BOOSTER_PACK_VERSION, true );
|
| 136 |
+
wp_enqueue_script( 'sbp-jquery-sonar', plugin_dir_url( __FILE__ ) . 'js/jquery.sonar.min.js', array( 'jquery' ), SPEED_BOOSTER_PACK_VERSION, true );
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
/*----------------------------------------------
|
| 141 |
Add settings link on plugins page
|
| 142 |
----------------------------------------------*/
|
