मैं अपनी वेबसाइट पर पेज स्क्रॉलिंग एनीमेशन जोड़ने के लिए एक वेनिला जावास्क्रिप्ट फ़ंक्शन लिख रहा हूं। समस्या यह है कि मैं चाहता हूं कि ईवेंट श्रोता एनीमेशन को पूरा करने के लिए समय देने के लिए निर्दिष्ट मिलीसेकंड समय के लिए रुक जाए क्योंकि अगर मैं सामान्य रूप से स्क्रॉल करता हूं, तो एनीमेशन एक के बाद एक कई बार होगा।
/* Event handler for scroll event */
// This is a function which allows a time to be passed in miliseconds. This function will then cause a sleep effect for the specified ms time
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Initial state
var iniState = 0;
// Adding scroll event
window.addEventListener('scroll', function(){
// Detects new state and compares it with the old one
if ((document.body.getBoundingClientRect()).top > iniState)
console.log('up');
else
console.log('down');
// Saves the new position for iteration.
iniState = (document.body.getBoundingClientRect()).top;
sleep(2000).then(() => { console.log("test"); });
});
मैंने टाइमआउट फ़ंक्शन की कोशिश की, लेकिन इसने केवल समय की अवधि के लिए रुकने के बजाय ईवेंट श्रोता में देरी की। यह ब्राउज़र में कंसोल के लिए लिंक है यदि इससे समस्या को समझना आसान हो जाता है।
गर्मियों में, मैं एक स्क्रॉल ईवेंट सुनने के लिए एक ईवेंट श्रोता बनाने की कोशिश कर रहा हूं, फिर एनीमेशन के पूरा होने की प्रतीक्षा करने के लिए 2000 मिलीसेकंड प्रतीक्षा करें। इसके बाद इवेंट श्रोता फिर से स्क्रॉल इवेंट के लिए फिर से सुनना शुरू कर देगा।
4 जवाब
बस ईवेंट श्रोता जोड़ें, इसे कॉल करने के बाद इसे हटा दें, फिर इसे फिर से जोड़ने के लिए टाइमआउट सेट करें।
function scrollHandler() {
window.removeEventListener('scroll', scrollHandler);
// Detects new state and compares it with the old one
if ((document.body.getBoundingClientRect()).top > iniState)
console.log('up');
else
console.log('down');
// Saves the new position for iteration.
iniState = (document.body.getBoundingClientRect()).top;
setTimeout(() => window.addEventListener('scroll', scrollHandler), 2000);
}
window.addEventListener('scroll', scrollHandler);
animationend
ईवेंट का उपयोग करें।
let lastScrollStart
window.addEventListener('scroll', () => {
const scrollStart = lastScrollStart = performance.now() // timestamp
const elAnimated = document.querySelector(...)
elAnimated.addEventListener('animationend', function onAnimationEnd() {
elAnimated.removeEventListener('animationend', onAnimationEnd)
if (scrollStart === lastScrollStart) {
...
}
})
})
मेरा मानना है कि हर बार जब कोई ब्राउज़र स्क्रॉल ईवेंट का पता लगाता है, तो यह आपके टेम्प्लेट का उपयोग करके एक नया फ़ंक्शन बनाएगा और एक स्टैक में डाल देगा।
उदाहरण के लिए: स्क्रॉल का पता चला: 7:41:20s कॉल स्टैक = [ function_created_at_7:41:20s
]
अगली स्क्रॉल 7:41:21s पर पाई गई:
call stack = [ function_created_at_7:41:20s,
function_created_at_7:41:21s
]
चूंकि वादा और टाइमआउट अतुल्यकालिक निष्पादन हैं, वे प्रतीक्षा करते हैं और कॉल स्टैक में रहते हैं।
2000 के दशक बीत जाने के बाद, function_created_at_7:41:20s
के स्लीप कॉलबैक को निष्पादित किया जाएगा
स्क्रॉल फ़ंक्शन को स्लीप में रखने के लिए आपको वैश्विक संदर्भों और कुछ ifs का उपयोग करना पड़ सकता है।
let is_waiting = false;
document.addEventListener("scroll",(e) => {
if(!is_waiting) {
console.log("scrolling...");
is_waiting = true;
setTimeout(() => {
is_waiting = false;
},2000);
}
})