【问题标题】:Should a Javascript function be written and called inside jQuery document ready or outside?应该在 jQuery 文档内部还是外部编写和调用 Javascript 函数?
【发布时间】:2012-05-25 20:45:30
【问题描述】:

我只是有一个关于在 jQuery 中编写函数的问题。在定义自己的函数时,它们应该写在$(function(){}); 内部还是外部?请注意,这些只是示例函数,可以是任何函数。我选择了一个 jQuery 函数和一个原生 JavaScript,看看是否有任何区别,即是否应该在 document ready 中定义一个自定义的 jQuery 函数?

例如:

$(function(){
    $('select').jQueryExample();
    nativeExample();    
});

$.fn.jQueryExample = function(){
    //Do something
}

function nativeExample(a, b)
{   
    return a + b;
}

与此相反,它们在文档中被调用并定义好了吗?

$(function(){
    $('select').jQueryExample();
    nativeExample();

    $.fn.jQueryExample = function(){
        //Do something
    }

    function nativeExample(a, b)
    {   
        return a + b;
    }
});

::EDIT::

一个额外的问题。如果一个函数在文档就绪外部定义并且也称为外部文档就绪,那么与将它定义在外部但称为inside文档就绪相反会发生什么?

我问这个是因为我在文档就绪范围之外定义了一个函数,并且这个函数是一个 ajax 调用,它在页面加载时获取新消息。应该在外部或内部调用文档就绪?

例如:

$(function(){
 //Hello, I am jQuery

});

nativeExample();

function nativeExample(a, b)
{   
    return a + b;
}

相对于:

$(function(){

 nativeExample();

});


function nativeExample(a, b)
{   
    return a + b;
}

提前感谢您的回复。

【问题讨论】:

标签: javascript jquery function scope document-ready


【解决方案1】:

我认为你应该在 jQuery ready 方法之外定义你的函数,因为:

  • 函数定义代码是一个“被动”代码:它不需要运行 DOM
  • 如果你想在ready事件之前使用你的函数,如果函数是在事件内部定义的,你就不能这样做,
  • jQuery ready 方法应该只在真正需要的时候使用,这意味着当你*真的必须等待 DOM 准备好时

有关信息,这里有一个我每次都使用的简化但常见的 HTML 页面模式,它工作得很好:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Page title</title>
    <!-- your CSS code -->
    <link rel="stylesheet" href="/path/to/file.css">
</head>
<body>
    <!-- your HTML elements -->

    <!-- all your scripts elements at the bottom -->

    <!-- load jQuery from Google CDN -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

    <!-- load all your "passive" code that defines custom or vendor jQuery plugins -->
    <script src="jquery.plugins.js"></script>

    <!-- load all your "active" code -->
    <script src="yourcode.js"></script>
</body>
</html>

jquery.plugins.js 文件可能包含您提供的内容:

// define all jQuery plugin, aka "passive" code
// "passive" means it won't affect the page
$.fn.jQueryExample = function(){
    //Do something
};

$.fn.somePlugin = function(){
    // Do something
};

// you could define vanilla JavaScript functions in a separated file if you want
function nativeExample(a, b)
{
    return a + b;
}

文件yourcode.js 可能是:

// place here all "active" code
// by "active" code I mean all code that will interact/alter/modify your page
$(function(){
    $('select').jQueryExample();
    nativeExample();    
});

关于您的编辑,您的问题what would happen as opposed to having it defined outside but called inside document ready 没有通用答案。看这个例子:

<!-- basic html setup -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Page title</title>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>
        // placing <script> tag in the <head> tag is considered as a bad practice
        // I use it for the example but you should not do the same in real code

        // define your functionsin the <head> tag
        function getFoo() {
            return "foo";
        }
        function getAnchor() {
            return document.getElementsByTagName('a');
        }
    </script>

    <script>
        // reference: ONE
        // call your function in the <head> tag
        console.log( "one", getFoo() ); // "foo"
        console.log( "one", getAnchor() ); // empty array
    </script>
    <script>
        // reference: TWO
        $(document).ready(function(){
            // call your function inside the jQuery 'ready' event
            console.log( "two", getFoo() ); // "foo"
            console.log( "two", getAnchor() ); // array with one element
        });
    </script>
