我有一个只接受html字符串的函数,它会显示一个信息窗口(弹出窗口),其中html为其内容:
function createInfoWindow(info_html){
// show a popup with info_html as its content
}
现在我想创建一个有按钮的信息窗口:
function createMyInfoWindow(o){
var info_html = "<input type='button' value='click me' onclick='foo(o)'>"
createInfoWindow(info_html);
}
function foo(o){
console.log(o);
}
createMyInfoWindow({ name: "test", age: 21);
但是,当我点击该按钮时,它表示无法找到o
。
答案 0 :(得分:1)
尝试以下代码
var info_html = "<input type='button' value='click me' onclick='foo(\""+o+"\")'>"
更新
如果o是对象则会变得更复杂。
您可以在store-object中存储传递的对象。然后,您可以在foo
中传递相应的索引:
var storage = [];
function createMyInfoWindow(o){
var index = storage.length;
storage[index] = o;
var info_html = "<input type='button' value='click me' onclick='foo(\""+index+"\")'>"
createInfoWindow(info_html);
}
function foo(i){
console.log(storage[i]);
}
createMyInfoWindow({ name: "test", age: 21);
答案 1 :(得分:0)
在分配给输入的innerHTML的HTML中,处理程序包含在函数中,因此范围是处理程序,然后是全局的(范围链上可能还有其他对象)。
在您的代码中, name 是 createMyInfoWindow 的本地,处理程序(也没有任何其他函数)可以访问该变量。请参阅Molecule关于如何使用它的答案。
答案 2 :(得分:0)
你现在这样做的方式是eval
的形式,并且通常不赞成。如果您想了解原因,请阅读Unobtrusive Javascript。
但是,有一种非常优秀的方法可以完成相同的任务,而不会遇到您面临的范围问题(更不用说尝试将该对象以字符串形式传递给函数了 - yikes!)这恰当地需要对你的功能进行一些重组,但我相信你会觉得它值得。
function createMyInfoWindow(o){
// creating window first so we can access it from the DOM
createInfoWindow(info_html);
// we can select the window from the DOM now, but it would be even better if
// createInfoWindow returned that object so we could just pick up where we left off
var myInfoWindow = document.getElementById("myInfoWindow");
// The button you are putting into the window
var myButton = document.createElement("input");
myButton.type = "button";
myButton.value = "click me";
// because of javascript closures, we can call foo(o) from within an anonymous function
myButton.onclick = function () { foo(o) };
}
我更喜欢这种方式创建HTML元素有很多原因:1)避免隐式使用eval
,2)当javascript为你生成时更容易调试HTML 3)不再有范围事件功能的问题。
您现在必须以相反的顺序创建窗口,因为窗口元素必须首先存在才能向其添加按钮,并且必须先存在按钮元素才能添加onclick
处理程序它