Добавление события onclick в строку таблицы

Я пытаюсь добавить событие onclick в строку таблицы через Javascript.

function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        row = table.rows[i];
        row.onclick = function(){
                          var cell = this.getElementsByTagName("td")[0];
                          var id = cell.innerHTML;
                          alert("id:" + id);
                      };
    }
}

Это работает, как и ожидалось, в Firefox, но в Internet Explorer (IE8) я не могу получить доступ к ячейкам таблицы. Я полагаю, что это как-то связано с тем, что «это» в функции onclick идентифицируется как «Окно», а не «Таблица» (или что-то в этом роде).

Если бы я мог получить доступ к текущей строке, я мог бы выполнить getElementById в функции onclick, я не могу найти способ сделать это. Какие-либо предложения?


person Community    schedule 30.07.2009    source источник
comment
Вы должны начать с индекса 0 (var i = 0;), а не 1.   -  person SolutionYogi    schedule 30.07.2009


Ответы (11)


Что-то вроде этого.

function addRowHandlers() {
  var table = document.getElementById("tableId");
  var rows = table.getElementsByTagName("tr");
  for (i = 0; i < rows.length; i++) {
    var currentRow = table.rows[i];
    var createClickHandler = function(row) {
      return function() {
        var cell = row.getElementsByTagName("td")[0];
        var id = cell.innerHTML;
        alert("id:" + id);
      };
    };
    currentRow.onclick = createClickHandler(currentRow);
  }
}

ИЗМЕНИТЬ

Рабочая демонстрация.

person SolutionYogi    schedule 30.07.2009
comment
Уверены ли вы? Это работает. Проверьте рабочую демо-ссылку в моем обновленном ответе. Кроме того, в вашем коде вы начали индекс с 1 вместо 0. Вы не будете прикреплять обработчик к первой строке. - person SolutionYogi; 30.07.2009
comment
Это работает, но когда я увидел ваше решение, оно немного отличалось от того, что есть сейчас... =P Я очень благодарен, весь день стучал головой! - person ; 30.07.2009
comment
Да, я понял это сразу после того, как опубликовал свой ответ (как и Redsquare), а затем исправил его. - person SolutionYogi; 30.07.2009
comment
Почему требуется table.rows[i]? Я попробовал «var currentRow = rows[i]», и это сработало. - person vaichidrewar; 19.05.2013
comment
Я искал это, спасибо. РЕДАКТИРОВАТЬ: я получаю сообщение об ошибке WHte.js:3 Uncaught TypeError: Cannot read property 'getElementsByTagName' of null . Я предполагаю, что это потому, что я загружаю строки динамически? Поэтому нет ТР. Как мне это обойти??? - person CromeX; 12.09.2016
comment
Отлично нашел... назовите это пост-обновлением... Отличный кусок кода!! - person CromeX; 12.09.2016

Я думаю, что для IE вам нужно будет использовать свойство srcElement объекта Event. если jQuery является вариантом для вас, вы можете рассмотреть возможность его использования, поскольку он абстрагирует для вас большинство различий между браузерами. Пример jQuery:

$("#tableId tr").click(function() {
   alert($(this).children("td").html());
});
person Nick Riggs    schedule 30.07.2009

Простым способом является создание кода, как показано ниже:

<!DOCTYPE html>
<html>
<head>

<style>
  table, td {
      border:1px solid black;
  }
</style>

</head>
<body>
<p>Click on each tr element to alert its index position in the table:</p>
<table>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
</table>

<script>
  function myFunction(x) {
      alert("Row index is: " + x.rowIndex);
  }
</script>

</body>
</html>

person Zolfaghari    schedule 28.10.2018

Вот компактная и немного более чистая версия того же чистого решения Javascript (не jQuery), как обсуждалось выше @redsquare и @SolutionYogi (re: добавление onclick обработчиков событий ко всем строкам таблицы HTML), который работает во всех основных веб-браузерах, включая последнюю версию IE11:

function addRowHandlers() {
    var rows = document.getElementById("tableId").rows;
    for (i = 0; i < rows.length; i++) {
        rows[i].onclick = function(){ return function(){
               var id = this.cells[0].innerHTML;
               alert("id:" + id);
        };}(rows[i]);
    }
}
window.onload = addRowHandlers();

Рабочая ДЕМО

Примечание: чтобы это работало и в IE8, вместо указателя this используйте явный идентификатор, например function(myrow), как предложил @redsquare. С наилучшими пожеланиями,

person Alexander Bell    schedule 20.04.2015

Голова застряла в jq слишком долго. Это сработает.

function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        var row = table.rows[i];
        row.onclick = function(myrow){
                          return function() { 
                             var cell = myrow.getElementsByTagName("td")[0];
                             var id = cell.innerHTML;
                             alert("id:" + id);
                      };
                  }(row);
    }
}
person redsquare    schedule 30.07.2009
comment
Будет ли это работать? Я разместил тот же пример, но я думаю, что «строка» внутри onlcick всегда будет ссылаться на последнюю строку. Не так ли? [JavaScript имеет только область действия функции, без области видимости блока.] - person SolutionYogi; 30.07.2009
comment
Я знаю, jQuery делает все эти вещи настолько простыми, что когда вы остаетесь без jQuery, вы делаете все глупые ошибки! :) - person SolutionYogi; 30.07.2009
comment
действительно так! дай мне каждый день - person redsquare; 30.07.2009

