jQuery ready function being called twice in a dialog
我正在用 PHP 脚本中的选项卡构建一个 jQuery 对话框。该脚本在循环内使用 \\'include\\' 指令,遍历选项卡并包括其他脚本。每个包含的文件都有选项卡的数据和一个带有 jQ??uery document.ready() 函数的标签。没有循环,它基本上是这样做的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <ul> <li> Tab1 </li> <li> Tab2 </li> </ul> <?php include"tab1.php"; ?> <?php include"tab2.php"; ?> |
,例如,tab1.php 可能有类似:
1 2 3 4 | <script type="text/javascript"> $(document).ready (function () { alert ('tab1 loaded'); }); |
问题是,在使用作为对话框的 DIV 创建和打开对话框时,会再次调用文档的就绪函数。这是对话框代码:
1 2 3 4 5 6 7 | $("#tabDialog").dialog ({ autoOpen: false, minWidth: 450, minHeight: 400, width: 600, height: 500 }).dialog ('open'); |
造成这种情况的原因是什么?解决这种情况的最佳方法是什么?我试图将每个选项卡的功能保存在单独的文件中,因为它们可以在多种情况下使用,并且我不必复制与它们关联的代码。
感谢您的帮助或建议。
我相信我已经找到了原因并制定了一个相当不错的解决方案。当 jQuery 创建对话框时,它会在 DOM 中移动包含对话框内容的 DIV(到文档的最后),并用对话框所需的必要脚手架包围该 div(可能使用 .append( )功能或类似的东西)。因为动态的 DIV 中包含 Javascript,所以 jQuery 在 DIV 重新定位到 DOM 后(即第二次)调用 document.ready() 函数。因此,在构建对话框之前,我 .remove() 对话框 DIV 中的每个脚本标记,如下所示:
1 2 3 4 5 6 7 8 | $("#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 中的任何脚本仍然可以按预期运行。这是一个小测试来证明这一点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <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 src="js/jquery-ui-1.8.1.custom.min.js" type="text/javascript"> </head> <body> <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'); }); }); </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...' }); }); </html> |
感谢大家在本帖中提供的帮助!
我也遇到了这个问题,但在我的情况下,原因是不同的。我在 div 内有一个自动关闭的 div 元素,用作对话框支架。当我用关闭标签替换自关闭元素时,文档就绪函数停止触发两次,并且只触发一次,正如预期的那样。
例如,这会导致文档就绪函数触发两次:
1 2 3 4 5 | $("#foo").dialog({ // ... }); ... |
而这仅触发了一次文档就绪功能:
1 2 3 4 5 | $("#foo").dialog({ // ... }); ... |
所以我不得不说我不是 100% 确定它为什么会发生,即使我知道对话框确实保持它自己的状态,所以这可能是原因之一。但我可能会走得很远。但是解决它的方法是改用这样的东西:
1 2 3 | $(document).one('ready', function () { alert ('tab1 loaded'); }); |
这将确保它只在页面加载时运行一次。
看起来
标签中的脚本:
1 2 | <script type="text/javascript"> function onOpen() { alert('tab1 loaded') }; |
对话框:
1 2 3 4 5 6 7 8 | $(this).dialog ({ autoOpen: false, minWidth: 450, minHeight: 400, width: 600, height: 500, open: function(event, ui) { onOpen(); } // call function in script }).dialog ('open'); |
将你的脚本放入
1 2 3 4 5 6 | $.dialog({ <your parameters> create: function() { <your script> } } |
使用此方法,您的脚本仅在您创建对话框时被调用一次,而不是两次!
这是页面的结果文本。我做了一个查看源代码,然后从页面中删除了所有无关的内容以尝试使其更简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <!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 src="js/jquery-ui-1.8.1.custom.min.js" type="text/javascript"> </head> <body> <ul> <li> Tab #1 </li> <li> Tab #2 </li> </ul> <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 ()"); }); }); <form id="tab2Form"> Testing: <input class="keypressMonitor" type="text"> <textarea id="testArea" class="keypressMonitor tinymce" style="position: absolute; top: 30px; bottom: 2px; left: 2px; right: 2px;"></textarea> </form> <script type="text/javascript"> $(document).ready (function () { $("#tab2Form").bind ('save', function () { alert ("in tab2Form.save ()"); }); }); <button class="applyButton" disabled>Apply</button> <button class="okButton" disabled>Ok</button> <button class="cancelButton">Cancel</button> <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' }); }); </body> </html> |
您可能不需要 .dialog(\\'open\\') 调用;使用选项 autoOpen : true 代替。