Skip to content

Commit c8aff57

Browse files
Fixed bugs with _tm.inview.js, _tm.loadmedia.js - can now be used as standalone plugins - fixed bug with t
_tm.dismissable.js where by refreshing the plugin did not work - cleaned up _tm.masonrygrid.js and reorganized _tm.core.js - now uses .masonry class for grid loading instance instead of .grid.preload
1 parent 026abdb commit c8aff57

File tree

6 files changed

+110
-60
lines changed

6 files changed

+110
-60
lines changed

src/js/_tm.core.js

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright © UnlimitDesign 2019
22
// Plugin: Timber core
3-
// Version: 1.0.1
3+
// Version: 1.0.3
44
// URL: @UnlimitDesign
55
// Author: UnlimitDesign, Christian Lundgren, Shu Miyao
66
// Description: Creates instances of timber plugins
@@ -41,24 +41,24 @@ const timberCore = (function () {
4141
// Set the plugin defaults
4242
const defaults = {
4343
initialize: true,
44-
inview: '.observe',
45-
loadmedia: '.preload-media',
4644
accordion: '.accordion',
4745
collapsable: '.collapsable',
4846
dismissable: '.dismissable',
4947
dropdown: '.dropdown',
50-
overlaynav: '.overlay-nav-show',
48+
lightbox: '.lightbox',
49+
horizon: '.horizon',
50+
inview: '.observe',
51+
loadmedia: '.preload-media',
52+
masonrygrid: '.masonry',
53+
overlaynavigation: '.overlay-nav-show',
54+
parallax: '.parallax',
5155
rollover: '.thumbnail',
5256
scrollto: '.scroll-to',
53-
sidenav: '.side-nav-show',
57+
sidenavigation: '.side-nav-show',
58+
stickyheader: '.header',
5459
togglesubmenu: '.toggle-sub-menus',
5560
tabs: '.tabs',
56-
horizon: '.horizon',
57-
lightbox: '.lightbox',
58-
masonrygrid: '.grid.preload',
59-
parallax: '.parallax',
60-
responsiveVideo: '.video',
61-
stickyheader: '.header'
61+
responsivevideo: '.video'
6262
};
6363

6464
// Create an empty plugin object
@@ -71,37 +71,56 @@ const timberCore = (function () {
7171
plugin.defaults = defaults;
7272
plugin.options = options;
7373
plugin.settings = Object.assign({}, defaults, options);
74-
plugin.module = { inview: null, loadmedia: null, accordion: null, collapsable: null, dismissable: null, dropdown: null, horizon: null, masonrygrid: null, overlaynavigation: null, rollover: null, scrollto: null, sidenavigation: null, stickyheader: null, tabs: null, togglesubmenu: null };
75-
74+
plugin.module = {
75+
accordion: null,
76+
collapsable: null,
77+
dismissable: null,
78+
dropdown: null,
79+
lightbox: null,
80+
horizon: null,
81+
inview: null,
82+
loadmedia: null,
83+
masonrygrid: null,
84+
overlaynavigation: null,
85+
parallax: null,
86+
rollover: null,
87+
scrollto: null,
88+
sidenavigation: null,
89+
stickyheader: null,
90+
tabs: null,
91+
togglesubmenu: null,
92+
responsivevideo: null,
93+
};
94+
7695
// Create instances if module exists
7796
if (typeof tmAccordion != 'undefined') plugin.module.accordion = new tmAccordion(plugin.settings.accordion);
7897
if (typeof tmCollapsable != 'undefined') plugin.module.collapsable = new tmCollapsable(plugin.settings.collapsable);
7998
if (typeof tmDismissable != 'undefined') plugin.module.dismissable = new tmDismissable(plugin.settings.dismissable);
8099
if (typeof tmDropdown != 'undefined') plugin.module.dropdown = new tmDropdown(plugin.settings.dropdown);
81100
if (typeof tmLightbox != 'undefined') plugin.module.lightbox = new tmLightbox(plugin.settings.lightbox);
82101
if (typeof tmHorizon != 'undefined') plugin.module.horizon = new tmHorizon(plugin.settings.horizon);
83-
if (typeof tmMasonryGrid != 'undefined') plugin.module.masonrygrid = new tmMasonryGrid(plugin.settings.masonrygrid);
84102
if (typeof tmInView != 'undefined') plugin.module.inview = new tmInView(plugin.settings.inview);
85103
if (typeof tmLoadMedia != 'undefined') plugin.module.loadmedia = new tmLoadMedia(plugin.settings.loadmedia);
86-
if (typeof tmOverlayNavigation != 'undefined') plugin.module.overlaynavigation = new tmOverlayNavigation(plugin.settings.overlaynav);
104+
if (typeof tmMasonryGrid != 'undefined') plugin.module.masonrygrid = new tmMasonryGrid(plugin.settings.masonrygrid);
105+
if (typeof tmOverlayNavigation != 'undefined') plugin.module.overlaynavigation = new tmOverlayNavigation(plugin.settings.overlaynavigation);
87106
if (typeof tmParallax != 'undefined') plugin.module.parallax = new tmParallax(plugin.settings.parallax);
88107
if (typeof tmRollover != 'undefined') plugin.module.rollover = new tmRollover(plugin.settings.rollover);
89108
if (typeof tmScrollTo != 'undefined') plugin.module.scrollto = new tmScrollTo(plugin.settings.scrollto);
90-
if (typeof tmSideNavigation != 'undefined') plugin.module.sidenavigation = new tmSideNavigation(plugin.settings.sidenav);
109+
if (typeof tmSideNavigation != 'undefined') plugin.module.sidenavigation = new tmSideNavigation(plugin.settings.sidenavigation);
91110
if (typeof tmStickyHeader != 'undefined') plugin.module.stickyheader = new tmStickyHeader(plugin.settings.stickyheader);
92111
if (typeof tmTabs != 'undefined') plugin.module.tabs = new tmTabs(plugin.settings.tabs);
93112
if (typeof tmToggleSubMenu != 'undefined') plugin.module.togglesubmenu = new tmToggleSubMenu(plugin.settings.togglesubmenu);
94-
if (typeof tmResponsiveVideo != 'undefined') plugin.module.responsivevideo = new tmResponsiveVideo(plugin.settings.responsiveVideo);
113+
if (typeof tmResponsiveVideo != 'undefined') plugin.module.responsivevideo = new tmResponsiveVideo(plugin.settings.responsivevideo);
95114
} catch (error) {
96115
console.log(`${error} - ensure module is imported or instantiate specific plugin instead of core, for example: plugin.module.moduleName.initialize();`);
97116
}
98-
117+
99118
/**
100119
* Initialize the plugin.
101120
*/
102121
plugin.initialize = () => {
103122
for (let module in plugin.module) {
104-
if (plugin.module[module] != null && document.querySelector(plugin.module[module].elements)) plugin.module[module].initialize();
123+
if (plugin.module[module] != null && document.querySelector(plugin.settings[module])) plugin.module[module].initialize();
105124
}
106125
};
107126

@@ -110,7 +129,7 @@ const timberCore = (function () {
110129
*/
111130
plugin.refresh = () => {
112131
for (let module in plugin.module) {
113-
if (plugin.module[module] != null && document.querySelector(plugin.module[module].elements)) plugin.module[module].refresh();
132+
if (plugin.module[module] != null && document.querySelector(plugin.settings[module])) plugin.module[module].refresh();
114133
}
115134
};
116135

@@ -119,7 +138,7 @@ const timberCore = (function () {
119138
*/
120139
plugin.destroy = () => {
121140
for (let module in plugin.module) {
122-
if (plugin.module[module] != null && document.querySelector(plugin.module[module].elements)) plugin.module[module].destroy();
141+
if (plugin.module[module] != null && document.querySelector(plugin.settings[module])) plugin.module[module].destroy();
123142
}
124143
};
125144

src/js/components/_tm.dismissable.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright © UnlimitDesign 2019
22
// Plugin: Dismissable
3-
// Version: 1.0.2
3+
// Version: 1.0.3
44
// URL: @UnlimitDesign
55
// Author: UnlimitDesign, Christian Lundgren, Shu Miyao
66
// Description: Detect when elements enter and/or leave viewport
@@ -59,7 +59,7 @@ const tmDismissale = (function () {
5959
*/
6060
const addCloseLink = (dismissible) => {
6161
const closeLink = document.createElement('button');
62-
closeLink.className = `close p-0 bg-transparent bg-hover-transparent border-none ${plugin.settings.fontLibrary}`;
62+
closeLink.className = `close p-0 outline-none bg-transparent bg-hover-transparent border-none ${plugin.settings.fontLibrary}`;
6363
closeLink.innerHTML = plugin.settings.iconClose;
6464
dismissible.appendChild(closeLink);
6565
addLinkEvents(closeLink);
@@ -105,7 +105,7 @@ const tmDismissale = (function () {
105105
* Initialize the plugin.
106106
*/
107107
plugin.initialize = () => {
108-
108+
109109
if(plugin.elements == null) return false;
110110

111111
// Loop through each item and check each dismissable element
@@ -138,7 +138,7 @@ const tmDismissale = (function () {
138138

139139
// Loop through each item and check each dismissable element
140140
document.querySelectorAll(plugin.elements).forEach(function(dismissible){
141-
removeLinkEvents(dismissible.querySelector('.close'));
141+
if(dismissible.querySelector('.close')) removeLinkEvents(dismissible.querySelector('.close'));
142142
});
143143

144144
// Callback

src/js/plugins/_tm.masonrygrid.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ const tmMasonryGrid = (function () {
224224
plugin.initialize = () => {
225225

226226
if(plugin.elements == null) return false;
227-
227+
228228
// Loop through grid and add inview instance
229229
document.querySelectorAll(plugin.elements).forEach(function(element){
230230

src/js/utilities/_tm.inview.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright © UnlimitDesign 2019
22
// Plugin: Inview
3-
// Version: 1.0.1
3+
// Version: 1.0.2
44
// URL: @UnlimitDesign
55
// Author: UnlimitDesign, Christian Lundgren, Shu Miyao
66
// Description: Detect when elements enter and/or leave viewport
@@ -120,14 +120,14 @@ const tmInView = (function () {
120120
entries.forEach(function(entry) {
121121
let item = entry.target;
122122
if(entry.isIntersecting){
123-
123+
124124
// Swap classes
125125
classList(item).removeClass('out-of-view').addClass('in-view');
126126

127127
// Test if item is still in the viewport
128128
delayCallbackInView(item, elementObserver);
129129
}else{
130-
130+
131131
// Swap classes
132132
classList(item).removeClass('in-view').addClass('out-of-view');
133133

@@ -226,7 +226,7 @@ const tmInView = (function () {
226226
if(plugin.elements == null) return false;
227227

228228
// Check element
229-
plugin.elements = NodeList.prototype.isPrototypeOf(plugin.elements) ? plugin.elements : document.querySelectorAll(plugin.elements);
229+
plugin.elements = !NodeList.prototype.isPrototypeOf(plugin.elements) ? document.querySelectorAll(plugin.elements) : plugin.elements[0].classList.contains('observe') ? document.querySelectorAll('.observe') : plugin.elements;
230230

231231
// Check force option
232232
iObserve = plugin.settings.forceObserveOnScroll ? false : iObserve;
@@ -236,7 +236,8 @@ const tmInView = (function () {
236236
plugin.elements.forEach(function(element) {
237237
let threshold = element.dataset.threshold ? element.dataset.threshold : plugin.settings.threshold;
238238
let detectionBuffer = element.dataset.detectionBuffer ? element.dataset.detectionBuffer : `0px 0px ${plugin.settings.detectionBuffer + 'px'} 0px`;
239-
if(plugin.settings.observeParent) element = element.parentNode;
239+
plugin.settings.observeParent = element.hasAttribute('data-observe-parent') ? true : plugin.settings.observeParent;
240+
element = plugin.settings.observeParent ? element.parentNode : element;
240241
observeOnIntersect(element, threshold, detectionBuffer);
241242
});
242243

@@ -268,15 +269,16 @@ const tmInView = (function () {
268269
* Destroy an existing initialization.
269270
*/
270271
plugin.destroy = () => {
271-
272272
if (!plugin.settings) return;
273273

274274
// Remove intersect and window listener
275-
if(iObserve)
275+
plugin.elements = !NodeList.prototype.isPrototypeOf(plugin.elements) ? document.querySelectorAll(plugin.elements) : plugin.elements;
276+
if(iObserve){
276277
plugin.elements.forEach(function (element,i) {
277-
elementObservers[i].unobserve(element);
278+
if(elementObservers.length > 0) elementObservers[i].unobserve(element);
279+
elementObservers = [];
278280
});
279-
else{
281+
}else{
280282
window.removeEventListener('scroll', observeOnScroll, false);
281283
}
282284

src/js/utilities/_tm.loadmedia.js

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
// Copyright © UnlimitDesign 2019
22
// Plugin: Load media
3-
// Version: 1.0.1
3+
// Version: 1.0.2
44
// URL: @UnlimitDesign
55
// Author: UnlimitDesign, Christian Lundgren, Shu Miyao
66
// Description: Detect when elements enter and/or leave viewport
77
// License: MIT
88

99
// Import classList utility
1010
import classList from './_chaining.js';
11+
import tmInView from '../utilities/_tm.inview.js';
1112

1213
const tmLoadMedia = (function () {
1314

1415
'use strict';
1516

1617
if (typeof document == 'undefined') return false;
1718

19+
// InView for lazyload instance
20+
let mediaInView;
21+
1822
// Set the plugin defaults
1923
const defaults = {
24+
lazyLoad: true, // Whether items should be lazyloaded using inView
2025
backgroundImage: false, // Preload background image set in CSS
2126
onLoaded: function(){}, // Callback - tabs initialized
2227
onError: function(){}, // Callback - element in view
@@ -49,7 +54,7 @@ const tmLoadMedia = (function () {
4954
* @param {string} The media tag type.
5055
*/
5156
const processMedia = (media, mediaType) =>{
52-
57+
5358
if(media.classList.contains('loaded')) return false;
5459

5560
switch(mediaType){
@@ -66,7 +71,7 @@ const tmLoadMedia = (function () {
6671
if(!plugin.settings.backgroundImage && image.srcset){
6772
proxyImage.srcset = image.dataset.srcset;
6873
}
69-
74+
7075
// Use decode for modern browsers
7176
if('decode' in proxyImage){
7277
proxyImage.decode().then(() => {
@@ -94,7 +99,7 @@ const tmLoadMedia = (function () {
9499
source.src = source.dataset.src;
95100
video.load();
96101
}
97-
})
102+
});
98103

99104
// Add events
100105
addEventListeners(video);
@@ -119,7 +124,7 @@ const tmLoadMedia = (function () {
119124
* @param {element} For images only, reference to old image for insertion.
120125
*/
121126
const addEventListeners = (media, refItem) =>{
122-
127+
123128
// Check load event
124129
let loadEvent = media.tagName == 'VIDEO' ? 'loadeddata' : 'load';
125130

@@ -184,6 +189,16 @@ const tmLoadMedia = (function () {
184189
plugin.settings.onError(target);
185190
};
186191

192+
/**
193+
* Check media type
194+
* @param {element} defaults The event or image that failed to load.
195+
*/
196+
const checkMediaType = (element) => {
197+
let tagName = element.tagName;
198+
let mediaType = tagName == 'IMG' ? 'image' : tagName == 'DIV' ? 'image' : tagName == 'SPAN' ? 'image' : tagName == 'SOURCE' ? 'video' : 'iframe';
199+
return mediaType;
200+
};
201+
187202
/**
188203
* Public variables and methods.
189204
*/
@@ -192,32 +207,46 @@ const tmLoadMedia = (function () {
192207
* Initialize the plugin.
193208
*/
194209
plugin.initialize = () => {
195-
196-
if(plugin.elements == null) return false;
197-
198-
// Check if data src exists on element
199-
let elementDataSrc = !plugin.elements.dataset ? false : plugin.elements.dataset.src ? true : false;
200210

201-
// Check tag type
202-
let tagName = plugin.elements.tagName;
203-
let mediaType = tagName == 'IMG' ? 'image' : tagName == 'DIV' ? 'image' : tagName == 'SPAN' ? 'image' : tagName == 'SOURCE' ? 'video' : 'iframe';
211+
if(plugin.elements == null) return false;
204212

205-
// Single item
206-
if(elementDataSrc){
207-
processMedia(plugin.elements, mediaType);
213+
// HTML element passed used commonly when integrated into other plugins
214+
if(plugin.elements instanceof Element){
215+
processMedia(plugin.elements, checkMediaType(plugin.elements));
208216

209-
// Look for multiple items in container
210217
}else{
211-
document.querySelectorAll(plugin.elements).forEach(function(element){
212-
let images = element.querySelectorAll(mediaType);
213-
for (let i=0; i < images.length; i++) {
214-
let image = images[i];
215-
processMedia(image, mediaType);
216-
}
217-
});
218+
if(!plugin.settings.lazyLoad){
219+
let images = document.querySelectorAll(plugin.elements);
220+
images.forEach(function(element){
221+
processMedia(element, checkMediaType(element));
222+
});
223+
}else{
224+
mediaInView = new tmInView(plugin.elements,{
225+
threshold: 0.5,
226+
detectionBuffer: 100,
227+
unObserveViewed: true,
228+
inView: function(visibleMedia){
229+
visibleMedia = visibleMedia.classList.contains(plugin.elements) ? visibleMedia : visibleMedia.querySelector(plugin.elements);
230+
processMedia(visibleMedia, checkMediaType(visibleMedia));
231+
}
232+
});
233+
mediaInView.initialize();
234+
}
218235
}
219236
};
220237

238+
/**
239+
* Refresh the plugin.
240+
*/
241+
plugin.refresh = () => {
242+
// Destroy the existing initialization
243+
plugin.destroy();
244+
245+
// Initialize the plugin
246+
plugin.settings = Object.assign({}, defaults, options);
247+
plugin.initialize();
248+
};
249+
221250
/**
222251
* Destroy an existing initialization.
223252
*/

src/scss/partials/components/_grid-css.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
.grid-item-inner{
3737
height: 100%;
3838
}
39-
.grid.preload{
39+
.grid.masonry{
4040
position: relative;
4141
.grid-item-inner{
4242
width: $grid-item-width-start;

0 commit comments

Comments
 (0)