From b25295c6ee2c540c0b0f39f1cfea4957d5980cbe Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 12:14:42 -0600 Subject: [PATCH 01/11] Fixed issue with calling the .observe() method on an instance that had no elements to begin with --- package.json | 2 +- src/lazy.js | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 8070dd8..569202f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lazy", - "version": "1.0.0", + "version": "1.0.1", "description": "A lazy loader based on the IntersectionObserver API", "keywords": [ "lazy", diff --git a/src/lazy.js b/src/lazy.js index ef1ff2b..fb4b0a7 100644 --- a/src/lazy.js +++ b/src/lazy.js @@ -6,6 +6,7 @@ const lazy = (options = {}) => { root: null, rootMargin: '200px 0px', threshold: 0.1, + unbindAfterIntersect: true, onIntersectionCallback: null }; let observer = null; @@ -15,9 +16,7 @@ const lazy = (options = {}) => { const init = () => { settings = {...defaults, ...options}; els = [...document.querySelectorAll(`${settings.elSelector}`)]; - if (els.length > 0) { - intersectionObserverIsSupported() ? bindObserver(els) : load(els); - } + intersectionObserverIsSupported() ? bindObserver(els) : load(els); }; const bindObserver = els => { @@ -38,7 +37,7 @@ const lazy = (options = {}) => { }); }; - const observe = els => { + const observe = (els = null) => { if (els && observer !== null) { const elsArr = ensureArray(els); elsArr.forEach(el => observer.observe(el)); @@ -49,7 +48,9 @@ const lazy = (options = {}) => { if (els) { const elsArr = ensureArray(els); elsArr.forEach(el => { - unbindObserver(el); + if (settings.unbindAfterIntersect === true) { + unbindObserver(el); + } if (settings.onIntersectionCallback !== null) { settings.onIntersectionCallback(el); } else { From 2aa3b88de466750a87510aafcc5dfef9d0e67352 Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 12:21:00 -0600 Subject: [PATCH 02/11] updated readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 0894da2..4127f66 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,11 @@ Type: `Number` Either a single number or an array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed. From the [IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options). Default: `0.1` +### options.unbindAfterIntersect +Type: `Boolean` +Determines if the observed element should be unobserved after its crossing its observation threshold for the first time. +Default: `false` + #### options.onIntersectionCallback Type: `Function` Returns: `Element` From c62c0955146989a380dfe287d293ff64468b3277 Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 12:21:54 -0600 Subject: [PATCH 03/11] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4127f66..c5d4182 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Default: `0.1` ### options.unbindAfterIntersect Type: `Boolean` -Determines if the observed element should be unobserved after its crossing its observation threshold for the first time. +Determines if the observed element should be unobserved after crossing its observation threshold for the first time. Default: `false` #### options.onIntersectionCallback From facc0d216f6b1f58080f8d13a8fcdf0e764eb044 Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 12:23:54 -0600 Subject: [PATCH 04/11] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5d4182..7148eda 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Default: `0.1` ### options.unbindAfterIntersect Type: `Boolean` Determines if the observed element should be unobserved after crossing its observation threshold for the first time. -Default: `false` +Default: `true` #### options.onIntersectionCallback Type: `Function` From ecf3116578ace0f6390dc226fcf411ee024fe04a Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 12:24:52 -0600 Subject: [PATCH 05/11] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7148eda..e0a22ea 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Default: `0.1` ### options.unbindAfterIntersect Type: `Boolean` -Determines if the observed element should be unobserved after crossing its observation threshold for the first time. +Determines if the observed elements should be unobserved after crossing their respective observation thresholds for the first time. Default: `true` #### options.onIntersectionCallback From 1311ec0c46427efa884d50a2f5286951c0195be1 Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 12:25:58 -0600 Subject: [PATCH 06/11] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 569202f..1512db6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lazy", - "version": "1.0.1", + "version": "1.1.0", "description": "A lazy loader based on the IntersectionObserver API", "keywords": [ "lazy", From d12b97c24356b31f1ee243c207d1c94fe56bcaa4 Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 13:35:20 -0600 Subject: [PATCH 07/11] Added onNonIntersectionCallback --- README.md | 6 ++++++ package.json | 2 +- src/lazy.js | 18 +++++++++++++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e0a22ea..8999ab9 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,12 @@ Returns: `Element` An optional callback that will override the default image-loading behavior, and simply return the observed element that has entered the viewport. Default: `null` +#### options.onNonIntersectionCallback +Type: `Function` +Returns: `Element` +An optional callback that will return the observed element that has left the viewport. +Default: `null` + ## Methods ### .observe(els) diff --git a/package.json b/package.json index 1512db6..1e64dd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lazy", - "version": "1.1.0", + "version": "1.2.0", "description": "A lazy loader based on the IntersectionObserver API", "keywords": [ "lazy", diff --git a/src/lazy.js b/src/lazy.js index fb4b0a7..60d0bfe 100644 --- a/src/lazy.js +++ b/src/lazy.js @@ -7,8 +7,10 @@ const lazy = (options = {}) => { rootMargin: '200px 0px', threshold: 0.1, unbindAfterIntersect: true, - onIntersectionCallback: null + onIntersectionCallback: null, + onNonIntersectionCallback: null }; + let initialIntersection = true; let observer = null; let settings; let els; @@ -30,13 +32,23 @@ const lazy = (options = {}) => { const onIntersection = entries => { entries.forEach(entry => { - if (entry.intersectionRatio > 0) { - const el = entry.target; + const el = entry.target; + if (entry.isIntersecting) { load(el); + } else { + onNonIntersection(el); } }); }; + const onNonIntersection = el => { + if (settings.onNonIntersectionCallback !== null && + initialIntersection === false) { + settings.onNonIntersectionCallback(el); + } + initialIntersection = false; + }; + const observe = (els = null) => { if (els && observer !== null) { const elsArr = ensureArray(els); From 866d83504e6744ce1945f88150edf394c33b8b3b Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 13:38:10 -0600 Subject: [PATCH 08/11] fixed version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1e64dd0..1512db6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lazy", - "version": "1.2.0", + "version": "1.1.0", "description": "A lazy loader based on the IntersectionObserver API", "keywords": [ "lazy", From 92c8163168f5c3f60972dd5d03323a64bdb2bdde Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 13:46:20 -0600 Subject: [PATCH 09/11] refactored unbindObserver, fix for load --- src/lazy.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lazy.js b/src/lazy.js index 60d0bfe..625195f 100644 --- a/src/lazy.js +++ b/src/lazy.js @@ -60,20 +60,20 @@ const lazy = (options = {}) => { if (els) { const elsArr = ensureArray(els); elsArr.forEach(el => { - if (settings.unbindAfterIntersect === true) { - unbindObserver(el); - } - if (settings.onIntersectionCallback !== null) { + unbindObserver(el); + if (settings.onIntersectionCallback !== null && + initialIntersection === false) { settings.onIntersectionCallback(el); } else { setElAttrs(el); } }); + initialIntersection = false; } }; const unbindObserver = el => { - if (observer) { + if (observer && settings.unbindAfterIntersect === true) { observer.unobserve(el); } }; From e18d23316550f5652d78aacaab1d4997d7e372a0 Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 13:50:38 -0600 Subject: [PATCH 10/11] refactored unbindObserver, fix for load --- src/lazy.js | 175 +++++++++++++++++++++++----------------------------- 1 file changed, 78 insertions(+), 97 deletions(-) diff --git a/src/lazy.js b/src/lazy.js index 625195f..a929b5e 100644 --- a/src/lazy.js +++ b/src/lazy.js @@ -1,106 +1,87 @@ -const lazy = (options = {}) => { +import {capitalize} from '../../../utils/stringUtils.js'; +import {getNextButtonAction} from '../../../utils/renderUtils.js'; +import React, {Component} from 'react'; +import {connect} from 'react-redux'; +import {changeEligibility} from '../../actions/formActions.js'; +import Description from './description.js'; +import Field from './field.js'; +import ActionButtons from './actionButtons.js'; - const defaults = { - elSelector: '[data-lazy]', - animationClass: null, - root: null, - rootMargin: '200px 0px', - threshold: 0.1, - unbindAfterIntersect: true, - onIntersectionCallback: null, - onNonIntersectionCallback: null - }; - let initialIntersection = true; - let observer = null; - let settings; - let els; +const nextButtonActionConfig = { + conditionalVals: [ + 'military', + 'spouse', + 'child' + ], + conditionalDestination: 'eligibilityDetails', + defaultDestination: 'policyHolder' +}; - const init = () => { - settings = {...defaults, ...options}; - els = [...document.querySelectorAll(`${settings.elSelector}`)]; - intersectionObserverIsSupported() ? bindObserver(els) : load(els); - }; +const mapDispatchToProps = dispatch => ({ + changeEligibility: payload => dispatch(changeEligibility(payload)) +}); - const bindObserver = els => { - observer = new IntersectionObserver(onIntersection, { - root: settings.root, - rootMargin: settings.rootMargin, - threshold: settings.threshold - }); - observe(els); - }; +class Eligibility extends Component { - const onIntersection = entries => { - entries.forEach(entry => { - const el = entry.target; - if (entry.isIntersecting) { - load(el); - } else { - onNonIntersection(el); + constructor(props) { + super(props); + this.handleInputChange = this.handleInputChange.bind(this); + this.state = { + nextButton: { + name: 'next', + action: getNextButtonAction(this.props.eligibilityStatus, nextButtonActionConfig) } - }); - }; - - const onNonIntersection = el => { - if (settings.onNonIntersectionCallback !== null && - initialIntersection === false) { - settings.onNonIntersectionCallback(el); - } - initialIntersection = false; - }; - - const observe = (els = null) => { - if (els && observer !== null) { - const elsArr = ensureArray(els); - elsArr.forEach(el => observer.observe(el)); - } - }; - - const load = els => { - if (els) { - const elsArr = ensureArray(els); - elsArr.forEach(el => { - unbindObserver(el); - if (settings.onIntersectionCallback !== null && - initialIntersection === false) { - settings.onIntersectionCallback(el); - } else { - setElAttrs(el); - } - }); - initialIntersection = false; - } - }; - - const unbindObserver = el => { - if (observer && settings.unbindAfterIntersect === true) { - observer.unobserve(el); - } - }; + }; + } - const setElAttrs = el => { - if (settings.animationClass) { - el.classList.add(settings.animationClass); - } - if (el.dataset.src) { - el.src = el.dataset.src; - } - if (el.dataset.srcset) { - el.srcset = el.dataset.srcset; - } - }; + componentDidMount() { + this.props.changeEligibility(this.props.eligibilityStatus); + } - const ensureArray = maybeArr => Array.isArray(maybeArr) ? maybeArr : [maybeArr]; - - const intersectionObserverIsSupported = () => 'IntersectionObserver' in window; - - init(); - - return { - observe, - load - }; + handleInputChange({name, value}) { + this.props.changeEligibility(value); + this.setState({ + nextButton: { + ...this.state.nextButton, + action: getNextButtonAction(value, nextButtonActionConfig) + } + }); + this.props.handleInputChange({ + name, + value + }); + } + + render() { + const { + heading, + description, + fields + } = this.props.section; -}; + return ( +
this.formEl = form} + onSubmit={e => this.props.handleSubmit(e, this.formEl, this.state.nextButton.action)} + noValidate> +
+

