11

PHP スクリプトでタブ付きの jQuery ダイアログを作成しています。このスクリプトは、ループ内で「include」ディレクティブを使用し、タブを繰り返し、他のスクリプトを含めます。含まれている各ファイルには、タブのデータと、jQuery の document.ready() 関数を含む <script> タグが含まれています。ループがなければ、基本的にこれを行います:

<div id="tabDialog">
  <div id="tabs">
    <ul>
      <li><a href="#tab1'>Tab1</a></li>
      <li><a href="#tab2'>Tab2</a></li>
    </ul>
    <div id="tabContainer">
      <div id="tab1">
        <?php include "tab1.php"; ?>
      </div>
      <div id="tab2">
        <?php include "tab2.php"; ?>
      </div>
    </div>
  </div>
</div>

たとえば、tab1.php には次のようなものがあります。

<script type="text/javascript">
   $(document).ready (function () {
       alert ('tab1 loaded');
   });
</script>

問題は、ダイアログの DIV として <div id="dialog"> を使用してダイアログを作成して開くと、ドキュメントの準備完了関数が 2 回呼び出されることです。ダイアログコードは次のとおりです。

 $("#tabDialog").dialog ({
   autoOpen: false,
   minWidth: 450,
   minHeight: 400,
   width: 600,
   height: 500
 }).dialog ('open');

これの原因は何ですか?また、状況を改善する最善の方法は何でしょうか? 各タブの機能を別々のファイルに保持しようとしています。それらは複数の状況で使用でき、それらに関連付けられたコードを複製する必要がないからです。

助けやアドバイスをありがとう。

4

7 に答える 7

9

私はその理由を見つけ、かなり良い修正を作成したと信じています。jQuery がダイアログを作成するとき、ダイアログのコンテンツを含む DIV を DOM 内で (ドキュメントの最後まで) 移動し、その div をダイアログが必要とする必要な足場で囲みます (おそらく .append( を使用して) ) 関数または類似のもの)。動的に実行されていた DIV には Javascript が含まれていたため、jQuery は DIV が DOM に再配置された後 (つまり 2 回目) に document.ready() 関数を呼び出していました。したがって、ダイアログを作成する前に、次のようにダイアログの DIV 内のすべてのスクリプト タグを .remove() します。

    $("#tabDialog").find ("script").remove ();
    $("#tabDialog").dialog ({
      autoOpen: true,
      minWidth: 450,
      minHeight: 400,
      width: 600,
      height: 500
    });

これを行うと、最初に読み込まれた DIV から SCRIPT タグが削除されますが、SCRIPT 自体はまだ存在します。動的にロードされた Javascript コードが実際に「生きている」場所を完全には理解していないため、これについてはまだ調査中ですが、DOM の外側のどこかにあると思われます。Chrome、Firefox、および Exploder 8 でこれを確認しました。

DIV にボタンを配置し、.click() 関数を割り当てることで、読み込まれた DIV 内に元々含まれていたスクリプトが期待どおりに機能することを確認しました。これを示す小さなテストを次に示します。

<html>
  <head>
    <link href="css/redmond/jquery-ui-1.8.1.custom.css" type="text/css" rel="stylesheet" media="screen" />
    <link href="css/style.css" type="text/css" rel="stylesheet" media="screen" />

    <script src="js/jquery-1.4.2.js" type="text/javascript"></script>
    <script src="js/jquery-ui-1.8.1.custom.min.js" type="text/javascript"></script>
  </head>

  <body>
    <div id="dialogContents" style="display: none;">
      <div  style="border: 1px solid black; height: 98%;">
        <form id="testForm">
          <input type="text">
        </form>
        <button id="testButton">Test</button>
        <script type="text/javascript">
          $(document).ready (function () {
            alert ("ready");

            $("#testButton").click (function () {
              alert ('click');
            });
          });
        </script>
      </div>
    </div>
  </body>

  <script type="text/javascript">
    $(document).ready (function () {
      //
      // Remove all the scripts from any place in the dialog contents.  If we
      // do not remove the SCRIPT tags, the .ready functions are called a
      // second time.  Removing this next line of Javascript demonstrates this.
      //
      $("#dialogContents").find ("script").remove ();
      $("#dialogContents").dialog ({
        width: 300,
        height: 300,
        title: 'Testing...'
      });
    });
  </script>

</html>

このスレッドで人々が提供してくれた助けに感謝します!

于 2010-07-01T13:01:08.550 に答える
1

私もこの問題を抱えていましたが、私の場合の原因は別のものでした。ダイアログホルダーとして使用された div 内に自己終了 div 要素がありました。自己終了要素を終了タグに置き換えたところ、予想どおり、ドキュメントの準備完了関数が 2 回の起動を停止し、1 回だけ起動しました。

たとえば、これにより、ドキュメントの準備完了関数が 2 回起動されました。

$("#foo").dialog({
  // ...
});

...

<div id="foo" title="My Dialog">
  <div id="bar" />
