9

私はそれを理解していません。私は検索して検索しましたが、これについては何が「正しい」のかわかりません。

3 つの例があります。

1) Fiddle 1.0 ここにはhtmlwith がonlick="function"あり、javascriptそこにも関数があり、正常に動作します

 <span class="classic one"   onclick="someFunction(this,'one')">CLICK HERE</span>

 <script type="text/javascript">
    function someFunction(obj,nr) {
        var string = $(obj).attr('class');
        $('.result').text( string );
    }
</script>

2) Fiddle 2.0 次に、関数をスクリプト セクションに移動すると (一種の .js ファイルに移動します)、「ReferenceError: someFunction が定義されていません」というエラーが表示されます。

ここから質問が始まります

3)フィドル 3 これで、.on(click で常に正常に動作するドキュメント準備完了関数が呼び出されました。この関数は、docuemnt.ready() の外部にある別の関数を呼び出しており、正常に動作します。

それで質問です。関数を定義する必要があるのはいつですか? AND WHY 常に機能しますか?

ありがとうございました!

例 3) のすべてのコードは次のようになります。

<div class="result">result</div>

    <span class="classic one"   onclick="someFunction(this,'one')">CLICK HERE</span>
    <span class="classic two"   onclick="someFunction(this,'two')">CLICK HERE</span>
    <span class="classic three" onclick="someFunction(this,'three')">CLICK HERE</span>
    <span class="classic four"  onclick="someFunction(this,'four')">CLICK HERE</span>

<div class="ready">ready</div>


<span class="callOtherFunction">Call other function</span>


<script type="text/javascript">
    $(document).ready(function(){
        $('.ready').text( 'dom is ready' );

        function someFunction(obj,nr) {
                var string = $(obj).attr('class');
                $('.result').text( string );
            }

         $( "span.callOtherFunction" ).on({
            click: function() {
                $(this).css("color","red");
                $(this).addClass("xyz");
                otherFunctionCallingFunction($(this));
            }
        });

    });

    function otherFunctionCallingFunction($me) {
        $('.callOtherFunction').append( ' --> ' + $me.attr('class') );
    }
</script>
4

2 に答える 2

16

多くの場合、jsFiddle の非常に驚くべきデフォルト設定 (スクリプト ペイン内のコードをonloadハンドラーでラップする) が原因です。onclickしたがって、コードは関数にラップされ、グローバル スコープではなくなります (これは、 -style 属性を使用する場合に関数が必要な場所です)。これは、左側のドロップダウン ボックス (ライブラリとスクリプトのリストの下にある 2 つ目) で変更できます。コードをアンラップするには、「ラップなし」に変更します。

この驚くべきデフォルトに苦しめられたのは (断然!) あなたが最初ではありません。


あなたの主な質問に答える:

$(document).ready() に関数がある場合

scriptスクリプトをロードするタグの場所を制御する場合、基本的にready;を使用する必要はありません。代わりに、scriptタグがHTMLの最後</body>、終了の直前にあることを確認してください。

もちろん使えますreadyこれは、コードを実行する前にすべての DOM 要素が作成されていることを確認するためです。しかし、scriptタグを最後に置くと、それはすでに真実です。ハンドラーの外部で関数を定義することもできますがready(関数をグローバルにしたい場合)、 を使用している場合は、ハンドラーから関数ready呼び出しready、要素が存在するようにします。


FWIW、onclick主にグローバル関数を作成する必要があるため、イベントハンドラーを接続するために -style 属性を使用することは避けます。回避できる場合は、グローバル シンボルの作成を避けることを好みます。

私がお勧めする一般的な形式:

<!-- ...your page markup here... -->
<script src="any_libraries_you_need_if_you_are_not_combining.js"></script>
<script src="your_script.js"></script>
</body>
</html>

スクリプトは次のようになります。

(function($) { // A scoping function that wraps everything
    // Hook up event handlers here. You can use `$` for jQuery, even if
    // you've used noConflict, because we have a private `$` symbol (see
    // the `$` argument above)

    // The body of your code goes here

})(jQuery); // <== Note how we're passing the jQuery reference in
            // and immediately executing the scoping function

完全な例を次に示します:ライブコピー

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Script Placement Example</title>
</head>
<body>
  <input type="button" class="hello-button" value="Click me">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
  <script>
    // This would be in a file, rather than inline
    (function($) {
      // Hook up handlers
      $(".hello-button").click(sayHello);

      // Body of the code
      function sayHello() {
        $("<p>Hello!</p>").appendTo(document.body);
      }
    })(jQuery);
  </script>
</body>
</html>
于 2013-09-25T08:19:19.867 に答える
3

JavaScript では、スコープは関数ごとに処理されます。関数のスコープ内のすべてのものは、その関数のスコープ内の他のものと、より広いスコープ内のものにアクセスできます。

関数内で変数を定義するとvar、その変数のスコープが関数に制限されます。

別の関数内で関数宣言を使用して関数を定義すると、定義された関数のスコープがコンテナー関数に制限されます。

を使用するときはready、それに関数を渡します。もちろん、その関数で定義されたものはすべて、その関数にスコープされます。その関数にスコープが設定されているため、グローバルではありません。onclick 属性はその関数のスコープ内で定義されていません。グローバルにしかアクセスできません。これが、参照エラーが発生する理由です。

グローバルは避けてください。それらは物事を維持するのを難しくします。属性は避けonclickてください。通常はグローバルに依存します。

readyDOM が完全に構築された後にコードを実行する場合に使用する必要があります。これは、JS を使用してイベント ハンドラーを要素にバインドする場合に便利です (例: を使用jQuery.on)。onclick属性を使用するのではなく、これを行ってください。

于 2013-09-25T08:22:03.423 に答える