jQuery替换HTML和JavaScript函数

3

[编辑:我试图只放置代码的相关部分。我明白这导致了混淆。对此感到抱歉。这里是一个我可以创建的片段,引起了相同的问题。在这里添加片段:]

加载片段后,单击按钮。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="hello">
  Some text
  <script>
 jQuery(document).ready(function () {
   func();
  });  
    var a = 5;
    function func() {
      alert("Value is FIVE. Integer value: " +a);
    }
</script>
</div>

<div id="mybtn" style="border: 2px solid black; padding:5px; background-color: yellow; width: 100px">CLICK</div>
<script>
   var data = " \
    Some text2 \
    <script> \
   jQuery(document).ready(function () { \
    func(); \
   }); \
            var a = 6; \
   function func() { \
     alert('Value is SIX. Integer value: ' +a); \
   } \
   <\/script> ";
   
 $('#mybtn').on('click', function(e) {
   $('#hello').html(data);  
 });
</script>   
   

我期望在点击按钮后看到六个6(或者可能是五个5)。但是却看到了六个5。有趣的是新函数被调用了,但是旧的数值(5)被使用了。在我的实际代码中,我将func()函数放在了调用它的位置下方,并且还在settimeout(func... )中调用了它。我正在尝试理解发生了什么。


我猜你没有关闭 script 标签只是在这个示例代码中,对吧...? - benomatis
你并没有定义var1 = 4,所以为什么会期望它被打印出来呢? - benomatis
这个版本缺少 </script>。你能否编辑你的代码并提供这部分的原始副本? - CY_
仅从结果来看,似乎函数func没有被覆盖,但变量已经被覆盖了。也许你可以在新代码中再次检查func的内容(在控制台中打印出来)。 - CY_
原因与“脚本”更改有关,但实际的JavaScript并没有更新。您需要“刷新”script标签来解决这个问题。如果您能在fiddle中重现这个问题,我很乐意向您展示解决方案。 - Nick Zuber
2个回答

1

更新

根据问题的更改,新问题是您声明变量a的新值的位置。

原因是:

jQuery(document).ready(function () {

当文档就绪时执行代码,因为您替换hello元素的html时文档已经准备好了,第一次单击时您会得到值5,只有在获取新值后才能获得它。从第二次开始,因为html已更改,单击时仅激活ready函数。解决方案是在文档准备好之前立即在数据字符串中声明变量a。

您可以使用添加的“描述函数”按钮自行查看包含在hello div中的脚本内容。

为了更好地理解,我添加了一个字符串作为参数传递给您的func函数,以便了解何时以及如何调用它。

更新的代码段:

$(document).on('click', '#btn2', function (e) {
  $('body').append('<br>var a is: ' + a + '  func() is: ' + func.toString())
  .append('<br><div style="border: double;">hello HTML: ' + $('#hello')[0].outerHTML.replace(/</g, '&lt;')
          .replace(/>/g, '&gt;') + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="hello">
    Some text
    <script>
        jQuery(document).ready(function () {
            func("inside ready");
        });
        var a = 5;
        function func(str) {
            alert("FIRST: " + str + "  Value is FIVE. Integer value: " +a);
        }
    </script>
</div>

<div id="mybtn" style="border: 2px solid black; padding:5px; background-color: yellow; width: 100px">CLICK</div>
<script>
    var data = " \
    Some text2 \
    <script> \
            var a = 6; /* HERE!!!!!!!!!!!!!!*/\
   jQuery(document).ready(function () { \
    func('inside second ready'); \
   }); \
   function func(str) { \
     alert('SECOND: ' + str + ' Value is SIX. Integer value: ' +a); \
   } \
   <\/script> ";

    $('#mybtn').on('click', function(e) {
        $('#hello').html(data);
    });
</script>
<button id="btn2">Describe function</button>

我创建并测试了一个可能相似的情况,对我来说它是可行的:

$(function () {
  var newcode = '<script>' +
      'var var1 = 3;' +
      'function func() {' +
      '    console.log("VALA is 4");' +
      '    console.log("VALB is " + var1);' +
      '}';
  $('#btn1').on('click', function (e) {
    $.getJSON('https://api.github.com/users', function(data) {
       $('#box1').html(newcode);
    });
  });
  $('#btn2').on('click', function (e) {
    func();
    $('body').append('<br>var var1 is: ' + var1 + '  func() is: ' + func.toString());
  });
});
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>

<div id="box1">
    <script>
        var var1 = 2;
        function func() {
            console.log("VALA is 1");
            console.log("VALB is " + var1);
        }
    </script>
</div>
<button id="btn1">Simulate Ajax Call</button>
<button id="btn2">Call function</button>


1
这与页面上JavaScript的解析和执行新脚本有关。当函数执行时,当NEW文档准备就绪触发函数执行时,OLD值仍然存在。
详细来说,它们按顺序发生(大致如下):
1. 新代码被放置(由Javascript解析),用新函数(其中包含SIX)替换OLD函数 2. NEW文档准备就绪触发(调用具有OLD a值的NEW函数(5)) 3. 然后,a值被替换为6的NEW值(不执行进一步使用NEW值的调用)
请看这里我如何更改片段。我在您的代码中添加了两个alert('a:'+a);。现在执行它,您会看到警报的顺序:
第二个警报在更改后警报了6。
   var data = " \
              Some text2 \
              <script> \
                jQuery(document).ready(function () { \
                    func(); \
                }); \
        alert('a:'+a);\
             var    a = 6; \
            alert('a:'+a);\
            function func() { \
                  alert('Value is SIX. Integer value: ' +a); \
                } \
                <\/script> ";

    $('#mybtn').on('click', function(e) {
      $('#hello').html(data);
      console.dir($('#hello').html());
    });

注意: 将这个 var a = 6; \ 移到文档准备好之前的字符串中,它会首先被执行。

可以将其视为以下代码:

    var  a = 6; \
    func(); \

编辑2:文档就绪

查看jQuery源代码;当$(document).ready()首次触发时,它将取消绑定先前注册的函数(例如忘记它们)。因此,手动调用jQuery.ready()(如你所做的那样)第二次不会重新触发相同的函数调用。因此,在页面上已经触发后加载的脚本中,您实际上不需要包装器,因为它只执行NEW文档准备好内部代码的立即执行,因为您的NEW绑定函数执行然后被解除绑定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接