简体   繁体   English

ALT+箭头键在表格中的单元格之间导航

[英]ALT+arrow keys to navigate between cells in table

Run the snippet below and focus the first input of the table.运行下面的代码片段并关注表的第一个输入。
Use the ALT key+any arrow key on your keyboard to navigate between the cells.使用键盘上的 ALT 键+任意箭头键在单元格之间导航。
Moving forward or down works great, but when you reach the third row it will take you up to the first cell instead of the second cell if your focus is on a div (compare to an input where it actually works).向前或向下移动效果很好,但是当您到达第三行时,如果您的焦点在 div 上(与实际工作的输入相比),它会将您带到第一个单元格而不是第二个单元格。
The next problem is that if you press ALT+left arrow it will take you back to the first cell, when you should move to the previous cell.下一个问题是,如果您按 ALT+向左箭头,它将带您回到第一个单元格,而此时您应该移动到上一个单元格。

Does it have anything to do with the $new_field[0] ?它与$new_field[0]有什么关系吗?

 function placeCaretAtEnd(el) { el.focus(); if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") { var range = document.createRange(); range.selectNodeContents(el); range.collapse(false); var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (typeof document.body.createTextRange != "undefined") { var textRange = document.body.createTextRange(); textRange.moveToElementText(el); textRange.collapse(false); textRange.select(); } } $(document).on('keydown', '.field', function(e) { // If arrow up / down if( (e.which == 38 || e.which == 40 || e.which == 37 || e.which == 39) && e.altKey ) { var $self = $(this); var $field = $self.closest('td.nav-field:visible'); var data_field = $field.attr('data-field'); var $row = $self.closest('tr'); if( e.which == 38 ) { var $target = $row.prevAll('tr:visible'); $new_field = $target.find('td.nav-field[data-field="' + data_field + '"]:visible .field'); } else if( e.which == 40 ) { var $target = $row.nextAll('tr:visible').eq(0); $new_field = $target.find('td.nav-field[data-field="' + data_field + '"]:visible .field'); } else if( e.which == 37 ) { var $target = $field.prevAll('td.nav-field:visible'); $new_field = $target.find('.field'); } else if( e.which == 39 ) { var $target = $field.nextAll('td.nav-field:visible').eq(0); $new_field = $target.find('.field'); } setTimeout(function() { if( $new_field.is('input') ) { $new_field.select(); } else if( $new_field.is('div[contenteditable]') ) { placeCaretAtEnd($new_field[0]); } else { $new_field.focus(); } }, 1); } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table> <tr> <td data-field="1" class="nav-field"><input value="Input 1" class="field"></td> <td data-field="2" class="nav-field"><div contenteditable="true" class="field">Content Editable 1</div></td> <td data-field="3" class="nav-field" style="display: none;"><input value="Input 2" class="field"></td> <td data-field="4" class="nav-field"><div contenteditable="true" class="field">Content Editable 2</div></td> <td data-field="5" class="nav-field"><input value="Input 3" class="field"></td> <td data-field="6">Not Editable</td> </tr> <tr style="display: none;"> <td data-field="1" class="nav-field"><input value="Input 1" class="field"></td> <td data-field="2" class="nav-field"><div contenteditable="true" class="field">Content Editable 1</div></td> <td data-field="3" class="nav-field" style="display: none;"><input value="Input 2" class="field"></td> <td data-field="4" class="nav-field"><div contenteditable="true" class="field">Content Editable 2</div></td> <td data-field="5" class="nav-field"><input value="Input 3" class="field"></td> <td data-field="6">Not Editable</td> </tr> <tr> <td data-field="1" class="nav-field"><input value="Input 1" class="field"></td> <td data-field="2" class="nav-field"><div contenteditable="true" class="field">Content Editable 1</div></td> <td data-field="3" class="nav-field" style="display: none;" class="field"><input value="Input 2"></td> <td data-field="4" class="nav-field"><div contenteditable="true" class="field">Content Editable 2</div></td> <td data-field="5" class="nav-field"><input value="Input 3" class="field"></td> <td data-field="6">Not Editable</td> </tr> <tr> <td data-field="1" class="nav-field"><input value="Input 1" class="field"></td> <td data-field="2" class="nav-field"><div contenteditable="true" class="field">Content Editable 1</div></td> <td data-field="3" class="nav-field" style="display: none;" class="field"><input value="Input 2"></td> <td data-field="4" class="nav-field"><div contenteditable="true" class="field">Content Editable 2</div></td> <td data-field="5" class="nav-field"><input value="Input 3" class="field"></td> <td data-field="6">Not Editable</td> </tr> </table>

I do not see why I should make you a complete solution, so here is just an example of using native Javascript methods to handle your problem...我不明白为什么我应该给你一个完整的解决方案,所以这里只是一个使用原生 Javascript 方法来处理你的问题的例子......

 const myTable = document.querySelector('#my-Table tbody') , nbRows = myTable.rows.length , nbCells = myTable.rows[0].cells.length , moving = { ArrowUp : p=>{ pr = (--pr +nbRows ) % nbRows } , ArrowLeft : p=>{ pc = (--pc +nbCells) % nbCells } , ArrowDown : p=>{ pr = ++pr % nbRows } , ArrowRight : p=>{ pc = ++pc % nbCells } } document.onkeydown=e=> { let currentPos = myTable.querySelector('.select') , evt = (e==null ? event:e) , pos = { r:currentPos.parentNode.rowIndex , c:currentPos.cellIndex } if ( evt.altKey && moving[evt.code] ) { moving[evt.code](pos) currentPos.classList.remove('select') myTable.rows[pos.r].cells[pos.c].classList.add('select') } }
 #my-Table { border-collapse: collapse; font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; font-size: 14px; } #my-Table td { width:20px; text-align: center; border: 1px solid grey; padding: 2px 5px; white-space: nowrap; } .select { background-color: aqua }
 <p>ALt arrow key usage...</p> <table id="my-Table"> <tbody> <tr><td class='select'>a</td><td>b</td><td>c</td><td>d</td></tr> <tr><td>e</td><td>f</td><td>g</td><td>h</td></tr> <tr><td>i</td><td>j</td><td>k</td><td>l</td></tr> <tr><td>m</td><td>n</td><td>o</td><td>p</td></tr> <tr><td>q</td><td>r</td><td>s</td><td>t</td></tr> </tbody> </table>

It's not that I wanted to do it, but when a problem has entered my mind, I want to finish it.不是我想这样做,而是当一个问题进入我的脑海时,我想完成它。

move key is [alt] + [shift] + [arrow keys] because [alt] + [arrow keys] corresponding for window moves on my computer (LINUX)移动键是 [alt] + [shift] + [箭头键] 因为 [alt] + [箭头键] 对应于我电脑上的窗口移动 (LINUX)

 const myTable = document.querySelector('#my-Table tbody') , nbRows = myTable.rows.length , nbCells = myTable.rows[0].cells.length , movKey = { ArrowUp : p=>{ pr = (--pr +nbRows ) % nbRows } , ArrowLeft : p=>{ pc = (--pc +nbCells) % nbCells } , ArrowDown : p=>{ pr = ++pr % nbRows } , ArrowRight : p=>{ pc = ++pc % nbCells } } // get On Focus event on Table elements myTable .querySelectorAll('input, [contenteditable=true]') .forEach(elm=>{elm.onfocus=e=> { let sPos = myTable.querySelector('.select') , tdPos = elm.parentNode if (sPos) sPos.classList.remove('select') tdPos.classList.add('select') } }) document.onkeydown=e=> { let sPos = myTable.querySelector('.select') , evt = (e==null ? event:e) , pos = { r: sPos?sPos.parentNode.rowIndex:-1 , c: sPos?sPos.cellIndex:-1 } if ( sPos // previous pos focus exist... && evt.altKey && evt.shiftKey // addin shift to control && movKey[evt.code] ) // evt.ctrlKey... ? { let loop = true , nxFocus = null , cell = null do { movKey[evt.code](pos) cell = myTable.rows[pos.r].cells[pos.c] // possible <td> for new focus... nxFocus = cell.querySelector('input, [contenteditable=true]') // get focussable element of <td> if ( nxFocus && cell.style.display!=='none' && cell.parentNode.style.display!=='none') { nxFocus.focus() loop = false } } while (loop) } }
 #my-Table { border-collapse: collapse; font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; font-size: 14px; } #my-Table td { min-width:20px; text-align: center; border: 1px solid grey; padding: 2px 5px; white-space: nowrap; } .select { background-color: aqua } /* just for the control, delete this line when commissioning the operation */
 <table id="my-Table"> <tbody> <tr> <td><input placeholder="r0, c0"></td> <td><div contenteditable="true">Content Editable 1 r0, c1</div></td> <td style="display: none;"><input placeholder="r0, c2"></td> <td><div contenteditable="true">Content Editable 2 r0, c3</div></td> <td><input placeholder="r0, c4"></td> <td>Not Editable</td> </tr> <tr style="display: none;"> <td><input placeholder="r1, c1"></td><td><div contenteditable=" true">Content Editable 1</div></td> <td style="display: none;"><input value="Input 2"></td> <td><div contenteditable="true">Content Editable 2</div></td> <td><input value="Input 3"></td> <td>Not Editable</td> </tr> <tr> <td><input placeholder="r2, c0"></td> <td><div contenteditable="true">Content Editable 1</div></td> <td style="display: none;"><input value="Input 2"></td> <td><div contenteditable="true">Content Editable 2</div></td> <td><input value="Input 3"></td> <td>Not Editable</td> </tr> <tr> <td><input value="Input 1"></td> <td><div contenteditable="true">Content Editable 1</div></td> <td style="display: none;"><input value="Input 2"></td> <td><div contenteditable="true">Content Editable 2</div></td> <td><input value="Input 3"></td> <td>Not Editable</td> </tr> </tbody> </table>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM