[英]jQuery Not Defined within a function
Alright, here's a puzzler. 好吧,这是一个难题。 I've got a jQuery function to display a PHP generated list of announcements for a website via .fadeIn/.fadeOut; 我有一个jQuery函数,用于通过.fadeIn / .fadeOut显示PHP生成的网站公告列表; the very first thing loaded on the page is jQuery 1.11.xx from a CDN. 页面上加载的第一件事是CDN中的jQuery1.11.xx。 I'm running Bootstrap, fullCalendar, SmartMenus, etc., and jQuery is most definitely loading. 我正在运行Bootstrap,fullCalendar,SmartMenus等,并且jQuery肯定正在加载。
Except within the setInterval() to update the announcement. 在setInterval()内以更新公告。 This is rough-code, some functionality isn't present, but to my mind it should be doing an animation. 这是粗糙的代码,不存在某些功能,但是在我看来,它应该是动画。
var announcementArray = [];
var announcementSource = "../announcements.php";
var totalAnnc;
$.getJSON(announcementSource, function(data) {
announcementArray = data.concat();
totalAnnc = announcementArray.length;
});
var count = 0;
var fadeAnnc = function() {
$('#announcementArea').text(announcementArray[count].announceText);
$('#announcementArea').fadeIn('slow',function() {
$('#announcementArea').css('display','block');
}).delay(2000).fadeOut('slow',function() {
count = (count + 1) % totalAnnc;
});
};
setInterval(function() {
fadeAnnc();
}, 3000);
Instead, when I run the page, I get a "function not defined" error for any jQuery function that's called within the setInterval(). 相反,当我运行页面时,对于在setInterval()中调用的所有jQuery函数,都会收到“未定义函数”错误。 If I call using document.getElementById('announcementArea').innerHTML = etc., it works, but doing the fade in/out via DOM manipulation seems to be more work than is needed when jQuery is available and working everywhere else on the page. 如果我使用document.getElementById('announcementArea')。innerHTML =等调用,它可以工作,但是通过DOM操作进行淡入/淡出似乎比需要jQuery并在页面上其他任何地方都能工作时所需的工作更多。
I've tried a few scope adjustments and have been working on what should be simple code for the last 5 hours. 我尝试了一些范围调整,并且在最近5个小时内一直在研究应该是简单代码的内容。 So, where's my glaring error? 那么,我明显的错误在哪里? ;) ;)
Not sure what kind of scope issue you are having (looks like it's the result of unposted code, as everything in your question looks OK), but if you want a fairly foolproof way of passing along the jQuery object, you could always pass it as a parameter: 不确定您遇到的是哪种范围的问题(看起来是未发布代码的结果,因为您的问题中的所有内容看起来都不错),但是如果您想要一种相当安全的方式传递jQuery对象,则可以始终将其传递为参数:
var fadeAnnc = function($) {
$('#announcementArea').text(announcementArray[count].announceText);
$('#announcementArea').fadeIn('slow',function() {
$('#announcementArea').css('display','block');
}).delay(2000).fadeOut('slow',function() {
count = (count + 1) % totalAnnc;
});
};
setInterval(function() {
fadeAnnc($);
}, 3000);
Based on your updated answer, here's another possible solution: 根据您更新的答案,这是另一种可能的解决方案:
(function($){
var announcementArray = [];
var announcementSource = "../announcements.php";
var announcementSpace = "#announcementArea";
$.getJSON(announcementSource, function(data) {
announcementArray = data.concat();
if (announcementArray.length === 0) {
$('#anncRow').css('display','none');
}
});
var count = 0;
var masterCount = 0;
var totalAnnc = announcementArray.length;
var timer;
var fadeAnnc = function() {
if (announcementArray.length > 0) {
$(announcementSpace).html(announcementArray[count].announceText);
$(announcementSpace).fadeIn(750, function() {
$(announcementSpace).css('display','block');
}).delay(4500).fadeOut(750, function() {
$(announcementSpace).css('display','hidden');
});
}
count += 1;
if ((count % announcementArray.length) == 0) {count = 0}
};
setInterval(fadeAnnc, 6000);
}(jQuery));
$
is defined as a function parameter and thus overrides the globally scoped $
within the function body, protecting it's definition for your code. $
被定义为一个函数参数,因此将覆盖函数体内的全局作用域$
,以保护代码的定义。 This is actually exactly what jQuery recommends when creating an extension . 实际上,这正是jQuery在创建扩展时所建议的 。
My previous answer - scratch that: 我以前的答案-刮that:
The issue was more interesting - somewhere between the SmartMenu plugin and the LibraryThing book display widget there is a jQuery conflict created. 这个问题更有趣-在SmartMenu插件和LibraryThing图书显示小部件之间的某个地方,创建了jQuery冲突。 This explains why - depending on the load order - different parts would break, but always the setInterval(), which always loaded after SmartMenu and LibraryThing. 这就解释了为什么-根据加载顺序,不同的部分会损坏,但总是会损坏setInterval(),而该部分总是在SmartMenu和LibraryThing之后加载。
So, my somewhat messy solution is to release the $ at the beginning of the script and reclaim it at the end so on other pages jQuery has access to it, like so: 因此,我的解决方案有些混乱,是在脚本开头释放$并在结尾处回收它,以便jQuery在其他页面上可以访问它,如下所示:
jq = jQuery.noConflict();
var announcementArray = [];
var announcementSource = "../announcements.php";
var announcementSpace = "#announcementArea";
jq.getJSON(announcementSource, function(data) {
announcementArray = data.concat();
if (announcementArray.length === 0) {
jq('#anncRow').css('display','none');
}
});
var count = 0;
var masterCount = 0;
var totalAnnc = announcementArray.length;
var timer;
var fadeAnnc = function() {
if (announcementArray.length > 0) {
jq(announcementSpace).html(announcementArray[count].announceText);
jq(announcementSpace).fadeIn(750, function() {
jq(announcementSpace).css('display','block');
}).delay(4500).fadeOut(750, function() {
jq(announcementSpace).css('display','hidden');
});
}
count += 1;
if ((count % announcementArray.length) == 0) {count = 0}
};
setInterval(fadeAnnc, 6000);
$ = jQuery.noConflict();
Use closures (which is considered good practice anyways): 使用闭包(无论如何都被认为是一种好习惯):
(function($) {
var your_function = function() {
$(...);
};
setTimeout(function() {
your_function();
});
}(jQuery));
Using closures creates a sort of 'sandbox' for your code, so you don't have to worry about overwriting any variables declared in a parent scope (such as the dollar-sign $
used by jQuery). 使用闭包会为您的代码创建一种“沙箱”,因此您不必担心会覆盖在父作用域中声明的任何变量(例如jQuery使用的美元符号$
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.