jQuery未在函数中定义

时间:2015-04-13 20:26:06

标签: javascript jquery html5

好吧,这是一个益智游戏。我有一个jQuery函数,通过.fadeIn / .fadeOut显示一个PHP生成的网站公告列表;页面上加载的第一件事是来自CDN的jQuery 1.11.xx。我正在运行Bootstrap,fullCalendar,SmartMenus等,而jQuery绝对是加载的。

除了在setInterval()内更新公告。这是粗略的代码,有些功能不存在,但在我看来它应该是动画。

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);   

相反,当我运行页面时,我在setInterval()中调用的任何jQuery函数都会出现“函数未定义”错误。如果我使用document.getElementById('announcementArea')。innerHTML =等来调用它,它可以工作,但是通过DOM操作进行淡入/淡出似乎比jQuery可用时需要更多的工作并且在页面上的其他地方工作

我已经尝试了一些范围调整,并且一直致力于过去5小时应该是简单的代码。那么,我的明显错误在哪里? ;)

3 个答案:

答案 0 :(得分:2)

不确定您遇到了哪种范围问题(看起来它是未发布代码的结果,因为您问题中的所有内容看起来都不错),但如果您想要一种相当简单的传递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);   

根据您更新的答案,这是另一种可能的解决方案:

(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));

$被定义为函数参数,因此会覆盖函数体内的全局范围$,保护它对代码的定义。这实际上正是jQuery recommends when creating an extension

答案 1 :(得分:0)

我之前的回答 - 抓住了:

问题更有趣 - 在SmartMenu插件和LibraryThing书籍显示小部件之间,创建了一个jQuery冲突。这解释了为什么 - 取决于加载顺序 - 不同的部分会破坏,但总是setInterval(),它总是在SmartMenu和LibraryThing之后加载。

所以,我有点凌乱的解决方案是在脚本开头发布$并在最后回收它,以便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();

答案 2 :(得分:0)

使用闭包(无论如何这被认为是好的做法):

(function($) {

    var your_function = function() {
        $(...);
    };

    setTimeout(function() {
        your_function();
    });

}(jQuery));

使用闭包创建了一种沙盒'对于你的代码,所以你不必担心覆盖父作用域中声明的任何变量(例如jQuery使用的dollar-sign $)。