</head>
<body>

    <a href="www.example.com">bar</a>


    <script>
        // reference: THREE
        // call your function at the end of the <body> tag
        console.log( "three", getFoo() ); // "foo"
        console.log("three",  getAnchor() ); // array with one element
    </script>

    <script>
        // reference: FOUR
        $(document).ready(function(){
            // call your function inside the jQuery 'ready' event
            console.log( "four", getFoo() ); // "foo"
            console.log( "four", getAnchor() ); // array with one element
        });
    </script>
</body>
</html>

getFoo 函数不需要 DOM 来工作。因此,它的 4 次调用总是返回 'foo',因此无论何时何地调用她(在 'ready' 事件内部或外部),该函数都可以工作。

函数getAnchor查询DOM并返回页面中锚标记的集合。脚本“ONE”中的第一个调用位于ready 事件之外并返回未定义。第三次调用,在脚本“THREE”中,也在ready 事件之外它在控制台中记录了一组锚元素。这意味着,函数调用的位置可以改变函数的行为。在第一次调用中,显然页面中没有锚标记,这就是函数返回undefined 的原因。然后,放置在页面开头和结尾的第二次调用和第四次调用都记录了一个数组。在这种情况下,函数调用的位置不会改变函数的行为,因为函数 getAnchor 实际上是在所有 DOM 元素都加载后调用的。如果您查看控制台日志,您会看到如下内容:

one foo
one []

three foo
three [<a href=​"www.example.com">​bar​</a>​]

two foo
two [<a href=​"www.example.com">​bar​</a>​]

four foo
four [<a href=​"www.example.com">​bar​</a>​]

看日志顺序:一、三、二、四;这与源顺序不同:一、二、三、四。函数是ready 一直延迟到页面加载完成。

【讨论】:

  • 您好,谢谢您的回复。我在这个问题中了解了 javascript 文件(头部或正文之前)的位置:stackoverflow.com/questions/7751514/…。主要的 GoogleApi jQuery 应该在 head 中,而我的自定义 javascript 应该在 body 之前吗?
  • @JohnathanAu 我已更新我的答案以回复您的编辑。我认为我在这里发布的第一个模式是放置 JavaScript 文件的最佳方式(使用模块加载器时除外)。为什么你会在 head 中加载 jQuery 但只在 &lt;/body&gt; 之前使用它?在你想使用它之前包含jQuery,这意味着在&lt;/body&gt;之前。此外,IMO 最好将 script 标签组合在一起。
  • 非常全面的答案。谢谢:)
【解决方案2】:

当然——你可以在任何你想写的地方写你的函数。它们根本不需要在您的文档就绪功能中。我不喜欢用函数把它弄得乱七八糟,所以我只是把它们写在外面。您应该或不应该没有真正的理由;无论如何,这些功能应该可以工作。

我们的想法是,这些函数只会在您的 $(function(){});(document.ready 函数)中被调用。

一旦所有 HTML 元素(也称为 DOM)完全加载并且 jQuery 准备就绪,就会调用文档就绪函数。最佳实践 (IMO) 是最后加载 jQuery 文件 - 在所有自定义 JavaScript 文件和 css 文件之后。这样,只有在调用文档就绪函数后,您就可以 100% 确定所有文件都已加载并准备就绪。

<head>
  <link type="text/css" href="myStyle.css">
  <script type="text/javascript" src="myFunctions.js" ></script>
  <script type="text/javascript" src="myUtils.js" ></script>
  <script type="text/javascript" src="jquery-1.7.2.min.js" ></script>
</head>

您甚至可以将您的函数完全放在一个单独的文件中...只要您在满足所有依赖项之前不调用该函数就可以了。


re:您的编辑 -

一旦调用了文档就绪函数 - 您就可以在 JavaScript 中的任何位置使用 jQuery 方法。如果您的 AJAX 调用发生在您的文档准备好之前,它可能不知道如何实际执行请求(如果您使用的是 jQery AJAX 调用)。您必须从准备好的文档中调用该函数。只需将“页面加载”事件替换为文档准备就绪的回调 - 使其在 jQuery 准备就绪后加载新消息。

【讨论】:

  • 您好,谢谢您的回复。非常感谢:) 虽然,一件事。页面加载事件是什么意思?我主要使用 $.post 和 $.getJSON
  • 你说"...an ajax call which gets new messages on page load"。我不确定你指的是window.onLoad()
  • 哦,对不起>_
猜你喜欢
  • 2019-09-23
  • 2020-11-01
  • 2018-06-30
  • 1970-01-01
  • 2011-08-06
  • 2021-01-05
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
相关资源
最近更新 更多