appear-polyfill
Version:
[](https://www.npmjs.com/package/rax-appear)
109 lines (88 loc) • 3.42 kB
JavaScript
;
exports.__esModule = true;
exports.createIntersectionObserver = createIntersectionObserver;
exports.destroyIntersectionObserver = destroyIntersectionObserver;
exports.observerElement = observerElement;
var _IntersectionObserver = _interopRequireDefault(require("./IntersectionObserver"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Shared intersectionObserver instance.
var intersectionObserver;
var IntersectionObserver = function () {
if (typeof window !== 'undefined' && 'IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
// features are natively supported
return window.IntersectionObserver;
} else {
// polyfilled IntersectionObserver
return _IntersectionObserver.default;
}
}();
function generateThreshold(number) {
var thresholds = [];
for (var index = 0; index < number; index++) {
thresholds.push(index / number);
}
return thresholds;
}
var defaultOptions = {
root: null,
rootMargin: '0px',
threshold: generateThreshold(10)
};
function createIntersectionObserver(options) {
if (options === void 0) {
options = defaultOptions;
}
intersectionObserver = new IntersectionObserver(handleIntersect, options);
}
function destroyIntersectionObserver() {
if (intersectionObserver) {
intersectionObserver.disconnect();
intersectionObserver = null;
}
}
function observerElement(element) {
if (!intersectionObserver) createIntersectionObserver();
if (element === document) element = document.documentElement;
intersectionObserver.observe(element);
}
function handleIntersect(entries) {
entries.forEach(function (entry) {
var target = entry.target,
boundingClientRect = entry.boundingClientRect,
intersectionRatio = entry.intersectionRatio; // pollfill 里面没有 top
var currentY = boundingClientRect.y || boundingClientRect.top;
var beforeY = parseInt(target.getAttribute('data-before-current-y')) || currentY; // is in view
if (intersectionRatio > 0.01 && !isTrue(target.getAttribute('data-appeared')) && !appearOnce(target, 'appear')) {
target.setAttribute('data-appeared', 'true');
target.setAttribute('data-has-appeared', 'true');
target.dispatchEvent(createEvent('appear', {
direction: currentY > beforeY ? 'up' : 'down'
}));
} else if (intersectionRatio === 0 && isTrue(target.getAttribute('data-appeared')) && !appearOnce(target, 'disappear')) {
target.setAttribute('data-appeared', 'false');
target.setAttribute('data-has-disappeared', 'true');
target.dispatchEvent(createEvent('disappear', {
direction: currentY > beforeY ? 'up' : 'down'
}));
}
target.setAttribute('data-before-current-y', currentY);
});
}
/**
* need appear again when node has isonce or data-once
*/
function appearOnce(node, type) {
var isOnce = isTrue(node.getAttribute('isonce')) || isTrue(node.getAttribute('data-once'));
var appearType = type === 'appear' ? 'data-has-appeared' : 'data-has-disappeared';
return isOnce && isTrue(node.getAttribute(appearType));
}
function isTrue(flag) {
return flag && flag !== 'false';
}
function createEvent(eventName, data) {
return new CustomEvent(eventName, {
bubbles: false,
cancelable: true,
detail: data
});
}