Bookmarklet unexpectedly opens new page on click
So I made a bookmarklet to collapse every row in a table, except the first one, then make that first row toggle/show the rest of the table:
javasc开发者_开发问答ript:(function(){
function open(tableid){
console.log('open');
for (j=1;j<table[tableid].rows.length;j++){
if(table[tableid].rows[j].style.display == 'none' ){
table[tableid].rows[j].style.display = '';
} else if(table[tableid].rows[j].style.display == ''){
table[tableid].rows[j].style.display = 'none';
}
}
}
var table = document.getElementsByTagName("table");
for (i=0;i<table.length;i++){
for (j=0;j<table[i].rows.length;j++){
if( j != 0){
table[i].rows[j].style.display = 'none';
}
if( j == 0){
table[i].rows[j].onclick = new Function("open("+i+")");
}
}
}
})();
I run this without javascript:(function(){}() in firebug's console, and it works fine. But when I use it as a bookmarklet, every time I click on the first row to show the table, it just opens a new page '0' (i.e. website.com/0 )
the Function constructor creates a global function, not lexically within your function. Therefore, it doesn't have access to your local function called open, so it uses the window's open method.
From my tests, your code should always be referencing the global open method whether run from a bookmarklet or the page itself.
Look at this example:
(function(){
function giveme5(x) { return 5;}
var func = new Function("return giveme5()");
// should output 5, but we get an error, giveme5 is not defined
console.log( func() );
})()
Here's a possible solution to your problem
(function(){
// Binds an argument to a method, this could be much better, but serves our
// purpose here
function bindArg(fun, arg) {
return function() {
fun.call(this, arg);
}
}
function toggleTable(table) {
var rows = table.rows;
for (var j=1; j<rows.length; j++){
if(rows[j].style.display == 'none' ){
rows[j].style.display = '';
} else if(rows[j].style.display == ''){
rows[j].style.display = 'none';
}
}
}
var tableList = document.getElementsByTagName("table");
for ( var i=0; i<tableList.length; i++){
var table = tableList[i];
for ( var j=0; j < table.rows.length;j++){
if( j != 0){
table.rows[j].style.display = 'none';
} else {
table.rows[j].onclick = bindArg(toggleTable, table);
}
}
}
})();
精彩评论