jQuery 就绪函数在对话框中被调用两次

发布于 2024-09-07 13:50:10 字数 1205 浏览 7 评论 0原文

我正在 PHP 脚本中构建一个带有选项卡的 jQuery 对话框。该脚本在循环内使用“include”指令,迭代选项卡并包含其他脚本。每个包含的文件都具有选项卡的数据和一个

<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,文档的ready函数被第二次调用。以下是对话框代码:

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

造成这种情况的原因是什么以及补救这种情况的最佳方法是什么?我试图将每个选项卡的功能保留在单独的文件中,因为它们可以在多种情况下使用,并且我不必复制与它们关联的代码。

感谢您的任何帮助或建议。

I am building a jQuery dialog with tabs in a PHP script. The script uses the 'include' directive inside of a loop, iterating over the tabs and including the other scripts. Each of the included files has the data for the tab and a <script> tag with a jQuery document.ready() function in it. Without the loop, it essentially does this:

<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>

and, for example, tab1.php might have something like:

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

The problem is, upon creating and opening the dialog using the <div id="dialog"> as the dialog's DIV, the document's ready function is called a second time. Here is the dialog code:

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

What is the cause of this and what would be the best way to remedy the situation? I'm trying to keep each tab's functionality in separate files because they can be used in multiple situations and I don't have to replicate the code associated to them.

Thanks for any help or advice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

溺孤伤于心 2024-09-14 13:50:10

我相信我已经找到了原因并创建了一个相当好的修复方案。当 jQuery 创建对话框时,它会在 DOM 中移动包含对话框内容的 DIV(到文档的最后),并用对话框所需的必要支架包围该 div(可能通过使用 .append( )函数或类似的东西)。因为动态的 DIV 中包含 Javascript,所以在 DIV 在 DOM 中重新定位后(即第二次),jQuery 会调用 document.ready() 函数。因此,在构建对话框之前,我会像这样 .remove() 对话框 DIV 中的每个脚本标记:

    $("#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>

我感谢人们在该线程中提供的帮助!

I believe I've found the reason and created a reasonably good fix. When jQuery creates the dialog, it moves the DIV that contains the contents of the dialog around in the DOM (to the very end of the document) and surrounds that div with the necessary scaffolding that a dialog requires (probably by using the .append() function or something similar). Because the DIV which was being dynamically had Javascript contained within it, jQuery was calling the document.ready() function after the DIV was relocated in the DOM (i.e. a second time). Therefore, prior to building the dialog, I .remove() every script tag within the dialog's DIV like this:

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

Doing this removes the SCRIPT tag from the DIV which it was originally loaded in, but the SCRIPT itself still exists. I'm still researching this because I don't completely understand where the Javascript code that was dynamically loaded actually "lives," but I suspect it's located somewhere outside of the DOM. I verified this in Chrome, Firefox, and Exploder 8.

I verified that any scripts that were originally contained within the loaded DIVs still function as expected by putting a button in the DIV and assigning a .click() function. Here is a small test that demonstrates this:

<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>

I appreciate the help people provided in this thread!

╰沐子 2024-09-14 13:50:10

我没有太多使用.dialog(),但是你需要在脚本中使用jQuery的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');

I haven't used .dialog() too much, but do you need to use jQuery's ready() method in your script?

Looks like .dialog() has callback options you could take advantage of.

Script in tab:

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

dialog:

$(this).dialog ({
    autoOpen: false,
    minWidth: 450,
    minHeight: 400,
    width: 600,
    height: 500,
    open: function(event, ui) { onOpen(); } // call function in script
}).dialog ('open');
怎会甘心 2024-09-14 13:50:10

所以我不得不说,我不能 100% 确定为什么会发生这种情况,尽管我知道对话框确实维持了它自己的状态,所以这可能是原因之一。但我可能还差得很远。但解决这个问题的方法是使用类似这样的东西:

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

这将确保它在页面加载时只运行一次。

So I have to say that I am not 100% sure why it is happening even though I understand that the dialog does maintin it's own state so this might be one of the reasons. But I could be way off. But the way to get around it is to use something like this instead:

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

This will make sure that it only runs once when the page loads.

冷情 2024-09-14 13:50:10

我也遇到了这个问题,但我的情况的原因有所不同。我在 div 内部有一个自动关闭的 div 元素,用作对话框支架。当我用结束标签替换自闭合元素时,文档就绪函数停止触发两次,只触发一次,正如预期的那样。

例如,这导致文档就绪函数触发两次:

$("#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>

I also had this problem, but the cause in my case was something different. I had a self-closing div element inside of the div that was used as the dialog holder. When I replaced the self-closing element with a closing tag, the document ready function stopped firing twice and only fired once, as expected.

For example, this caused the document ready function to fire twice:

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

...

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

Whereas this only fired the document ready function once:

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

...

<div id="foo" title="My Dialog">
  <div id="bar"></div>
</div>
煮茶煮酒煮时光 2024-09-14 13:50:10

您可能不需要 .dialog('open') 调用;使用选项 autoOpen : true 代替。

You probably don't need the .dialog('open') call; use the option autoOpen : true instead.

删除会话 2024-09-14 13:50:10

这是页面的结果文本。我做了一个查看源代码,然后从页面中删除了所有无关的内容,以尝试使其更简单。

<!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> 

Here's the resulting text of the page. I did a view-source and then removed any extraneous stuff from the page to try and make it simpler.

<!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> 
初见 2024-09-14 13:50:10

将您的脚本放入 create 方法中:

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

使用此方法,您的脚本仅在您创建对话框时被调用一次,而不是两次!

Puts your script into create method:

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

With this method your script is called once only you create the dialog, not twice!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文