Вот как я это делаю. Я создаю таблицу с тегами thead и tbody. А затем добавить событие клика в элемент tbody по id.

<script>
    document.getElementById("mytbody").click = clickfunc;
    function clickfunc(e) {
        // to find what td element has the data you are looking for
        var tdele = e.target.parentNode.children[x].innerHTML;
        // to find the row
        var trele = e.target.parentNode;
    }
</script>
<table>
    <thead>
        <tr>
            <th>Header 1</th>
            <th>Header 2</th>
        </tr>
    </thead>
    <tbody id="mytbody">
        <tr><td>Data Row</td><td>1</td></tr>
        <tr><td>Data Row</td><td>2</td></tr>
        <tr><td>Data Row</td><td>3</td></tr>
    </tbody>
</table>
person user3121053    schedule 02.05.2017

Попробуйте изменить строку this.getElementsByTagName("td")[0]) на row.getElementsByTagName("td")[0];. Это должно зафиксировать ссылку row в замыкании, и оно должно работать как положено.

Изменить: приведенное выше неверно, поскольку строка является глобальной переменной - как говорили другие, выделите новую переменную, а затем используйте ЭТО в закрытии.

person Luke Rinard    schedule 30.07.2009

Моя таблица находится в другом iframe, поэтому я изменил ответ SolutionYogi для работы с этим:

<script type="text/javascript">
window.onload = addRowHandlers;
function addRowHandlers() {
    var iframe = document.getElementById('myiframe');
    var innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;

    var table = innerDoc.getElementById("mytable");
    var rows = table.getElementsByTagName("tr");
    for (i = 0; i < rows.length; i++) {
        var currentRow = table.rows[i];
        var createClickHandler = 
            function(row) 
            {
                return function() { 
                                        var cell = row.getElementsByTagName("td")[0];
                                        var id = cell.innerHTML;
                                        alert("id:" + id);
                                 };
            }

        currentRow.onclick = createClickHandler(currentRow);
    }
}
</script>
person Fco Javier Rod Ca    schedule 12.11.2013

Я пытался выбрать строку таблицы, чтобы ее можно было легко скопировать в буфер обмена, а затем вставить в Excel. Ниже приведена небольшая адаптация вашего решения.

Использованная литература:

<!DOCTYPE html>
<html>
<body>

<div>
    <table id="tableId" border=1>
      <tbody>
        <tr><td>Item <b>A1</b></td><td>Item <b>B1</b></td></tr>
        <tr><td>Item <b>A2</b></td><td>Item <b>B2</b></td></tr>
        <tr><td>Item <b>A3</b></td><td>Item <b>B3</b></td></tr>
      </tbody>
    </table>
</div>

<script>
function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 0; i < rows.length; i++) {
        var currentRow = table.rows[i];
        var createClickHandler = 
            function(row) 
            {
                return function() { 
                                        var cell = row.getElementsByTagName("td")[0];
                                        var id = cell.innerHTML;

                                        var cell1 = row.getElementsByTagName("td")[1];
                                        var id2 = cell1.innerHTML;
                                        // alert(id + " - " + id2);
                                        window.prompt("Copy to clipboard: Ctrl+C, Enter", "<table><tr><td>" + id + "</td><td>" + id2 + "</td></tr></table>")
                                 };
            };

        currentRow.onclick = createClickHandler(currentRow);
    }
}
window.onload = addRowHandlers();
</script>
</body>
</html> 
person robertocm    schedule 30.04.2017

Хотя большинство ответов являются копией ответа SolutionYogi, все они пропускают важную проверку, чтобы увидеть, не является ли «ячейка» нулевой, которая вернет ошибку при нажатии на заголовки. Итак, вот ответ с включенным чеком:

function addRowHandlers() {
  var table = document.getElementById("tableId");
  var rows = table.getElementsByTagName("tr");
  for (i = 0; i < rows.length; i++) {
    var currentRow = table.rows[i];
    var createClickHandler = function(row) {
      return function() {
        var cell = row.getElementsByTagName("td")[0];
        // check if not null
        if(!cell) return; // no errors! 
        var id = cell.innerHTML;
        alert("id:" + id);
      };
    };
    currentRow.onclick = createClickHandler(currentRow);
  }
}
person Cornelius    schedule 11.05.2019

Я пытаюсь понять, как получить лучший результат с чистым JS, и получаю следующее:

ДЕМО: https://jsfiddle.net/f5r3emjt/1/

const tbody = document.getElementById("tbody");
let rowSelected;

tbody.onclick = (e) => {
  for (let i = 0; i < e.path.length; ++i) {
    if (e.path[i].tagName == "TR") {
      selectRow(e.path[i]);
      break;
    }
  }
};

function selectRow(r) {
  if (rowSelected !== undefined) rowSelected.style.backgroundColor = "white";

  rowSelected = r;
  rowSelected.style.backgroundColor = "dodgerblue";
}

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

person Swiler    schedule 15.11.2020