#javascript #jquery #html #dom
#javascript #jquery #HTML #dom
Вопрос:
Итак, у меня сейчас такая ситуация:
https://jsfiddle.net/rucjr5cm/
$(function() {
var row = $('.DataList tbody tr.highlight');
var index = row.index();
console.log('current row: ' index);
function highlight(tableIndex) {
$('.DataList tbody tr').removeClass('highlight');
$('.DataList tbody tr:eq(' tableIndex ')').addClass('highlight');
}
$(document).keydown(function(e) {
var currentRow = $('.DataList tbody tr.highlight');
switch (e.which) {
case 38:
var prevRow = currentRow.closest('.DataList tbody tr:not(.Header, .SubHeader, .Total)').prev('tr');
highlight(prevRow.index());
break;
case 40:
var nextRow = currentRow.closest('.DataList tbody tr:not(.Header, .SubHeader, .Total)').next('tr');
highlight(nextRow.index());
break;
}
});
});
.highlight {
background-color: yellow !important;
}
.Header,
.SubHeader,
.Total {
background-color: grey;
}
<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>
<table id="data" class="DataList" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<th>#</th>
<th>header2</th>
<th>header3</th>
<th>header4</th>
<th>header5</th>
</tr>
<tr>
<td>1</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="Header">
<td>2</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="SubHeader">
<td>3</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="highlight">
<td>4</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>5</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="Total">
<td>6</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
</tbody>
</table>
Я бы хотел, чтобы выделенная строка пропускала серые (которые определяются классами и не могут быть изменены). Было бы неплохо также, если бы был достигнут последний, не выделенный серым цветом, перейти к первому (опять же, не выделенный серым цветом).
Я тоже пытался использовать ближайший следующий и предыдущий подход из jQuery, но из этого тоже ничего не вышло.
Я никогда не использовал ближайший и следующий / предыдущий подход, и я, конечно, делаю что-то не так, может кто-нибудь оказать какую-либо помощь в этом?
Большое спасибо!
Комментарии:
1. ваша функция
highlight(tableIndex)
всегда будет вызываться путем передачи значения -1, т.е.highlight(-1)
Ответ №1:
Я бы использовал функции nextAll
and prevAll
:
var rows = $('.DataList tbody tr'); // cache this for better performance
function highlight(row) {
// changed to use the cached object
rows.removeClass('highlight');
// instead of using the index, you can just pass the object in
row.addClass('highlight');
}
$(document).keydown(function(e) {
var currentRow = rows.filter('.highlight'); // use filter to get the current highlight
switch (e.which) {
case 38:
e.preventDefault(); // this will stop the page moving when the arrow is pressed
var prevRows = currentRow.prevAll('tr').not('.Header,.SubHeader,.Total'), // use prevAll to get all preceding rows and then filter out ones with the classes,
prevRow;
if (prevRows.length) {
// test if there is a matching row and then highlight it
prevRow = prevRows.eq(0);
} else {
// no matching so start from the end
prevRow = currentRow.nextAll('tr').not('.Header,.SubHeader,.Total').last();
}
highlight(prevRow); // no need to figure out the index. but if you want you would do rows.index(prevRow); - gets the index with regards to all rows
break;
case 40:
e.preventDefault(); // this will stop the page moving when the arrow is pressed
var nextRows = currentRow.nextAll('tr').not('.Header,.SubHeader,.Total'), // same as above but next
nextRow;
if (nextRows.length) {
nextRow = nextRows.eq(0);
} else {
nextRow = currentRow.prevAll('tr').not('.Header,.SubHeader,.Total').last();
// no matching so start from the beginning
}
highlight(nextRow);
break;
}
});
.highlight {
background-color: yellow !important;
}
.Header,
.SubHeader,
.Total {
background-color: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="data" class="DataList" border="1" cellspacing="1" cellpadding="1">
<thead> <!-- put header into a thead so it's not included in highlighting -->
<tr>
<th>#</th>
<th>header2</th>
<th>header3</th>
<th>header4</th>
<th>header5</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="Header">
<td>2</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="SubHeader">
<td>3</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="highlight">
<td>4</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>5</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="Total">
<td>6</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
</tbody>
</table>
С closest
вашим первоначальным ответом — он проходит через предков (родителей), а не через братьев и сестер
Комментарии:
1. возможно ли, чтобы он переходил к первой (возможной) строке при достижении последней возможной строки? это выглядит действительно многообещающе
2. @Dunnow см. Редактирование. Я также остановил прокрутку страницы при нажатии стрелки
3. <3 похоже, это именно то, что ожидалось, большое спасибо
4. Я просто подумал, что вы можете захотеть переместить
e.preventDefault()
в каждый из операторов case (в противном случае это предотвратит действие по умолчанию для всех нажатий клавиш!)
Ответ №2:
- измените опечатку в highlight
- простой предварительный и следующий селектор
- если pre amp; next tr не найден, используйте первый / последний обычный tr в качестве следующей цели выделения
var row = $('.DataList tbody tr.highlight');
function highlight(tableIndex) {
$('.DataList tbody tr').removeClass('highlight');
$('.DataList tbody tr:eq(' tableIndex ')').addClass('highlight');
}
$(document).keydown(function (e) {
var currentRow = $('.DataList tbody tr.highlight');
var normalRowSelector = 'tr:not(.Header,.SubHeader,.Total,.highlight)';
var nextHltIndex = -1;
switch(e.which) {
case 38:
nextHltIndex = currentRow.prev(normalRowSelector).index();
if(nextHltIndex == -1){
nextHltIndex = $(normalRowSelector).filter(":last").index();
}
break;
case 40:
nextHltIndex = currentRow.next(normalRowSelector).index();
if(nextHltIndex == -1){
nextHltIndex = $(normalRowSelector).filter(":first").index();
}
break;
}
highlight(nextHltIndex);
});
.highlight {
background-color: yellow !important;
}
.Header, .SubHeader, .Total {
background-color: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="data" class="DataList" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr class="Header">
<th>#</th>
<th>header2</th>
<th>header3</th>
<th>header4</th>
<th>header5</th>
</tr>
<tr>
<td>1</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="Header">
<td>2</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="SubHeader">
<td>3</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="highlight">
<td>4</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>5</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr class="Total">
<td>6</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
</tbody>
</table>
Комментарии:
1. он не возвращается к строке # 1, он отлично работает, когда падает
Ответ №3:
Я обновил jsfiddle. Не могли бы вы ознакомиться с обновленным
Надеюсь, вам нужна эта функциональность?
Ответ №4:
Идентификатор является строго селектором, а не классом.
Попробуйте это
$('#data tr.highlight');
Ответ №5:
Я обновил jsfiddle, который вы предоставляете, и новый подход, похоже, работает просто отлично.
Используется not()
для предотвращения добавления класса highlight
к любому tr
attribute
, который имеет class
Еще одна вещь — ваша первая tr
, которая содержит все th
, что должно быть включено в thead
раздел раньше tbody
, но я не изменил его для вас, пожалуйста, сделайте это самостоятельно
Комментарии:
1. Это тот, который работает лучше всего, проблема в том, что я предоставил упрощенную структуру таблицы, которую я хочу специально избегать. Заголовок, .SubHeader, .Total это классы, но строки все еще могут иметь другие классы. При таком подходе это не сработало бы, можно ли использовать другую логику для пропуска этих дорогих стилей? Я также должен указать, что таблица не имеет фиксированного количества строк, и может быть, что индекс 0 является одним из тех классов, которых я хочу избежать
2. Я не знал, что вы хотите избежать этих классов, хотя все, что вы хотите, это избегать серых. В любом случае @Pete уже сделал это для вас, так что, думаю, мне не нужно редактировать свой. : D
3. да, в любом случае, спасибо, вы, ребята, были очень быстрыми, не ожидали так много отзывов так скоро