</div>

これはドキュメントの準備ができた関数を一度だけ起動しました:

$("#foo").dialog({
  // ...
});

...

<div id="foo" title="My Dialog">
  <div id="bar"></div>
</div>
于 2011-03-31T17:08:54.823 に答える
1

あまり使っていませんが、スクリプトで jQuery のメソッド.dialog()を使用する必要はありますか?ready()

.dialog()利用できるコールバック オプションがあるようです。

タブ内のスクリプト:

    <script type="text/javascript">
        function onOpen() { alert('tab1 loaded') };
    </script>

ダイアログ:

$(this).dialog ({
    autoOpen: false,
    minWidth: 450,
    minHeight: 400,
    width: 600,
    height: 500,
    open: function(event, ui) { onOpen(); } // call function in script
}).dialog ('open');
于 2010-07-01T01:26:38.297 に答える
1

したがって、ダイアログが独自の状態を維持していることを理解しているにもかかわらず、なぜそれが起こっているのか100%確信が持てないので、これが理由の1つである可能性があると言わざるを得ません。しかし、私は道を外れている可能性があります。しかし、それを回避する方法は、代わりに次のようなものを使用することです。

$(document).one('ready', function () {
   alert ('tab1 loaded');
});

これにより、ページの読み込み時に一度だけ実行されるようになります。

于 2010-07-01T01:58:31.317 に答える
0

おそらく .dialog('open') 呼び出しは必要ありません。代わりにオプションautoOpen : true を使用してください。

于 2010-07-01T01:08:42.800 に答える
0

スクリプトをcreateメソッドに入れます:

$.dialog({
    <your parameters>
    create: function() {
        <your script>
    }
}

この方法では、スクリプトが 1 回だけ呼び出され、ダイアログを作成するのは 2 回ではありません!

于 2013-07-18T10:43:57.553 に答える
0

ページの結果のテキストを次に示します。ソースを表示してから、ページから不要なものを削除して、ページをシンプルにしました。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
    <head>
        <link href="css/redmond/jquery-ui-1.8.1.custom.css" type="text/css" rel="stylesheet" media="screen" />
        <link href="css/style.css" type="text/css" rel="stylesheet" media="screen" />
        <script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
        <script src="js/jquery-ui-1.8.1.custom.min.js" type="text/javascript"></script>
    </head>

    <body>
        <div id="tabDialog" style="position: relative; display: none;" title="Test Dialog">
            <div id="tabs" style="position: absolute; top: 5px; bottom: 40px; left: 3px; right: 3px;">
                <ul>
                    <li><a href='#tab1'>Tab #1</a></li><li><a href='#tab2'>Tab #2</a></li>
                </ul>

                <div class="tab_container" style="position: absolute; top: 35px; bottom: 0px; left: 1px; right: 1px; overflow: auto;">
                    <div id='tab1' class='tabPage ui-dialog-content'>
                        <form id="tab1Form">
                            More testing... <input class="keypressMonitor" type="text">
                        </form>
                        Testing...<br/>
                        Testing...<br/>

                        <script type="text/javascript">
                            $(document).ready (function () {
                                alert ('tab1 loaded');
                                $("#tab1Form").bind ('save', function () {
                                    alert ("in tab1Form.save ()");
                                });
                            });
                        </script>
                    </div>

                    <div id='tab2' class='tabPage ui-dialog-content'>
                        <form id="tab2Form">
                            <div style="position: absolute; left: 1px; right: 1px; top: 1px; bottom: 1px;">
                                Testing: <input class="keypressMonitor" type="text">

                                <textarea id="testArea" class="keypressMonitor tinymce" style="position: absolute; top: 30px; bottom: 2px; left: 2px; right: 2px;"></textarea>
                            </div>
                        </form>

                        <script type="text/javascript">
                            $(document).ready (function () {
                                $("#tab2Form").bind ('save', function () {
                                    alert ("in tab2Form.save ()");
                                });
                            });
                        </script>
                    </div>
                </div>
            </div>

            <div id="dialogButtons" style="position: absolute; bottom: 3px; left: 3px; right: 15px; text-align: right; height: 32px;">
                <button class="applyButton" disabled>Apply</button>
                <button class="okButton" disabled>Ok</button>
                <button class="cancelButton">Cancel</button>
            </div>
        </div>

        <script type="text/javascript">
            $(document).ready (function () {
                $("#tabs").tabs ();
                $("button").button ();

                /**
                 * Pressing the cancel button simply closes the dialog.
                 */
                $(".cancelButton").click (function () {
                    $("#tabDialog").dialog ("close");
                });

                $("#tabDialog").dialog ({
                    open: function () {
                    },
                    autoOpen: true,
                    minWidth: 450,
                    minHeight: 400,
                    width: 600,
                    height: 500,
                    height: 'auto'
                });
            });
        </script>
    </body>
</html> 
于 2010-07-01T02:11:27.937 に答える