onclick设置的函数的参数范围是什么?

时间:2011-07-26 05:18:05

标签: javascript javascript-events

我有一个只接受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

3 个答案:

答案 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处理程序它