Как сделать целую строку в таблице кликабельной в виде ссылки?
Я использую Bootstrap, и следующее не работает:
<tbody>
<a href="#">
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</a>
</tbody>
28 ответов
Вы используете Bootstrap, что означает, что вы используете jQuery:^), поэтому один из способов сделать это:
<tbody>
<tr class='clickable-row' data-href='url://'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
jQuery(document).ready(function($) {
$(".clickable-row").click(function() {
window.location = $(this).data("href");
});
});
Конечно, вам не нужно использовать href или переключать местоположения, вы можете делать все что угодно в функции обработчика кликов. Следить за публикациями jQuery
и как писать обработчики;
Преимущество использования класса перед id заключается в том, что вы можете применить решение к нескольким строкам:
<tbody>
<tr class='clickable-row' data-href='url://link-for-first-row/'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr class='clickable-row' data-href='url://some-other-link/'>
<td>More money</td> <td>1234567</td> <td>£800,000</td>
</tr>
</tbody>
и ваша база кода не меняется. Один и тот же обработчик позаботится обо всех строках.
Другой вариант
Вы можете использовать обратные вызовы Bootstrap jQuery, как это (в document.ready
Перезвоните):
$("#container").on('click-row.bs.table', function (e, row, $element) {
window.location = $element.data('href');
});
Это имеет преимущество в том, что не сбрасывается при сортировке таблиц (что происходит с другой опцией).
Заметка
Так как это было опубликовано window.document.location
устаревшее (или, по крайней мере, устаревшее) использование window.location
вместо.
Вы не можете сделать это. Это неверный HTML. Вы не можете положить <a>
между <tbody>
и <tr>
, Попробуйте это вместо этого:
<tr onclick="window.location='#';">
...
</tr>
Работая над этим, вы захотите использовать JavaScript, чтобы назначить обработчик кликов за пределами HTML.
Вы можете включить якорь внутри каждого <td>
, вот так:
<tr>
<td><a href="#">Blah Blah</a></td>
<td><a href="#">1234567</a></td>
<td><a href="#">more text</a></td>
</tr>
Вы могли бы тогда использовать display:block;
на якорях, чтобы сделать полный ряд кликабельным.
tr:hover {
background: red;
}
td a {
display: block;
border: 1px solid black;
padding: 16px;
}
Это, вероятно, примерно так же оптимально, как вы собираетесь получить, если вы не прибегаете к JavaScript.
Да, но не со стандартным <table>
элементы. Если вы используете display: table
Свойства стиля, вы можете. Здесь и здесь есть несколько скрипок для демонстрации.
Этот код должен сделать свое дело:
.table {
display: table;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
padding: 10px;
}
.row:hover {
background-color: #cccccc;
}
.cell:hover {
background-color: #e5e5e5;
}
<link href="https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
<div class="table">
<div class="row">
<div class="cell">
1.1
</div>
<div class="cell">
1.2
</div>
<div class="cell">
1.3
</div>
</div>
<a class="row" href="#">
<div class="cell">
2.1
</div>
<div class="cell">
2.2
</div>
<div class="cell">
2.3
</div>
</a>
</div>
Обратите внимание, что роли арии используются для обеспечения надлежащей доступности, так как стандарт <table>
элементы не используются. Возможно, вам придется добавить дополнительные роли, такие как role="columnheader"
если это применимо. Узнайте больше в следующем руководстве здесь.
Достигается с использованием стандартного Bootstrap 4.3+ следующим образом - не требуется ни jQuery, ни каких-либо дополнительных классов css!
Ключ в том, чтобы использовать stretched-link
по тексту в ячейке и определяя <tr>
как содержащий блок.
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-hover">
<tbody>
<tr style="transform: rotate(0);">
<th scope="row"><a href="#" class="stretched-link">1</a></th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
Вы можете определить содержащий блок по-разному, например, установив transform
в значение not none (как в примере выше).
Для получения дополнительной информации прочтите документацию Bootstrap дляstretched-link
.
Гораздо более гибким решением является нацеливание чего-либо с помощью атрибута data-href. Это было то, что вы можете легко использовать код в разных местах.
<tbody>
<tr data-href="https://google.com">
<td>Col 1</td>
<td>Col 2</td>
</tr>
</tbody>
Затем в вашем jQuery просто укажите любой элемент с этим атрибутом:
jQuery(document).ready(function($) {
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
});
И не забудьте оформить свой CSS:
[data-href] {
cursor: pointer;
}
Теперь вы можете добавить атрибут data-href к любому элементу, и он будет работать. Когда я пишу такие фрагменты, мне нравится, чтобы они были гибкими. Не стесняйтесь добавить решение Vanilla JS к этому, если у вас есть.
Вот простое решение..
<tr style='cursor: pointer; cursor: hand;' onclick="window.location='google.com';"></tr>
Одно из решений, которое не упоминалось ранее, - использовать одну ссылку в ячейке и немного CSS для расширения этой ссылки по ячейкам:
table {
border: 1px solid;
width: 400px;
overflow: hidden;
}
tr:hover {
background: gray;
}
tr td {
border: 1px solid;
}
tr td:first-child {
position:relative;
}
a:before {
content: '';
position:absolute;
left: 0;
top: 0;
bottom: 0;
display: block;
width: 400px;
}
<table>
<tr>
<td><a href="https://google.com">First column</a></td>
<td>Second column</td>
<td>Third column</td>
</tr>
<tr>
<td><a href="https://stackru.com">First column</a></td>
<td>Second column</td>
<td>Third column</td>
</tr>
</table>
Вы можете использовать этот компонент начальной загрузки:
http://jasny.github.io/bootstrap/javascript/
Jasny Bootstrap
Недостающие компоненты для вашего любимого интерфейса.
<table class="table table-striped table-bordered table-hover">
<thead>
<tr><th>Name</th><th>Description</th><th>Actions</th></tr>
</thead>
<tbody data-link="row" class="rowlink">
<tr><td><a href="#inputmask">Input mask</a></td><td>Input masks can be used to force the user to enter data conform a specific format.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="http://www.jasny.net/" target="_blank">jasny.net</a></td><td>Shared knowledge of Arnold Daniels aka Jasny.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="#rowlinkModal" data-toggle="modal">Launch modal</a></td><td>Toggle a modal via JavaScript by clicking this row.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
</tbody>
</table>
использование
Через атрибуты данных
Добавить класс .rowlink
и атрибут data-link="row"
к <table>
или же <tbody>
элемент. Для других опций добавьте имя к data-, как в data-target="a.mainlink"
Ячейка может быть исключена путем добавления .rowlink-skip
класс к <td>
,
Через JavaScript
Вызовите маску ввода через JavaScript:
$('tbody.rowlink').rowlink()
Вы можете добавить роль кнопки в строку таблицы, и Bootstrap изменит курсор без каких-либо изменений CSS. Я решил использовать эту роль как способ легко сделать любую строку кликабельной с очень небольшим количеством кода.
Html
<table class="table table-striped table-hover">
<tbody>
<tr role="button" data-href="#">
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
JQuery
$(function(){
$(".table").on("click", "tr[role=\"button\"]", function (e) {
window.location = $(this).data("href");
});
});
Вы можете применить этот же принцип, чтобы добавить роль кнопки к любому тегу.
Есть хороший способ сделать это технически <a>
тег внутри <tr>
, который может быть семантически неправильным (может дать вам предупреждение браузера), но будет работать без JavaScript/jQuery
требуется:
<!-- HTML -->
<tbody>
<tr class="bs-table-row">
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
<a class="bs-row-link" href="/your-link-here"></a>
</tr>
</tbody>
/* CSS */
.bs-table-row {
position: 'relative';
}
.bs-row-link {
position: 'absolute';
left: 0;
height: '36px'; // or different row height based on your requirements
width: '100%';
cursor: 'pointer';
}
PS: обратите внимание на хитрость здесь, чтобы поставить <a>
тег как последний элемент, в противном случае он будет пытаться занять место первого <td>
клетка.
PPS: Теперь вся ваша строка будет кликабельной, и вы можете использовать эту ссылку, чтобы открыть ее и в новой вкладке (Ctrl/CMD+ клик)
Очень простой вариант (работает также с Angular ng-click):
<table>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
</table>
<script>
function myFunction(x) {
alert("Row index is: " + x.rowIndex);
}
</script>
Пример работы здесь
Вот способ, поместив прозрачный элемент A над строками таблицы. Преимущества:
- является реальным элементом ссылки: при наведении курсора изменяет указатель, показывает целевую ссылку в строке состояния, может перемещаться по клавиатуре, может быть открыт в новой вкладке или окне, можно скопировать URL и т. д.
- таблица выглядит так же, как и без ссылки
- никаких изменений в самом коде таблицы
Недостатки:
- Размер элемента A должен быть установлен в скрипте как при создании, так и после любых изменений размера строки, которую он покрывает (в противном случае это может быть сделано вообще без JavaScript, что по-прежнему возможно, если также установлен размер таблицы). в HTML или CSS)
Стол остается как есть:
<table id="tab1">
<tbody>
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
Добавьте ссылки (для каждой строки) с помощью jQuery JavaScript, вставив элемент A в каждый первый столбец и установив необходимые свойства:
// v1, fixed for IE and Chrome
// v0, worked on Firefox only
// width needed for adjusting the width of the A element
var mywidth=$('#tab1').width();
$('#tab1 tbody>tr>td:nth-child(1)').each(function(index){
$(this).css('position', 'relative');// debug: .css('background-color', '#f11');
// insert the <A> element
var myA=$('<A>');
$(this).append(myA);
var myheight=$(this).height();
myA.css({//"border":'1px solid #2dd', border for debug only
'display': 'block',
'left': '0',
'top': '0',
'position': 'absolute'
})
.attr('href','the link here')
.width(mywidth)
.height(myheight)
;
});
Настройка ширины и высоты может быть сложной, если используется много отступов и полей, но, как правило, несколько пикселей не должны иметь значения.
Демонстрационная версия здесь: http://jsfiddle.net/qo0dx0oo/ (работает в Firefox, но не в IE или Chrome, там ссылка расположена неправильно)
Исправлено для Chrome и IE (все еще работает в FF): http://jsfiddle.net/qo0dx0oo/2/
Я знаю, что кто-то уже написал примерно то же самое, однако мой путь - правильный (div не может быть дочерним для A), а также лучше использовать классы.
Вы можете имитировать таблицу с помощью CSS и сделать элемент A строкой
<div class="table" style="width:100%;">
<a href="#" class="tr">
<span class="td">
cell 1
</span>
<span class="td">
cell 2
</span>
</a>
</div>
CSS:
.table{display:table;}
.tr{display:table-row;}
.td{display:table-cell;}
.tr:hover{background-color:#ccc;}
Вы можете использовать javascript-метод onclick в tr и сделать его кликабельным, также если вам нужно создать ссылку из-за некоторых деталей, вы можете объявить функцию в javascript и вызвать ее в onclick, передавая некоторые значения.
Этот код ниже сделает всю вашу таблицу кликабельной. Щелкнув по ссылкам в этом примере, вы увидите ссылку в диалоговом окне предупреждения, а не перейдете по ссылке.
HTML:
Вот HTML за приведенным выше примером:
<table id="example">
<tr>
<th> </th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<tr>
<td><a href="apples">Edit</a></td>
<td>Apples</td>
<td>Blah blah blah blah</td>
<td>10.23</td>
</tr>
<tr>
<td><a href="bananas">Edit</a></td>
<td>Bananas</td>
<td>Blah blah blah blah</td>
<td>11.45</td>
</tr>
<tr>
<td><a href="oranges">Edit</a></td>
<td>Oranges</td>
<td>Blah blah blah blah</td>
<td>12.56</td>
</tr>
</table>
CSS
И CSS:
table#example {
border-collapse: collapse;
}
#example tr {
background-color: #eee;
border-top: 1px solid #fff;
}
#example tr:hover {
background-color: #ccc;
}
#example th {
background-color: #fff;
}
#example th, #example td {
padding: 3px 5px;
}
#example td:hover {
cursor: pointer;
}
JQuery
И, наконец, jQuery, благодаря которому происходит волшебство:
$(document).ready(function() {
$('#example tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
То, что он делает, когда щелкают по строке, выполняется поиск по href, принадлежащему якору. Если он найден, местоположение окна устанавливается на этот href.
Я бы предпочел использовать onclick=""
атрибут, так как он прост в использовании и понимании для новичков, таких как
<tr onclick="window.location='any-page.php'">
<td>UserName</td>
<td>Email</td>
<td>Address</td>
</tr>
Еще один вариант использования <a>
, Позиции CSS и некоторые JQuery или JS:
HTML:
<table>
<tr>
<td>
<span>1</span>
<a href="#" class="rowLink"></a>
</td>
<td><span>2</span></td>
</tr>
</table>
CSS:
table tr td:first-child {
position: relative;
}
a.rowLink {
position: absolute;
top: 0; left: 0;
height: 30px;
}
a.rowLink:hover {
background-color: #0679a6;
opacity: 0.1;
}
Затем вам нужно указать ширину, используя, например, jQuery:
$(function () {
var $table = $('table');
$links = $table.find('a.rowLink');
$(window).resize(function () {
$links.width($table.width());
});
$(window).trigger('resize');
});
Вот статья, в которой объясняется, как это сделать в 2020 году: https://www.robertcooper.me/table-row-links
В статье объясняются 3 возможных решения:
- Используя JavaScript.
- Обертывание всех ячеек таблицы элементами привязки.
- С помощью
<div>
элементы вместо собственных элементов таблицы HTML, чтобы строки таблицы были<a>
элементы.
В статье подробно рассматривается, как реализовать каждое решение (со ссылками на CodePens), а также рассматриваются крайние случаи, например, как подойти к ситуации, когда вы хотите добавить ссылки внутри ячеек таблицы (с вложенными <a>
elements не является допустимым HTML, поэтому вам нужно это исправить).
Как отметил @gameliela, возможно, стоит попытаться найти подход, при котором вы не делаете всю свою строку ссылкой, поскольку это упростит многие вещи. Я, однако, думаю, что для пользователя может быть полезно иметь целую строку таблицы, которую можно щелкнуть в качестве ссылки, поскольку пользователю удобно иметь возможность щелкнуть в любом месте таблицы для перехода на соответствующую страницу.
Я потратил много времени, пытаясь решить эту проблему.
Есть 3 подхода:
Используйте JavaScript. Очевидные недостатки: невозможно открыть новую вкладку изначально, а при наведении курсора на строку в строке состояния не будет индикации, как у обычных ссылок. Доступность - тоже вопрос.
Используйте только HTML/CSS. Это означает положить
<a>
вложены под каждый<td>
. Такой простой подход, как эта скрипка, не работает - потому что интерактивная поверхность не обязательно одинакова для каждого столбца. Это серьезная проблема UX. Кроме того, если вам нужен<button>
в строке недопустимый HTML-код для вложения его в<a>
(хотя в браузерах это нормально).Я нашел еще 3 способа реализовать этот подход. Первый - нормально, два других - не очень.
а) Взгляните на этот пример:
tr { height: 0; } td { height: 0; padding: 0; } /* A hack to overcome differences between Chrome and Firefox */ @-moz-document url-prefix() { td { height: 100%; } } a { display: block; height: 100%; }
Это работает, но из-за несоответствий между Chrome и Firefox требуется взлом для конкретного браузера, чтобы преодолеть различия. Также Chrome всегда будет выравнивать содержимое ячейки по верхнему краю, что может вызвать проблемы с длинными текстами, особенно если речь идет о разной высоте строк.
б) Настройка
<td>
к{ display: contents; }
. Это приводит к 2 другим проблемам:b1. Если кто-то другой пытается напрямую стилизовать
<td>
тег, например, установив его на{ width: 20px; }
, нам нужно каким-то образом передать этот стиль<a>
тег. Для этого нам нужна магия, возможно, больше магии, чем в альтернативе Javascript.Би 2.
{ display: contents; }
все еще экспериментальный; в частности, он не поддерживается в Edge.в) Настройка
<td>
к{ height: --some-fixed-value; }
. Это просто недостаточно гибко.Последний подход, о котором я рекомендую серьезно подумать, - это вообще не использовать интерактивные строки. Кликабельные строки не очень удобны для пользовательского интерфейса: их непросто визуально пометить как интерактивные, и возникают проблемы, когда в строках можно щелкнуть несколько частей, например кнопок. Таким образом, жизнеспособной альтернативой может быть
<a>
только в первом столбце, отображаемом как обычная ссылка, и дать ему роль навигации по всей строке.
<tbody>
<tr data-href='www.bbc.co.uk'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
<tr data-href='www.google.com'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
<script>
jQuery(document).ready(function ($) {
$('[data-href]').click(function () {
window.location = $(this).data("href");
});
});
</script>
Хотя основное решение здесь великолепно, мое решение устраняет необходимость в занятиях. Все, что вам нужно сделать, это добавить атрибут data-href с URL-адресом.
Принятый ответ хорош, но я предлагаю небольшую альтернативу, если вы не хотите повторять URL-адрес для каждого запроса. Таким образом, вы помещаете url или href в таблицу data-url, а не в tr.
<table data-click data-url="href://blah">
<tbody>
<tr id ="2">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr id ="3">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
</table
jQuery(document).ready(function($) {
$('[data-click] tbody tr').click(function() {
var url = $(this).closest('table').data("url");
var id = $(this).closest('tr').attr('id');
window.location = url+"?id="+id);
});
});
Это также хорошо, потому что вам не нужно добавлять атрибут данных клика для каждого tr. Еще одна хорошая вещь - мы не используем класс для запуска клика, так как классы должны использоваться только для стиля.
Ответ 2023 года: вы можете добавить addEventListener в строку:
Вот общий подход. Определите этот css:
// css
td a.linker {
color:#212529;
display: block;
padding: 16px;
text-decoration: none;
}
Затем поместите это внутри каждого td:
<td>
<a class="linker" href="www.google.com">
Cell content goes here
</a>
</td>
Вы можете дать строке идентификатор, например,
<tr id="special"> ... </tr>
а затем используйте jquery, чтобы сказать что-то вроде:
$('#special').onclick(function(){ window="http://urltolinkto.com/x/y/z";})
Вот еще один способ...
HTML:
<table>
<tbody>
<tr class='clickableRow'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
JQuery:
$(function() {
$(".clickableRow").on("click", function() {
location.href="http://google.com";
});
});
<table>
<tr tabindex="0" onmousedown="window.location='#';">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
Замените # URL-адресом, tabindex="0"
делает любой элемент фокусируемым
Почему мы не должны использовать теги "div"....
<div>
<a href="" > <div> Table row of content here.. </div> </a>
</div>