Букмарклет неожиданно открывает новую страницу при клике - PullRequest
0 голосов
/ 03 декабря 2010

Итак, я создал букмарклет, чтобы свернуть каждую строку в таблице, кроме первой, а затем переключить эту первую строку / показать остальную часть таблицы:

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

Я запускаю это без JavaScript:(function () {} () в консоли firebug, и она отлично работает. Но когда я использую его как букмарклет, каждый раз, когда я нажимаю на первую строку, чтобы показать таблицу, она просто открывает новую страницу '0' (то есть website.com/0)

1 Ответ

2 голосов
/ 03 декабря 2010

Конструктор функции создает глобальную функцию, а не лексически внутри вашей функции. Следовательно, он не имеет доступа к вашей локальной функции open, поэтому он использует метод open окна.

Из моих тестов ваш код всегда должен ссылаться на метод глобального открытия, независимо от того, запускается он из букмарклета или самой страницы.

Посмотрите на этот пример:

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

Вот возможное решение вашей проблемы

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