Skip to content

Commit 101ce20

Browse files
committed
Added video support.
1 parent 0f6818b commit 101ce20

File tree

7 files changed

+145
-50
lines changed

7 files changed

+145
-50
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Double Lazy Load | dll.js
2-
Double Lazy Load for images and background images.
2+
Double Lazy Load for images, background images and videos.
33

44
# CDN
55
Thanks to jsdelivr, we have CDN link <a href="http://www.jsdelivr.com/#!dll.js">here</a>.
@@ -18,20 +18,21 @@ new dll('selector',callback);
1818
```
1919

2020
# What it does
21-
* Do lazy loading for an element that is subject to lazy load via data-src, or
21+
* Do lazy loading for an element that is subject to lazy load via `data-src`, or
2222
* Do to all child items of a given element
2323
* Do <code>backgroundImage</code> to elements other than <code>&lt;img&gt;</code> if they have <code>data-src</code> attribute.
2424
* Do callback when load event is triggered for one element, or for the last child element of a given parent.
25+
* Do lazy loading for video elements having `<source>` with `data-src` attribute
2526
* Do lazy load for all items having <code>data-src</code> attribute.
2627

2728
# Works with
2829
Any valid selector or no selector.
2930
```js
3031
// lazy loads an element with a given class and it's children if any have data-src
31-
new dll('.uniqueClassName');
32+
new dll('.uniqueClassName', callBack);
3233

3334
// lazy loads an element with a given ID and it's children if any have data-src
34-
new dll('#uniqueID');
35+
new dll('#uniqueID', callBack);
3536

