【问题标题】:$ is not a function error after AJAX call$不是AJAX调用后的函数错误
【发布时间】:2014-08-25 14:31:46
【问题描述】:

我正在向 WordPress 网页添加无限滚动功能。我正在使用 jQuery 使用以下代码向每三个内容项添加一个类,没有任何问题:

jQuery(document).ready(function($) {
    $(".leden li:nth-child(3n)").addClass('last');
});

在发现上面的代码在 AJAX 调用后没有执行以显示动态内容后,我添加了以下代码:

jQuery(document).ajaxComplete(function($) {
    $(".leden li:nth-child(3n)").addClass('last');  
});

我不确定这是否是在 AJAX 之后使用 jQuery 添加类的正确方法,但似乎 Firebug 在向下滚动页面并动态加载内容后仅显示以下控制台错误:

TypeError: $ is not a function

这让我作为一个 JavaScript/jQuery 新手感到困惑,因为为什么只有在使用相同格式的第二个 jQuery 片段时才会显示错误?据我所知,我只使用了不同的偶数处理程序......

我做错了什么,而且,在使用 AJAX 动态添加内容时,这是执行 jQuery 的正确方法吗?

【问题讨论】:

    标签: jquery ajax


    【解决方案1】:

    当你这样做时:

    jQuery(document).ajaxComplete(function($) {
    

    你在函数范围内声明了一个变量$,隐藏了外部声明jQuery)。当您不向函数传递任何参数时,此变量的值为 undefined

    做吧

    jQuery(document).ajaxComplete(function() {
    

    如果您想将jQuery 别名为$,请将您的整个代码放在这样的函数调用中:

    (function($){
       $(document).ajaxComplete(function() {
          $(".leden li:nth-child(3n)").addClass('last');  
       });
       // the rest of your code using $ goes here
    })(jQuery);
    

    【讨论】:

    • +1 不仅显示了修复,还清楚地描述了问题所在。
    • 这确实解决了控制台中的错误,但不知何故,该类并未应用于动态添加内容的每第三项。似乎它的应用取决于向下滚动时加载的许多项目,从而触发无限滚动行为。
    • $ 如果$ 首先提到 jQuery,则将是“隐藏 jQuery 的外部声明”,但由于这是一个 Wordpress 站点,jQuery 可能以 noConflict 模式加载,所以$ 只是未定义(或者可能是对 MooTools 或其他东西的引用)。否则很好的答案。
    【解决方案2】:

    针对您的问题,“在使用 AJAX 动态添加内容时,这是执行 jQuery 的正确方法吗?”我会说不,因为ajaxComplete 用于指定在任何 ajax 结果返回后会发生什么,所以如果您的页面上有任何其他 ajax 代码,或者如果您将来添加任何插件或任何也使用 ajax 的东西,那么ajaxComplete 代码也会为其他 ajax 调用运行。

    典型的 ajax 调用看起来更像这样,在更新内容后在 done() 回调中添加代码。

    $.ajax({
        type: "GET",
        url: "some.php",
        dataType: "json"
    })
    .done(function(data) {
        //example code to set content on the page
        $('#someDiv').html( data.someHtml );
    
        //your code
        $(".leden li:nth-child(3n)").addClass('last');  
    });
    

    回答您关于$ 不起作用的问题:

    更新

    由于您在评论中说 Ajax 调用发生在 document.ready 之前,ajaxComplete 内部的调用 document.ready 将发生得太晚。所以就用这个:

    jQuery(document).ajaxComplete(function() {
        jQuery(".leden li:nth-child(3n)").addClass('last');
    });
    

    这当然等同于:

    jQuery(document).ajaxComplete(function() {
        var $ = jQuery;
        $(".leden li:nth-child(3n)").addClass('last');
    });
    

    ...但是声明 $ 对于一行代码来说是多余的。


    您可能在“无冲突”模式下加载了 jQuery。在此模式下,您可以使用一个方便的技巧使 $document.ready 中可用,这就是您正在使用的 - jQuery(document).ready(function($) { ...。但是你不能用ajaxComplete 做到这一点,此外,如果你把代码放在document.ready 回调中,你已经有$ 可用。我建议您像这样构建您的代码:

    jQuery(document).ready(function($) {
        $(document).ajaxComplete(function() {
            $(".leden li:nth-child(3n)").addClass('last');
        });
    });
    

    或者,如果您不需要在 document.ready 上运行其他代码,那么您可以像其他答案所建议的那样单独使用 ajaxComplete 函数。

    更多详情:http://api.jquery.com/jquery.noconflict/

    【讨论】:

    • 为什么投反对票?使用$ 作为document.ready 函数的参数是完全有效的,实际上建议在noConflict 模式的jQuery 文档中这样做:api.jquery.com/jquery.noconflict
    • 确实如此,但是您假设 jQuery 运行在 noConflict 模式下,这在任何地方都没有提到。主要问题是局部范围的$ 变量(参数)会掩盖任何存在的全局$ 变量。所以Conflict或noConflict,是需要修正的参数。剩下的就是猜测了。顺便说一句,没有投反对票。
    • OP 提到它是一个 Wordpress 站点,所以 jQuery 将在 noConflict 模式下运行,除非 OP 更改它。但有效点 - 即使不在 noConflict 模式下,原始代码仍然会失败。
    • 是的,它在 noConflict 模式下运行,但您的解决方案仅在 Ajax 调用之后执行 jQuery,而不是不幸之前。
    • “您的解决方案只在 Ajax 调用之后执行 jQuery,不幸的是之前没有执行” - 你的意思是什么?
    【解决方案3】:

    由于您在 Wordpress 中以 noConflict 模式运行:

    jQuery(document).ready(function($) {
        // Code that uses jQuery's $ can follow here.
    
        $(document).ajaxComplete(function() {
            $(".leden li:nth-child(3n)").addClass('last');
        });
    });
    
    // Code that uses other library's $ can follow here.
    // If there is no other library named $ then you will get a TypeError: $ is not a function
    

    您始终可以使用$ = jQuery; 之类的操作,或使用jQuery 名称代替$

    【讨论】:

    • 如果 jQuery 已经在 noConflict 模式下加载,这将不起作用,因为它是一个 Wordpress 站点,并且 noConflict 模式是 Wordpress 的默认模式,因此可能就是这种情况。
    • 如果您想这样做,您必须将其更改为jQuery(".leden li:nth-child(3n)").addClass('last');,因为$ 未定义。请参阅我的答案以获取另一种选择。
    • 嗯,这就是我在最初的回答中的想法,但 OP 说它仍然不起作用。显然 ajax 调用发生在页面甚至完成加载之前(即在 document.ready 被触发之前。)
    【解决方案4】:
    • 首先检查$ 是否在调用之前实际设置。你用jQuery 而不是 $ 在您的通话中,所以它可能不会被设置。
    • 如果已设置 然后删除参数。该函数的内容将有一个 已包含 $ 的 JavaScript 闭包。

    【讨论】:

      【解决方案5】:

      $ = jQuery;

      所以,既然您使用的是 WordPress,WordPress 会强制 jQuery 使用 jQuery 而不是 $

      因此,您的错误出现是因为 $ 未定义。

      您可以通过在包含 jQuery 脚本后立即添加 $ = jQuery 来解决此问题,前提是您没有使用任何其他将自身用作 $ 的库(这就是 WP 首先这样做的原因)-否则,您应该将 $ 替换为 jQuery

      希望能帮助你理解。

      【讨论】:

      • "WordPress 强制 jQuery 成为 jQuery 而不是 $"。我不会肯定你错了,因为我不知道 WordPress,但你确定吗?有参考吗?
      • @dystroy Wordpress 在默认情况下肯定会在 noConflict 模式下加载 jQuery。这里甚至还有一个关于如何禁用此行为的问题:stackoverflow.com/questions/17687619/…
      • 我猜 OP 正在为他的网站编写自定义代码,但请注意,如果您正在编写打算与他人共享的 Wordpress 插件,则应避免这种情况,因为其他网站可能确实将$ 定义为 MooTools 或其他东西。因此,如果您正在编写插件,最好只在闭包中执行 $ = jQuery,而不是“在包含 jQuery 脚本之后”。
      猜你喜欢
      • 2023-04-07
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      相关资源
      最近更新 更多