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:

javascript:(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 )

Answers


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);
            }
        }
    }
})();

Need Your Help

django forms, not valid

python django forms django-forms django-validation

so no matter what I seem to do I can't get a valid form from just a integer field.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.