草庐IT

关于 php:jQuery 就绪函数在对话框中被调用两次

codeneng 2023-03-28 原文

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');

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

感谢您的帮助或建议。

  • 有什么方法可以添加更多代码以查看更多正在发生的事情?仅此一点很难弄清楚。
  • 因为你在一个循环中,你确定你没有在 html 中多次使用 ID tabDialog 吗?在这种情况下,它将触发每个#tabDialog div 的事件。
  • 发生这种情况是因为包括脚本块在内的内容被移动到正文的末尾(并再次执行)......虽然我不确定纠正这个问题的最佳方法,但所有这些的脚本可以不包含在一个单一的外部文件?
  • 看来你有令人讨厌的 javascript。这可能会有所帮助——stackoverflow.com/questions/3142504/


我相信我已经找到了原因并制定了一个相当不错的解决方案。当 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>

感谢大家在本帖中提供的帮助!

  • 这是我的解决方案!我在一大块 HTML 中运行了一个 onready $(function(){...}); 块,该块通过 .dialog() 变成了一个对话框。我的函数被调用了两次。将它移到被 dialog() 编辑的 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');
});

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

  • $(document).one(ready, function () { alert(tab1 loaded); }); $(document).one(ready, function () { alert(tab2 loaded); });测试函数 Launch() { $("#tabDialog").dialog({ autoOpen: false, }).dialog(open);这对我有用。修剪代码以适合注释。
  • 忘了提到我是针对 jquery 1.3.2 版运行这个的
  • 有趣的。当我把它放到我的代码中时,它会调用你的每个 document.ready() 函数两次。现在把我的头发扯下来:P。
  • 您忘记将底部的 document.ready 更改为 document.one。我现在刚刚使用该更改运行了代码,它只运行了一次。有趣的是它运行了两次。
  • 我正在搜索另一个线程。 jQuery 对话框是否"克隆"正在用作对话框的 div?完全复制 DIV 的内容?如果是这样,那么我认为这就是问题所在,因为 SCRIPT 也会被复制,因此会在 DOM 中出现两次 :(。
  • 是的,我稍后会进一步研究。有兴趣看看我建议的最后一个更改是否确实对您有用吗?
  • @spinon - 这个和 find("script").remove() 修复都对我有用。我讨厌这个"功能"仍然是 jQuery UI 的一部分......


.dialog()我用的不多,但是你的脚本中需要使用jQuery的ready()方法吗?

看起来 .dialog() 有你可以利用的回调选项。

标签中的脚本:

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');

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

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 代替。

  • 是的,但是每个 ready() 函数仍然被调用两次:(。
  • 从技术上讲,您可以在同一页面中有多个 document.ready() 调用。重要的是对您的 dialog() 函数的调用。另请参阅我对您的问题的评论。您能否向我们展示显示错误的页面的完整 html 代码?
  • 我会试着看看我可以把它放在哪里,或者试着创建一个更小的例子。我"认为"问题的根本原因是包含的 PHP 文件标签位于 div 内部,而 div 本身位于对话框函数内部。如果我查看页面、复制结果源并将脚本移出 DIV,它只会被调用一次。有一些关于 jQuery 对话框的东西会导致第二次调用 ready() 函数。
  • 我将代码放在答案中,因为它太大而无法发表评论。

有关关于 php:jQuery 就绪函数在对话框中被调用两次的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  4. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  5. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  6. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  7. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

  8. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  9. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  10. ruby - 在 ruby​​ 中使用 .try 函数和 .map 函数 - 2

    我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法

随机推荐