What's the scope of parameters of a function set by onclick?
I've a function which accept only html string, it will show a info window (a popup) with the html as its content:
function createInfoWindow(info_html){
// show a popup with info_html as its content
}
Now I want to create a info window which will have a button:
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);
However, when I click the button, it says that o
can't be found.
Try following code
var info_html = "<input type='button' value='click me' onclick='foo(\""+o+"\")'>"
UPDATE
If o is object it becomes more complicated.
You can store passed objects in store-object. Then you can pass corresponding index in 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);
In the HTML assigned to the innerHTML of the input, handlers are wrapped in functions so the scope is the handler, then global (there may be other objects on the scope chain).
In your code, name is local to createMyInfoWindow, the handler (nor any other function) has access to that variable. See Molecule's answer for how to use it.
The way you are doing it now is a form of eval
, and is generally frowned upon. Read up on Unobtrusive Javascript if you'd like to know all the reasons why.
However, there is a really excellent way to accomplish the same task without the scope problems your facing (let alone trying to get that object passed to the function in string form -- yikes!) Doing this properly will require some restructuring of your functions, but I'm sure you'll find it to be worth it.
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) };
}
I prefer creating HTML elements this way for many reasons: 1) Avoid the implicit use of eval
, 2) much easier to debug the HTML when it is generated by the javascript for you and 3) no more scope issues for event functions.
You just have to create the window in the reverse order now, because the window element must exist first in order to add a button to it, and the button element must exist before you can add the onclick
handler to it.
精彩评论