{heading}

+ + +
+ + + ); + } +} -export default lazy; +export default connect(null, mapDispatchToProps)(Eligibility); From 6fac8d5d1b65e6c8192e54998321d9007b0c240a Mon Sep 17 00:00:00 2001 From: Aaron Ladage Date: Wed, 21 Nov 2018 13:52:56 -0600 Subject: [PATCH 11/11] oops --- src/lazy.js | 174 +++++++++++++++++++++++++++++----------------------- 1 file changed, 96 insertions(+), 78 deletions(-) diff --git a/src/lazy.js b/src/lazy.js index a929b5e..d8aab28 100644 --- a/src/lazy.js +++ b/src/lazy.js @@ -1,87 +1,105 @@ -import {capitalize} from '../../../utils/stringUtils.js'; -import {getNextButtonAction} from '../../../utils/renderUtils.js'; -import React, {Component} from 'react'; -import {connect} from 'react-redux'; -import {changeEligibility} from '../../actions/formActions.js'; -import Description from './description.js'; -import Field from './field.js'; -import ActionButtons from './actionButtons.js'; +const lazy = (options = {}) => { -const nextButtonActionConfig = { - conditionalVals: [ - 'military', - 'spouse', - 'child' - ], - conditionalDestination: 'eligibilityDetails', - defaultDestination: 'policyHolder' -}; + const defaults = { + elSelector: '[data-lazy]', + animationClass: null, + root: null, + rootMargin: '200px 0px', + threshold: 0.1, + unbindAfterIntersect: true, + onIntersectionCallback: null, + onNonIntersectionCallback: null + }; + let initialIntersection = true; + let observer = null; + let settings; + let els; -const mapDispatchToProps = dispatch => ({ - changeEligibility: payload => dispatch(changeEligibility(payload)) -}); + const init = () => { + settings = {...defaults, ...options}; + els = [...document.querySelectorAll(`${settings.elSelector}`)]; + intersectionObserverIsSupported() ? bindObserver(els) : load(els); + }; -class Eligibility extends Component { + const bindObserver = els => { + observer = new IntersectionObserver(onIntersection, { + root: settings.root, + rootMargin: settings.rootMargin, + threshold: settings.threshold + }); + observe(els); + }; - constructor(props) { - super(props); - this.handleInputChange = this.handleInputChange.bind(this); - this.state = { - nextButton: { - name: 'next', - action: getNextButtonAction(this.props.eligibilityStatus, nextButtonActionConfig) + const onIntersection = entries => { + entries.forEach(entry => { + const el = entry.target; + if (entry.isIntersecting) { + load(el); + } else { + onNonIntersection(el); } - }; - } + }); + }; - componentDidMount() { - this.props.changeEligibility(this.props.eligibilityStatus); - } + const onNonIntersection = el => { + if (settings.onNonIntersectionCallback !== null && + initialIntersection === false) { + settings.onNonIntersectionCallback(el); + } + initialIntersection = false; + }; - handleInputChange({name, value}) { - this.props.changeEligibility(value); - this.setState({ - nextButton: { - ...this.state.nextButton, - action: getNextButtonAction(value, nextButtonActionConfig) - } - }); - this.props.handleInputChange({ - name, - value - }); - } - - render() { - const { - heading, - description, - fields - } = this.props.section; + const observe = (els = null) => { + if (els && observer !== null) { + const elsArr = ensureArray(els); + elsArr.forEach(el => observer.observe(el)); + } + }; + + const load = els => { + if (els) { + const elsArr = ensureArray(els); + elsArr.forEach(el => { + unbindObserver(el); + if (settings.onIntersectionCallback !== null) { + settings.onIntersectionCallback(el); + } else { + setElAttrs(el); + } + }); + initialIntersection = false; + } + }; - return ( -
this.formEl = form} - onSubmit={e => this.props.handleSubmit(e, this.formEl, this.state.nextButton.action)} - noValidate> -
-

{heading}

- - -
- - - ); - } -} + const unbindObserver = el => { + if (observer && settings.unbindAfterIntersect === true) { + observer.unobserve(el); + } + }; + + const setElAttrs = el => { + if (settings.animationClass) { + el.classList.add(settings.animationClass); + } + if (el.dataset.src) { + el.src = el.dataset.src; + } + if (el.dataset.srcset) { + el.srcset = el.dataset.srcset; + } + }; + + const ensureArray = maybeArr => Array.isArray(maybeArr) ? maybeArr : [maybeArr]; + + const intersectionObserverIsSupported = () => 'IntersectionObserver' in window; + + init(); + + return { + observe, + load + }; + +}; -export default connect(null, mapDispatchToProps)(Eligibility); +export default lazy;