Skip to content

Commit 700605c

Browse files
authored
Merge pull request #10 from Hugoer/main
feat(project): Defer creation of the component instance
2 parents d77ceaf + 7cdca50 commit 700605c

File tree

7 files changed

+60
-26
lines changed

7 files changed

+60
-26
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ Adding more than one component
101101
data-nc-params-Component2="{}"></div>
102102
```
103103

104+
105+
Defering component instantiation until it enters the viewport
106+
107+
```
108+
<div data-nc="Component1"
109+
data-nc-loading="lazy"></div>
110+
```
111+
104112
### register
105113

106114
This method will register components constructor in loaderComponents
@@ -111,7 +119,7 @@ You can register individual component, or list
111119
```
112120
/**
113121
* Constant with a object that contain collection of components classes.
114-
*
122+
*
115123
* @param {object} newComponents - Components collection { name: definition }
116124
* @param {number} [level] - level of inheritance
117125
*/

package-lock.json

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

src/factory.js

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { components } from './components';
2+
import { create } from './create';
23
import { deferredComponents } from './deferredComponents';
34
import { instances } from './instances';
4-
import { create } from './create';
55
import { uuid } from './uuid';
66

77
const sortKeys = (list) => Object.keys(list).sort((a, b) => b - a);
@@ -18,16 +18,46 @@ const getComponent = (name) => {
1818
* Factory by a component name and node
1919
* Removed this feature from run.js function into its own function for separate use
2020
*/
21-
export const factory = (name, element, initAttr) => {
21+
export const factory = (name, element, initAttr, lazyAttr) => {
2222
// if there is a component available with the name
2323
const component = getComponent(name);
24+
const isLazy = element.getAttribute(lazyAttr) === 'lazy';
25+
26+
if (!component) {
27+
// no component was found
28+
deferredComponents[name] = deferredComponents[name] || [];
29+
deferredComponents[name].push({ element, initAttr, lazyAttr });
30+
// eslint-disable-next-line no-console
31+
return console.warn(`Deferring initialisation of Component because factory cannot find a class for "${name}"`);
32+
}
2433

25-
if (component) {
26-
if (!instances[name]) {
27-
instances[name] = [];
28-
}
29-
// create a unique ID for the component + node
30-
element.uuid = uuid();
34+
if (!instances[name]) {
35+
instances[name] = [];
36+
}
37+
// create a unique ID for the component + node
38+
element.uuid = uuid();
39+
40+
if (isLazy) {
41+
const observerSettings = { rootMargin: '50px 0px', threshold: 0.01 };
42+
const observer = new IntersectionObserver((entries) => {
43+
entries.forEach((entry) => {
44+
if (entry.intersectionRatio > 0) {
45+
observer.unobserve(element);
46+
// add to the active collection using a unique ID
47+
instances[name].push(
48+
create(
49+
component, // Component Class
50+
name, // Component Name
51+
element, // Node
52+
initAttr // params to find components
53+
)
54+
);
55+
}
56+
});
57+
}, observerSettings);
58+
59+
observer.observe(element);
60+
} else {
3161
// add to the active collection using a unique ID
3262
instances[name].push(
3363
create(
@@ -37,11 +67,7 @@ export const factory = (name, element, initAttr) => {
3767
initAttr // params to find components
3868
)
3969
);
40-
return null;
4170
}
42-
// no component was found
43-
deferredComponents[name] = deferredComponents[name] || [];
44-
deferredComponents[name].push({ element, initAttr });
45-
// eslint-disable-next-line no-console
46-
return console.warn(`Deferring initialisation of Component because factory cannot find a class for "${name}"`);
71+
72+
return null;
4773
};

src/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
export * from './components';
22
export * from './create';
3+
export * from './domReady';
4+
export * from './factory';
35
export * from './instances';
46
export * from './observe';
57
export * from './register';
68
export * from './run';
7-
export * from './uuid';
8-
export * from './factory';
9-
export * from './domReady';
109
export * from './runComponent';
1110
export * from './scan';
11+
export * from './uuid';

src/register.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { factory } from './factory';
21
import { components } from './components';
32
import { deferredComponents } from './deferredComponents';
3+
import { factory } from './factory';
44

55
/**
66
* Constant with an object that contain collection of components classes.
@@ -19,7 +19,7 @@ export const register = (newComponents, level) => {
1919
components[level][name] = newComponents[name];
2020
}
2121
if (deferredComponents[name]) {
22-
deferredComponents[name].forEach(({ element, initAttr }) => factory(name, element, initAttr));
22+
deferredComponents[name].forEach(({ element, initAttr, lazyAttr }) => factory(name, element, initAttr, lazyAttr));
2323
delete deferredComponents[name];
2424
}
2525
});

src/run.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { scan } from './scan';
77
* @param {string} [initAttr] attribute name
88
*/
99

10-
export const run = (element = window.document, initAttr = 'data-nc') =>
10+
export const run = (element = window.document, initAttr = 'data-nc', lazyAttr = 'data-nc-loading') =>
1111
scan(element, initAttr).forEach(
1212
(node) => setTimeout(() => {
1313
// when we have coral polyfills (forced all browsers at cloud env), it creates elements twice + and move then around.
@@ -17,7 +17,7 @@ export const run = (element = window.document, initAttr = 'data-nc') =>
1717
// get the component that needs, will load by attribute
1818
const componentNames = node.getAttribute(initAttr).split(',');
1919
componentNames.forEach((name) =>
20-
factory(name, node, initAttr));
20+
factory(name, node, initAttr, lazyAttr));
2121
}
2222
})
2323
);

src/runComponent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { scan } from './scan';
55
* Run the loader scan only for one component
66
*/
77

8-
export const runComponent = (name, element = window.document, initAttr = 'data-nc') =>
8+
export const runComponent = (name, element = window.document, initAttr = 'data-nc', lazyAttr = 'data-nc-loading') =>
99
scan(element, `${initAttr}*="${name}"`)
1010
.forEach((node) => setTimeout(() =>
11-
factory(name, node, initAttr)));
11+
factory(name, node, initAttr, lazyAttr)));

0 commit comments

Comments
 (0)