3637
// lazy loads any items with data-src from the entire page
3738
new dll();
@@ -46,7 +47,7 @@ function loadFunctionExample(){
4647
window.addEventListener('load', loadFunctionExample, false);
4748
```
4849

49-
If you want to lazy load on scroll
50+
If you want to lazy load on scroll, with [elementInViewport](https://gist.github.com/vincentorback/9ca8446a4c7c87ce3623) you can do:
5051
```js
5152
function scrollExample(){
5253
var el = document.getElementById('myItem');

assets/css/dll.css

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,16 @@ footer .content-wrap {
6969
.testCol2,
7070
.testCol2 img { opacity: 0 }
7171

72+
/* ie8 fix */
7273
.ie8 .testCol1 img,
7374
.ie8 .testCol2,
7475
.ie8 .testCol2 img { filter: alpha(opacity=0) }
7576

77+
/* video */
78+
.testCol3 { opacity: 0; }
79+
.ie8 .testCol3 { filter: alpha(opacity=0) }
80+
.testCol3 video { opacity: 0; max-width: 100% }
81+
7682
/* UTILITY STYLES
7783
-------------------------------------------------- */
7884
.clearfix:before,
@@ -203,7 +209,7 @@ pre {
203209
display: block;
204210
padding: 5px 10px;
205211
margin: 0 0 10px;
206-
font-size: 12px;
212+
font-size: 16px;
207213
line-height: 2.08;
208214
color: #999;
209215
word-break: break-all;

assets/js/scripts.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ for ( var i=0, itl=itms2.length; i<itl; i++ ){
7272
makeSRC(itms2[i],sizeSmall,imgs[rd].type,imgs[rd].name);
7373
}
7474

75+
var testCols3 = document.querySelector('.testCol3');
76+
makeSRC(testCols3,'980x800',imgs[n1].type,imgs[n1].name);
7577

7678
//some DLL demo
7779
new dll('.cover',pageLoadFinished);
@@ -129,17 +131,37 @@ function clickExample(e){
129131
window.addEventListener('scroll', scrollExample, false);
130132

131133
function scrollExample(){
134+
// IMGAGES
132135
var el = document.querySelector('.testCol2');
133136

134137
if ( elementInViewport(el) ){
135-
new dll(el, callback);
138+
new dll(el, imgCallback);
136139
}
137-
function callback(){
140+
function imgCallback(){
138141

139142
if ( !el.classList.contains('loaded') ){
140143
el.classList.add('loaded');
141144
var itms = el.getElementsByTagName('IMG'), il = itms.length;
142-
KUTE.fromTo(el, { opacity: 0 }, { opacity: 1 }, { delay: 500, duration: 2000, easing: 'easingExponentialOut' }).start();
145+
KUTE.fromTo(el, { opacity: 0 }, { opacity: 1 }, { delay: 500, duration: 2000 }).start();
146+
for ( var i = 0; i<il; i++ ) {
147+
var dl = parseInt(250*i + 2500);
148+
KUTE.fromTo(itms[i], { scale: 0.2, opacity: 0 }, { scale: 1, opacity: 1 }, { delay: dl, duration: 500, easing: 'easingBackOut' }).start();
149+
}
150+
}
151+
}
152+
153+
// VIDEO
154+
var videoWrapper = document.querySelector('.testCol3');
155+
156+
if ( elementInViewport(videoWrapper) ){
157+
new dll(videoWrapper, videoCallback);
158+
}
159+
function videoCallback(){
160+
161+
if ( !videoWrapper.classList.contains('loaded') ){
162+
videoWrapper.classList.add('loaded');
163+
KUTE.fromTo(videoWrapper, { opacity: 0 }, { opacity: 1 }, { delay: 500, duration: 2000 }).start();
164+
var itms = videoWrapper.getElementsByTagName('VIDEO'), il = itms.length;
143165
for ( var i = 0; i<il; i++ ) {
144166
var dl = parseInt(250*i + 2500);
145167
KUTE.fromTo(itms[i], { scale: 0.2, opacity: 0 }, { scale: 1, opacity: 1 }, { delay: dl, duration: 500, easing: 'easingBackOut' }).start();

dist/dll.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dll.js

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
srcSelector = '['+dataSRC+']',
2222
querySelector = 'querySelector',
2323
querySelectorAll = 'querySelectorAll',
24-
length = 'length';
24+
SOURCE = 'SOURCE', IMG = 'IMG', VIDEO = 'VIDEO',
25+
length = 'length',
26+
tagName = 'tagName';
2527

2628
// DLL DEFINITION
2729
// ==============
@@ -33,55 +35,60 @@
3335
// callback
3436
callbackFn = typeof callbackFn === 'function' ? callbackFn : null; // callback function
3537

36-
var self = this,
37-
38+
var self = this,
3839

3940
// element's src attribute
4041
elementSRC = element && element[getAttribute](dataSRC) || null, //element has own data-src attribute
4142

4243
// private methods
43-
loader = function(elementImage, imageCallback) {
44-
var img = new Image(), src = elementImage[getAttribute](dataSRC);
45-
img.onload = function(){
46-
if (elementImage.tagName === 'IMG') {
47-
elementImage.src=src;
48-
} else {
49-
elementImage.style.backgroundImage = 'url("'+src+'")';
50-
}
51-
elementImage.removeAttribute(dataSRC);
52-
if (imageCallback) { imageCallback() }
44+
loadMedia = function(mediaElement, imageCallback) {
45+
var isVideo = mediaElement[tagName] === SOURCE,
46+
loadMethod = isVideo ? 'onloadstart' : 'onload',
47+
newVideo = isVideo ? document.createElement(VIDEO) : 0,
48+
mediaObject = isVideo ? document.createElement(SOURCE) : new Image(),
49+
loadTarget = isVideo ? newVideo : mediaObject,
50+
src = mediaElement[getAttribute](dataSRC);
51+
52+
loadTarget[loadMethod] = function(){
53+
if (mediaElement[tagName] === IMG) { mediaElement.src=src; } // IMG
54+
else if (mediaElement[tagName] === SOURCE) { // VIDEO SOURCE
55+
mediaElement.src=src;
56+
mediaElement.parentNode.load();
57+
}
58+
else {mediaElement.style.backgroundImage = 'url("'+src+'")'; } // background-image
59+
mediaElement.removeAttribute(dataSRC);
60+
imageCallback && imageCallback();
5361
}
54-
img.src = src
62+
mediaObject.src = src;
63+
newVideo && ( newVideo.appendChild(mediaObject) );
64+
5565
},
5666
getElements = function() { //we get images of a given object or itself
57-
var queue, imgs = [], items = element[querySelectorAll](srcSelector);
58-
if ( elementSRC && !items) {
67+
var queue, mediaItems = [], matchedSelectors = element[querySelectorAll](srcSelector);
68+
if ( elementSRC && !matchedSelectors) {
5969
queue = [element];
60-
} else if ( !elementSRC && items ) {
61-
queue = items;
62-
} else if ( elementSRC && items ){
63-
queue = items;
64-
/* put element first in line, it may have a bigger image
65-
* to load than all childNodes combined */
66-
// imgs.push(element);
67-
imgs.unshift(element);
68-
} else if ( !elementSRC && !items ){
70+
} else if ( !elementSRC && matchedSelectors ) {
71+
queue = matchedSelectors;
72+
} else if ( elementSRC && matchedSelectors ){
73+
queue = matchedSelectors;
74+
mediaItems.unshift(element);
75+
} else if ( !elementSRC && !matchedSelectors ){
6976
queue = document[querySelectorAll](srcSelector);
7077
}
7178

72-
for (var i = 0; i < queue[length]; i++) { imgs.push(queue[i]) }
79+
for (var i = 0; i < queue[length]; i++) { mediaItems.push(queue[i]) }
7380

74-
return imgs;
81+
return mediaItems;
7582
};
7683

7784
// init
7885
if (elementSRC || element[querySelector](srcSelector) !== null) {
7986
var images = getElements();
8087
for (var i = 0; i < images[length]; i++) {
8188
if ( i === images[length]-1 && callbackFn) {
82-
loader(images[i],callbackFn);
89+
loadMedia(images[i],callbackFn);
8390
} else {
84-
loader(images[i])
91+
loadMedia(images[i])
8592
}
8693
}
8794
}

index.html

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<meta charset="utf-8">
1111
<meta http-equiv="X-UA-Compatible" content="IE=edge">
1212
<meta name="viewport" content="width=device-width, initial-scale=1">
13-
<meta name="description" content="Double Lazy Load for lazy loading images and background images">
13+
<meta name="description" content="Double Lazy Load for lazy loading images, background images and videos">
1414
<meta name="keywords" content="Double Lazy Load,dll.js,Javascript,Native Javascript,vanilla javascript">
1515
<meta name="author" content="dnp_theme">
1616
<link rel="shortcut icon" href="./assets/img/favicon.png"> <!-- TO DO -->
@@ -136,9 +136,9 @@ <h2>Let's do some lazy load on click</h2>
136136

137137
<div class="content-wrap onscroll">
138138
<h2>Let's do some lazy load on scroll</h2>
139-
<p>In this example, we target the parent <code>.testCol2</code> element with our function, and DLL lazy loads it and it's inner elements. And now we'll scroll down a bit.</p>
139+
<p>In this example, we target the parent <code>.img-wrapper</code> element with our function, and DLL lazy loads it and it's inner elements. And now we'll scroll down a bit.</p>
140140

141-
<div class="columns testCol2 fill" data-src="http://placehold.it/980x205/555/555/">
141+
<div class="columns testCol2 img-wrapper fill" data-src="http://placehold.it/980x205/555/555/">
142142
<div class="col2">
143143
<img src="./assets/img/img-blank.gif" data-src="http://placehold.it/450x205/555/555/">
144144
</div>
@@ -179,7 +179,8 @@ <h2>Let's do some lazy load on scroll</h2>
179179
el.classList.add('.loaded');
180180
}
181181
}
182-
</span></pre>
182+
</span></pre>
183+
<p>Grab the <code>elementInViewport</code> <a href="https://gist.github.com/vincentorback/9ca8446a4c7c87ce3623" target="_blank">right here</a>.</p>
183184
</div>
184185

185186
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
@@ -189,14 +190,70 @@ <h2>Let's do some lazy load on scroll</h2>
189190
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
190191
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
191192

192-
193+
194+
<div class="content-wrap onscroll">
195+
<h2>Let's play with videos</h2>
196+
<p>Similar to the above example, but this time we load a bunch of videos. Check notes below to get a glimpse on how it works:</p>
197+
<div class="columns testCol3 video-wrapper fill" data-src="http://placehold.it/980x205/555/555/">
198+
<div class="col2">
199+
<video poster="https://img-9gag-fun.9cache.com/photo/a24K1Me_460s.jpg" autoplay loop muted>
200+
<source data-src="https://img-9gag-fun.9cache.com/photo/a24K1Me_460sv.mp4" type="video/mp4">
201+
</video>
202+
</div>
203+
<div class="col2">
204+
<video poster="https://img-9gag-fun.9cache.com/photo/aDzY1YZ_460s.jpg" autoplay loop muted>
205+
<source data-src="https://img-9gag-fun.9cache.com/photo/aDzY1YZ_460sv.mp4" type="video/mp4">
206+
</video>
207+
</div>
208+
<div class="col2">
209+
<video poster="https://img-9gag-fun.9cache.com/photo/a9A1x40_460s.jpg" autoplay loop muted>
210+
<source data-src="https://img-9gag-fun.9cache.com/photo/a9A1x40_460sv.mp4" type="video/mp4">
211+
</video>
212+
</div>
213+
<div class="col2">
214+
<video poster="https://img-9gag-fun.9cache.com/photo/aY4VLyO_460s.jpg" autoplay loop muted>
215+
<source data-src="https://img-9gag-fun.9cache.com/photo/aY4VLyO_460sv.mp4" type="video/mp4">
216+
</video>
217+
</div>
218+
</div>
219+
220+
221+
<p>DLL.js will only target videos with the following structure:</p>
222+
<pre><span class="brush: html; ruler: true; toolbar:false; gutter: false">
223+
&lt;video id="myVideo" poster="video/my-video.jpg"&gt;
224+
&lt;source data-src="video/my-video.mp4" type="video/mp4"&gt;
225+
&lt;/video&gt;
226+
</span></pre>
227+
228+
<p>If your content has the right structure, you can do everything else just like the usual:</p>
229+
<pre><span class="brush: js; ruler: true; toolbar:false; gutter: false">
230+
// grab a video
231+
var myVideo = document.getElementById('myVideo');
232+
// initialize for a single video element
233+
new dll(myVideo, callback);
234+
235+
// grab a wrapper element
236+
var myWrapper = document.getElementById('myWrapper');
237+
// initialize for and element and/or all child elements
238+
new dll(myWrapper, callback);
239+
</span></pre>
240+
</div>
241+
242+
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
243+
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
244+
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
245+
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
246+
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
247+
<div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div> <div class="clearfix"><br></div>
248+
249+
193250
<div class="content-wrap">
194251
<h2>In case you missed the features</h2>
195252
<ul>
196253
<li>Lazy load a single element that has <code>data-src</code> attribute, ideally an <code>&lt;img&gt;</code> or a layer element with no child elements</li>
197-
<li>By the way, do you want retina images loaded later?</li>
198-
<li>Works for <code>&lt;img&gt;</code> and other elements as well, that's right, it's <code>background-image</code></li>
199-
<li>When an element other than image is targeted, it will also lazy load it's child elements having the <code>data-src</code> attribute</li>
254+
<li>With DLL.js version 1.0.0 it works with videos as well. How cool is that?</li>
255+
<li>Works for <code>&lt;img&gt;</code> and other elements as well, to update the <code>background-image</code></li>
256+
<li>When an element other than image/video is targeted, it will also lazy load it's child elements having the <code>data-src</code> attribute</li>
200257
<li>You can also call DLL to do lazy load for all elements in a page at once, by simply using <code>new dll();</code></li>
201258
<li>DLL has callback ability and it's triggered when the target element is loaded or it's last element is loaded</li>
202259
<li>With a <code>elementInViewport</code> function you can lazy load elements on scroll, like the example above</li>
@@ -253,7 +310,7 @@ <h1>Hi. I'm DLL.js</h1>
253310
<script src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.js" type="text/javascript"></script>
254311

255312
<!--<script src="http://cdn.jsdelivr.net/dll.js/0.9.1/dll.min.js"></script> lazy-load CDN -->
256-
<script src="./dist/dll.min.js"></script> <!-- lazy-load local -->
313+
<script src="./dist/dll.min.js"></script><!-- lazy-load local -->
257314
<script src="https://cdn.jsdelivr.net/kute.js/1.6.2/kute.min.js"></script> <!-- KUTE CDN -->
258315

259316
<script src="./assets/js/scripts.js"></script> <!-- some stuff -->

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dll.js",
3-
"version": "0.9.5",
3+
"version": "1.0.0",
44
"description": "Double Lazy Load for images and background images.",
55
"main": "dll.js",
66
"scripts": {
@@ -14,6 +14,8 @@
1414
"keywords": [
1515
"dll.js",
1616
"lazy load",
17+
"lazy load image",
18+
"lazy load video",
1719
"double lazy load",
1820
"vanilla js",
1921
"vanilla javascript"

0 commit comments

Comments
 (0)