问题:
我有一个花哨的循环图像轮播需要从特定的第一张幻灯片开始 - 当用户滚动到某个div时。如果用户向上/向下滚动并返回到该div,则不应重新启动。
我现在只能在用户滚动到div时启动它 - 然后当你滚动并返回它时它会被搞砸,我认为这是因为函数再次开始运行。
我想要实现的目标:
我的(匿名,对不起!)代码:
http://jsfiddle.net/annablabber/h8pqW/
HTML
<p class="scroll_down">Scroll down...</p>
<div class="animation_container">You should get an alert only once here—the first time you scroll to this div.</div>
CSS
.scroll_down {
margin-bottom: 1000px;
}
.animation_container {
width: 300px;
height: 200px;
background-color: red;
padding: 30px;
color: white;
margin-bottom: 1000px;
}
的jQuery
// The fancy function for my animations
function doSomeComplicatedStuff() {
alert("...and here's where the complicated animations happen!");
}
// The function to check if div.animation_container is scrolled into view
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
// If div.animation_container is scrolled into view, run the fancy function
$(window).on('scroll', function() {
if (isScrolledIntoView('.animation_container')) {
run_once(function() {
doSomeComplicatedStuff();
});
}
});
// The function that's supposed to make sure my fancy function will only run ONCE, EVER
function run_once( callback ) {
var done = false;
return function() {
if ( !done ) {
done = true;
return callback.apply( this, arguments );
}
};
}
由视觉设计师清楚地写的脚本道歉。如果问题在匿名代码中不够明确,请告诉我。
答案 0 :(得分:3)
将done
变量移动到全局?
var firstScroll = false;
$(window).on('scroll', function() {
if (isScrolledIntoView('.animation_container') && !firstScroll) {
doSomeComplicatedStuff();
}
});
function doSomeComplicatedStuff() {
firstScroll = true;
// Your code here
}
这样,第一次isScrolledIntoView
返回true时,doComplicatedStuff
函数会立即翻转停止后续调用的布尔值firstScroll
。
答案 1 :(得分:1)
你可以有这样的东西
// The fancy function for my animations
var alreadyRun = false;
function doSomeComplicatedStuff() {
alert("...and here's where the complicated animations happen!");
}
// The function to check if div.animation_container is scrolled into view
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
// If div.animation_container is scrolled into view, run the fancy function
$(window).on('scroll', function() {
if (isScrolledIntoView('.animation_container') && !alreadyRun) {
doSomeComplicatedStuff();
alreadyRun = true;
}
});
工作jsfiddle
答案 2 :(得分:1)
run_once()
时都会一次又一次地重新定义。更好的方法是在该函数中添加第一个参数,以确定运行的是哪个动作(function run_once(identifier,callback) { if(!done[identifier]) { run function and set done[identifier] to true; }
)return function()
run_once()
答案 3 :(得分:1)
以下是更新的解决方案:http://jsfiddle.net/h8pqW/2/
基本上,每次满足条件时您都在运行run_once
,因此它创建了一个新的done
变量。我将run_once
调用移到了doSomeComplicatedStuff
声明中,将其转换为只运行一次的方法。
// The fancy function for my animations
var doSomeComplicatedStuff = run_once(function () {
alert("...and here's where the complicated animations happen!");
});
这是一个更高效的替代方案,不需要使用run_once
帮助程序:http://jsfiddle.net/h8pqW/3/
在这个例子中,我只要在调用函数时解除绑定scroll
事件。这将阻止页面在每次用户滚动时继续尝试运行该功能。
// If div.animation_container is scrolled into view, run the fancy function
$(window).on('scroll', function() {
if (isScrolledIntoView('.animation_container')) {
doSomeComplicatedStuff();
$(window).unbind('scroll');
}
});