Javascript对AJAX调用的不同变量作用域
Javascript different variable scope on AJAX call
我在编写的一个简单滑块脚本中的变量作用域有问题(由于带宽低,我不想使用现成的解决方案)。滑块脚本在静态加载的页面(http)和通过AJAX加载的内容上都被调用。在静态加载的页面上(因此没有AJAX),脚本似乎工作得很完美。然而,当通过AJAX调用时,调用的方法找不到DOM的元素,这会停止滑块所需的必要动画。
所有事件都是通过甚至委托(使用jQuery的on()函数)来处理的,但这并没有提供解决方案。我确信这与脚本的结构和变量范围有关,但无法确定如何更改结构。因此,我正在寻找一种在这两种情况下都能工作的解决方案(称为普通或通过AJAX)。
我试图在每个函数中声明所需的变量,但由于函数范围的原因,这导致了一些错误,比如我为动画设置的间隔的乘积。希望有人能在正确的方向上帮助我。
// Slider function
(function (window, undefined) {
var console = window.console || undefined, // Prevent a JSLint complaint
doc = window.document,
Slider = window.Slider = window.Slider || {},
$doc = $(doc),
sliderContainer = doc.getElementById('slider_container'),
$sliderContainer = $(sliderContainer),
$sliderContainerWidth = $sliderContainer.width(),
slider = doc.getElementById('slider'),
$slider = $(slider),
$sliderChildren = $slider.children(),
$slideCount = $sliderChildren.size(),
$sliderWidth = $sliderContainerWidth * $slideCount;
$sliderControl = $(doc.getElementById('slider_control')),
$prevButton = $(doc.getElementById('prev')),
$nextButton = $(doc.getElementById('next')),
speed = 2000,
interval,
intervalSpeed = 5000,
throttle = true,
throttleSpeed = 2000;
if (sliderContainer == null) return; // If slider is not found on page return
// Set widths according to the container and amount of children
Slider.setSliderWidth = function () {
$slider.width($sliderWidth);
$sliderChildren.width($sliderContainerWidth);
};
// Does the animation
Slider.move = function (dir) {
// Makes use of variables such as $sliderContainer, $sliderContainer width, etc.
};
// On ajax call
$doc.on('ajaxComplete', document, function () {
Slider.setSliderWidth();
});
// On doc ready
$(document).ready(function () {
Slider.setSliderWidth();
interval = window.setInterval('Slider.move("right")', intervalSpeed);
});
// Handler for previous button
$doc.on('click', '#prev', function (e) {
e.preventDefault();
Slider.move('left');
});
// Handler for next button
$doc.on('click', '#next', function (e) {
e.preventDefault();
Slider.move('right');
});
// Handler for clearing the interval on hover and showing next and pervious button
$doc.on('hover', '#slider_container', function (e) {
if (e.type === 'mouseenter') {
window.clearInterval(interval);
$sliderControl.children().fadeIn(400);
}
});
// Handler for resuming the interval and fading out the controls
$doc.on('hover', '#slider_control', function (e) {
if (e.type !== 'mouseenter') {
interval = window.setInterval('Slider.move("right")', intervalSpeed);
$sliderControl.children().fadeOut(400);
}
});
})(window);
HTML示例结构:
<div id="slider_control">
<a id="next" href="#next"></a>
<a id="prev" href="#prev"></a>
</div>
<div id="slider_container">
<ul id="slider">
<li style="background-color:#f00;">1</li>
<li style="background-color:#282">2</li>
<li style="background-color:#ff0">3</li>
</ul>
</div>
我注意到你有
Slider.setSliderWidth = function() {
$slider.width($sliderWidth);
$sliderChildren.width($sliderContainerWidth);
};
它在ajax上被调用完成。
您是否使用ajax更新DOM,从而提供一个可以通过doc.getElementById('slider')
访问的新DOM元素?那么您的var slider
和jquery var $slider
很可能指向已经不存在的东西(即使有一个以slider
为id的dom元素)。为了纠正这种情况,无论何时调用替换该元素的ajax,都要使用相同的初始化来重新初始化slider
和$slider
,以指向新的jquery封装的元素。
slider = doc.getElementById('slider');
$slider = $(slider);
编辑:
我不确定您将如何处理可变范围问题,但请看一下这个例子。
<pre>
<script>
(function(){
var a = "something";
function x (){
a += "else";
}
function y() {
a = "donut";
}
function print (){
document.write(a +"'n");
}
print ();
x();
print ();
y();
print ();
x();
print ();
})();
document.write(typeof(a) + "'n");
</script>
</pre>
输出到pre
标签
something
somethingelse
donut
donutelse
undefined
这与你已经在做的没有什么不同。只要a
不是方法的参数,并且没有在嵌套作用域中用var声明,那么在function(window,undefined){ ...}
方法中定义的代码中对a
的所有引用都将引用该a
,因为a
是由var
本地定义的。有道理吗?
首先,您可以使用jQuery方法替换所有getElementById
。即用$('#next')
替换$(doc.getElementById('next'))
我认为,当您使用on
时,它不会像您所假设的那样在元素中搜索选择器。所以你必须使用:
$doc.on('click', '#slider_control #prev',function(e){
e.preventDefault();
Slider.move('left');
});
等等,什么通过Ajax加载?滑块html代码?在这种情况下,Slider已经"创建",并且您的许多变量将不指向任何位置(因为这些DOM元素在初始化变量时并不存在)。他们也永远不会这么做。
- 带有KendoUI组件的Javascript变量作用域
- Javascript变量作用域:从回调函数中提取变量
- 使用JavaScript回调函数了解变量作用域和闭包
- jquery.post和变量作用域
- 变量作用域:在函数之间传递的名称
- 在 AJAX 和 Javascript 中使用变量和变量作用域
- 节点.js/express.js中的变量作用域
- jquery ajax 回调变量作用域(为什么有些在作用域中,而另一些则不在作用域中)
- JavaScript 中的变量作用域
- ajax GET 和 POST 中的变量作用域
- Javascript:变量作用域和全局变量的弊端
- Javascript 自执行函数和变量作用域
- 拼接上的Javascript全局变量作用域/覆盖
- 在Node中与jsdom和jquery共享变量作用域
- NodeJS:代码优化和变量作用域
- Javascript数组变量作用域
- AngularJS ng控制器指令不接受javascript中的变量(作用域函数),也不给出任何错误
- 回调函数中的变量作用域呢
- JavaScript/jQuery变量作用域导致错误
- AJAX变量作用域