Open
Description
使用我修改后的包(Use my modified package)
适合懒人
For lazy people
主要是生命周期vue2和vue3不通导致不兼容,还有一些其他细微变化
The main reason is that the life cycle vue2 and vue3 are incompatible, and there are some other minor changes.
我把改动后的项目,也上传到了npm上,方便大家直接使用
I also uploaded the changed project to npm, which is convenient for everyone to use directly.
也进行了开源,直接安装vue3-infinite-scroll-good ,用法和vue-infinite-scroll一模一样
As like as two peas, vue3-infinite-scroll-good is installed directly, and the usage is exactly the same as vue-infinite-scroll.
直接修改源码替换(Direct modification of source code replacement)
适合有洁癖的人,不愿使用小众包
It is suitable for people who are obsessed with cleanliness and do not want to use crowdsourcing
directive.js
const ctx = "@@InfiniteScroll";
var throttle = function(fn, delay) {
var now, lastExec, timer, context, args; //eslint-disable-line
var execute = function() {
fn.apply(context, args);
lastExec = now;
};
return function() {
context = this;
args = arguments;
now = Date.now();
if (timer) {
clearTimeout(timer);
timer = null;
}
if (lastExec) {
var diff = delay - (now - lastExec);
if (diff < 0) {
execute();
} else {
timer = setTimeout(() => {
execute();
}, diff);
}
} else {
execute();
}
};
};
var getScrollTop = function(element) {
if (element === window) {
return Math.max(
window.pageYOffset || 0,
document.documentElement.scrollTop
);
}
return element.scrollTop;
};
var getComputedStyle = document.defaultView.getComputedStyle;
var getScrollEventTarget = function(element) {
var currentNode = element;
// bugfix, see http://w3help.org/zh-cn/causes/SD9013 and http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome
while (
currentNode &&
currentNode.tagName !== "HTML" &&
currentNode.tagName !== "BODY" &&
currentNode.nodeType === 1
) {
var overflowY = getComputedStyle(currentNode).overflowY;
if (overflowY === "scroll" || overflowY === "auto") {
return currentNode;
}
currentNode = currentNode.parentNode;
}
return window;
};
var getVisibleHeight = function(element) {
if (element === window) {
return document.documentElement.clientHeight;
}
return element.clientHeight;
};
var getElementTop = function(element) {
if (element === window) {
return getScrollTop(window);
}
return element.getBoundingClientRect().top + getScrollTop(window);
};
var isAttached = function(element) {
var currentNode = element.parentNode;
while (currentNode) {
if (currentNode.tagName === "HTML") {
return true;
}
if (currentNode.nodeType === 11) {
return false;
}
currentNode = currentNode.parentNode;
}
return false;
};
var doBind = function() {
if (this.binded) return; // eslint-disable-line
this.binded = true;
var directive = myInstance;
var element = directive.el;
var throttleDelayExpr = element.getAttribute(
"infinite-scroll-throttle-delay"
);
var throttleDelay = 200;
if (throttleDelayExpr) {
throttleDelay = Number(
directive.vm[throttleDelayExpr] || throttleDelayExpr
);
if (isNaN(throttleDelay) || throttleDelay < 0) {
throttleDelay = 200;
}
}
directive.throttleDelay = throttleDelay;
directive.scrollEventTarget = getScrollEventTarget(element);
directive.scrollListener = throttle(
doCheck.bind(directive),
directive.throttleDelay
);
directive.scrollEventTarget.addEventListener(
"scroll",
directive.scrollListener
);
var disabledExpr = element.getAttribute("infinite-scroll-disabled");
var disabled = false;
if (disabledExpr) {
this.vm.$watch(disabledExpr, function(value) {
directive.disabled = value;
if (!value && directive.immediateCheck) {
setTimeout(() => {
doCheck.call(directive);
});
}
});
disabled = Boolean(directive.vm[disabledExpr]);
}
directive.disabled = disabled;
var distanceExpr = element.getAttribute("infinite-scroll-distance");
var distance = 0;
if (distanceExpr) {
distance = Number(directive.vm[distanceExpr] || distanceExpr);
if (isNaN(distance)) {
distance = 0;
}
}
directive.distance = distance;
var immediateCheckExpr = element.getAttribute(
"infinite-scroll-immediate-check"
);
var immediateCheck = true;
if (immediateCheckExpr) {
immediateCheck = Boolean(directive.vm[immediateCheckExpr]);
}
directive.immediateCheck = immediateCheck;
if (immediateCheck) {
setTimeout(() => {
doCheck.call(directive);
});
}
var eventName = element.getAttribute("infinite-scroll-listen-for-event");
if (eventName) {
directive.vm.$on(eventName, function() {
setTimeout(() => {
doCheck.call(directive);
});
});
}
};
var doCheck = function(force) {
var scrollEventTarget = myInstance.scrollEventTarget;
var element = myInstance.el;
var distance = myInstance.distance;
if (force !== true && myInstance.disabled) return; //eslint-disable-line
var viewportScrollTop = getScrollTop(scrollEventTarget);
var viewportBottom = viewportScrollTop + getVisibleHeight(scrollEventTarget);
var shouldTrigger = false;
if (scrollEventTarget === element) {
shouldTrigger = scrollEventTarget.scrollHeight - viewportBottom <= distance;
} else {
var elementBottom =
getElementTop(element) -
getElementTop(scrollEventTarget) +
element.offsetHeight +
viewportScrollTop;
shouldTrigger = viewportBottom + distance >= elementBottom;
}
if (shouldTrigger && myInstance.expression) {
this.expression();
}
};
var myInstance = null;
var myDirective = {
mounted(el, binding, vnode) {
el[ctx] = {
el,
vm: binding.instance,
expression: binding.value,
};
myInstance = el[ctx];
var args = arguments;
el[ctx].vm.$nextTick(function() {
if (isAttached(el)) {
doBind.call(el[ctx], args);
}
el[ctx].bindTryCount = 0;
var tryBind = function() {
if (el[ctx].bindTryCount > 10) return; //eslint-disable-line
el[ctx].bindTryCount++;
if (isAttached(el)) {
doBind.call(el[ctx], args);
} else {
setTimeout(tryBind, 50);
}
};
tryBind();
});
}
};
export default myDirective;
Metadata
Metadata
Assignees
Labels
No labels