2017-03-01 74 views
0

我有外部js,它在我的HTML中的一个div的内部调用。 在外部文件中我有下面的代码:调用函数形式外部js

var script = document.createElement("script"); 
script.innerHTML = '$("body").prepend(\'<input type="hidden" id="sid" value="0">\');var vl=0;$(".sbut").click(function(){vl ++; var snew=vl;$("#sid").val(snew).trigger("change");});';   
document.head.appendChild(script); 

$("#sid").change(function(){ 
    alert("change"); 
});   

警报不会被触发。如果我试试这个:

var script = document.createElement("script"); 
script.innerHTML = '$("body").prepend(\'<input type="hidden" id="sid" value="0">\');var vl=0;$(".sbut").click(function(){vl ++; var snew=vl;$("#sid").val(snew).trigger("change");});$("#sid").change(function(){somef();alert("change");}); ';  
document.head.appendChild(script); 

function somef(){ 
    alert("change"); 
} 

比我得到,我的函数somef没有定义。我猜这必须按照我的功能顺序进行,但我不确定究竟是什么。有人可以建议我做什么是正确的方法吗?另外,我的外部脚本(fscript.js)在HTML中的一个div中被调用,我无法更改它,因为我无法访问HTML。这就是为什么我追加输入和脚本。

+0

页面中的哪个位置是'.sbut'元素?任何在脚本中低于脚本的'.sbut'元素都不会附加到它们的点击处理程序。另外...如果你能够使用ES2015(或者从它开始编译)编写你正在注入的HTML,使用模板字符串会更加可读,因为你可以在它们中使用换行符。 –

+0

想想吧,我不明白你为什么把这段代码写成一个字符串并注入脚本标记。您已经加载了一个外部脚本,应该没有理由不能将它写入该文件。除非你还在这个脚本的一部分注入了jQuery,而你没有向我们展示这些脚本标记,以确保执行顺序? –

+0

虽然,你也在脚本字符串之外使用jQuery,所以我假设它已经加载到页面中了? –

回答

0

你动态地添加sid元素,因此它是不可用时绑定修改事件处理程序,请尝试以下代码绑定事件处理程序

$(document).on("change","#sid",function(){ 
    alert("change"); 
}); 
+0

仍然不能正常工作 – codexy

+0

输入的值正在改变,我在控制台中没有任何错误,但是更改没有缓存在外部文件中 – codexy

+0

您需要在完成更改后单击输入框外部。你可以清除你的浏览器缓存并尝试。还有一件事就像'sid'在DOM中必须是唯一的。 –

0

正如我在评论中提到的,我没有看到一个理由将脚本编写为字符串并将其注入为脚本标记。 fscript.js已经被加载,所以你可以在其中编写代码,它将运行在相同的上下文中,就好像它在页面中的脚本标记中一样。

这是我写它的方式。

// Use an IIFE to encapsulate our code so our variables don't leak into 
 
// the global namespace. This will ensure they don't collide with 
 
// and existing JS in the page avoiding creating bugs in both our code 
 
// and the surrounding page 
 
(function() { 
 
    'use strict'; 
 

 
    var vl = 0, 
 
    // create the sid element and store a reference to the 
 
    // returned jQuery object in a variable we can use to 
 
    // refer to it later 
 
    sid = $('<input type="hidden" id="sid" value="0">'); 
 

 
    // attach the change event to sid 
 
    sid.change(function() { 
 
    alert('Change, sid is now ' + sid.val()); 
 
    });  
 

 
    // inject sid into the DOM 
 
    $('body').prepend(sid); 
 

 
    // use event delegation to add the click event for .sbut 
 
    // this will ensure that any .sbut elements in the HTML 
 
    // after this script is run will have the click handler 
 
    // If you know that .sbut will always appear above the place 
 
    // where your script runs, you could just use a normal 
 
    // jQuery selector instead. 
 
    $(document).on('click', '.sbut', function() { 
 
     vl++; 
 
     // there doesn't seem to be any need to create the 
 
     // snew var here, its value is exactly the same as vl 
 
     // at this point, just use vl 
 
     sid.val(vl).trigger('change'); 
 
    }); 
 
}());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<button class="sbut">.sbut</button>

我使用Immediately-Invoked Function Expression (IIFE) 包代码封装,以便它不与其他代码干扰 页面上,反之亦然。使用strict mode, 也是一种很好的做法,它可以帮助避免一些常见类型的错误并实施一些最佳实践。

我用event delegation将点击事件附加到.sbut,因为我不知道你的脚本加载后是否有.sbut元素出现,似乎可能是这种情况。如果您知道.sbut将始终发生在脚本加载之前,您可以将其更改为正常的$('.sbut').click(function() {});处理程序。