1

我正在使用 PHP/MySQL 构建一个 CMS,到目前为止,我使用 jQuery 向表列添加排序和过滤。通常,它工作得很好,但有时排序和过滤元素不会加载 - 只有当我手动刷新页面时才会发生这种情况(从不通过链接访问它),而且只是有时。有时我可以在它发生之前刷新几次,而其他时候它可能会连续发生几次。

当问题发生时,Firebug 的控制台会告诉我以下一项或两项:

ReferenceError:未定义 jQuery

ReferenceError: $ 未定义
$(document).ready(function(){

(有时:TypeError: $(".tablesorter").tablesorter is not a function

当一切正常时,控制台是空白的。

我的头文件加载在 CMS 的所有页面上,开头是:

<?php ob_start(); ?>
<!DOCTYPE html>
<html>
<head>
    <meta name="robots" content="noindex">
    <title><?=$pg_title." - ".$site_name;?> | Lucid <?=$ver_num;?></title>
    <link href="/favicon.gif" rel="icon" />
    <link rel="stylesheet" href="css/styles.php" type="text/css" />
    <script src="js/jquery-1.8.3.min.js" async></script>
    <script src="plugins/jquery-tablesorter/js/jquery.tablesorter.min.js" async></script>
    <script src="plugins/jquery-tablesorter/js/jquery.metadata.js" async></script>
    <script src="plugins/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.min.js" async></script>
    <script src="js/picnet.table.filter.min.js" async></script>
</head>

然后在页脚文件中,我调用了各种函数:

 <script async>
    $(document).ready(function(){
        function validateNumber(event) {
            var key = window.event ? event.keyCode : event.which;

            if (event.keyCode == 8 || event.keyCode == 46
             || event.keyCode == 37 || event.keyCode == 39) {
                return true;
            }
            else if ( key < 48 || key > 57 ) {
                return false;
            }
            else return true;
        };
        $('[class=sort-order]').keypress(validateNumber);
        $(".tablesorter").tablesorter({ 
            textExtraction: 'complex'
        }); 
        var options = {
            filterDelay: 100,
            clearFiltersControls: [$('.filter-clear')]
        };
        $('.tablesorter').tableFilter(options);
        $('input:not(.filter)').live("change", function () {
            window.onbeforeunload = function () { return "Your changes have not been saved, if you leave the page you'll lose them" };
        });
    });
</script>
</body>
</html>
<?php 
ob_flush();
?>

我知道这是一个相当普遍的问题,但我觉得我已经尝试了所有解决方案(包括这里列出的那些:JQuery - $ is not defined

我尝试使用 setTimeout 将除 jQuery 之外的所有脚本的加载延迟最多一秒钟 - 没有帮助。

我试过检查 jQuery 是否是用 if(jQuery) 定义的——它总是这样。

Firebug 的 Net 选项卡显示 jQuery 文件的状态为 304 Not Modified,无论问题是否发生。

据我所知,我所有的拼写和语法都很好,应该认为它在大多数情况下都有效。

我尝试从外部网站而不是本地加载 jQuery - 没有区别。

我应该指出我正在使用 XAMPP 在本地开发 CMS,而不是远程服务器,所以我认为我的 apache 配置可能有问题。然后我将所有内容上传到远程服务器,发现问题更严重,这表明这与加载页面的速度有关,也许是异步?但我不知道在加载任何脚本之前我还能做些什么来确保 jQuery 加载......

4

1 回答 1

5

元素上的async属性script意味着 HTML 的解析可以在脚本被下载和评估之前继续。这意味着后续的脚本元素不能依赖于之前已经评估过的元素——这意味着您在 jQuery 之后加载的 jQuery 插件失败,因为尚未加载 jQuery。

具体来说:

<script src="js/jquery-1.8.3.min.js" async></script>

告诉浏览器你想要那个脚本,但不要等待它。然后:

<script src="plugins/jquery-tablesorter/js/jquery.tablesorter.min.js" async></script>

说同样的话。这设置了一个竞争条件,这两个脚本元素不再有任何顺序,因此有时第二个元素首先被评估。由于第二个需要 jQuery,因此失败了。

要修复它,您需要删除该async属性。如果您的目标是让页面更快地呈现,而无需等待脚本,请将所有脚本移动到末尾body(例如,就在之前</body>)。但请注意,这可能意味着用户在连接事件处理程序之前尝试与页面交互的短暂时刻等。

于 2012-12-01T11:36:17.333 回答