简体   繁体   English

添加使用向上和向下箭头键选择表格行的功能

[英]Adding functionality for using the up and down arrow keys to select a table row

I need the help of an expert on my question below as it exceed and goes well beyond the level of knowledge that I have for programming in JavaScript. 我需要以下问题的专家帮助,因为它超出了我用于JavaScript编程的知识水平。

Given the existing JavaScript coding below, how can I piggy back and add onto the existing coding so as to add functionality for a user to use their up and down arrow keys to scroll through the table, while they are scrolling through (btw the header column exempt) it would highlight the selected row and change its row color. 鉴于下面的现有JavaScript编码,我如何能够捎带并添加到现有编码上,以便为用户添加功能,以便在滚动浏览表时使用上下箭头键滚动表格(顺便说一下标题列)它将突出显示所选行并更改其行颜色。

A point to note that if an existing table row is selected, and I hit my up or down arrow key, it would just move to and highlight the previous and next row. 需要注意的是,如果选择了现有的表格行,并且按下向上或向下箭头键,则只会移动并突出显示上一行和下一行。 Some logic here is that I am guessing that one would need to find the row index to do this. 这里的一些逻辑是我猜测需要找到行索引来执行此操作。 Like I said, it is well beyond what I know how to do. 就像我说的那样,它远远超出我所知道的范围。

Much thanks and a huge appreciation for all your help. 非常感谢并非常感谢您的帮助。

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
tr.normal td {
    color: black;
    background-color: white;
}
tr.highlighted td {
    color: white;
    background-color: red;
}
</style>
</head>
<body>
<div id="results" class="scrollingdatagrid">
  <table id="mstrTable" cellspacing="0" border="1">
     <thead>
      <tr> 
        <th>File Number</th>
        <th>Date1</th>
        <th>Date2</th>
        <th>Status</th>
        <th>Num.</th>
      </tr>
    </thead>
    <tbody>
      <tr> 
        <td>KABC</td>
        <td>09/12/2002</td>
        <td>09/12/2002</td>
        <td>Submitted</td>
        <td>1</td>

      </tr>
      <tr> 
        <td>KCBS</td>
        <td>09/11/2002</td>
        <td>09/11/2002</td>
        <td>Lockdown</td>
        <td>2</td>
      </tr>

      <tr> 
        <td>WFLA</td>
        <td>09/11/2002</td>
        <td>09/11/2002</td>
        <td>Submitted</td>
        <td>3</td>
      </tr>
      <tr> 
        <td>WTSP</td>
        <td>09/15/2002</td>
        <td>09/15/2002</td>
        <td>In-Progress</td>
        <td>4</td>
      </tr>
    </tbody>
  </table>
</div>

<script type="text/javascript">
(
function() {
var trows = document.getElementById("mstrTable").rows;

    for (var t = 1; t < trows.length; ++t) {
        trow = trows[t];
        trow.className = "normal";
        trow.onclick = highlightRow;
    }//end for

    function highlightRow() {
        for ( var t = 1; t < trows.length; ++t ) {
            trow = trows[t];
            if (trow != this) { trow.className = "normal" }
        }//end for

        this.className = (this.className == "highlighted")?"normal":"highlighted";
      }//end function



  }//end function

)();//end script
</script>
</body>
</html>

This is certainly not optimal, but as you're not using jQuery (or a similar library) you've incurred a lot of cross browser overhead. 这肯定不是最佳的,但是由于您没有使用jQuery(或类似的库),因此会产生大量的跨浏览器开销。 This should be backwards compatible up to IE8. 这应该向后兼容IE8。

Live Demo 现场演示

HTML HTML

Only change here is the addition of the tabindex 只有这里更改是tabindex

<table tabindex='0' id="mstrTable" cellspacing="0" border="1">

JS JS

//From: http://forrst.com/posts/JavaScript_Cross_Browser_Event_Binding-yMd
var addEvent = (function( window, document ) {
    if ( document.addEventListener ) {
        return function( elem, type, cb ) {
            if ( (elem && !elem.length) || elem === window ) {
                elem.addEventListener(type, cb, false );
            }
            else if ( elem && elem.length ) {
                var len = elem.length;
                for ( var i = 0; i < len; i++ ) {
                    addEvent( elem[i], type, cb );
                }
            }
        };
    }
    else if ( document.attachEvent ) {
        return function ( elem, type, cb ) {
            if ( (elem && !elem.length) || elem === window ) {
                elem.attachEvent( 'on' + type, function() { return cb.call(elem, window.event) } );
            }
            else if ( elem.length ) {
                var len = elem.length;
                for ( var i = 0; i < len; i++ ) {
                    addEvent( elem[i], type, cb );
                }
            }
        };
    }
})( this, document );

//derived from: http://stackoverflow.com/a/10924150/402706
function getpreviousSibling(element) {
    var p = element;
    do p = p.previousSibling;
    while (p && p.nodeType != 1);
    return p;
}

//derived from: http://stackoverflow.com/a/10924150/402706
function getnextSibling(element) {
    var p = element;
    do p = p.nextSibling;
    while (p && p.nodeType != 1);
    return p;
}

;(function() {
    var trows = document.getElementById("mstrTable").rows;

    for (var t = 1; t < trows.length; ++t) {
        trow = trows[t];
        trow.className = "normal";
        trow.onclick = highlightRow;
    }//end for

    function highlightRow() {
        for ( var t = 1; t < trows.length; ++t ) {
            trow = trows[t];
            if (trow != this) { trow.className = "normal" }
        }//end for

        this.className = (this.className == "highlighted")?"normal":"highlighted";
    }//end function

    addEvent(document.getElementById('mstrTable'), 'keydown', function(e){
        var key = e.keyCode || e.which;

        if((key === 38 || key === 40) && !e.shiftKey && !e.metaKey && !e.ctrlKey && !e.altKey){

            var highlightedRows = document.querySelectorAll('.highlighted'); 

            if(highlightedRows.length > 0){

                var highlightedRow = highlightedRows[0];

                var prev = getpreviousSibling(highlightedRow); 
                var next = getnextSibling(highlightedRow); 

                if(key === 38 && prev && prev.nodeName === highlightedRow.nodeName){//up
                    highlightedRow.className = 'normal';
                    prev.className = 'highlighted';
                } else if(key === 40 && next && next.nodeName === highlightedRow.nodeName){ //down
                    highlightedRow.className = 'normal';
                    next.className = 'highlighted';
                }

            }
        }

    });


})();//end script

I don't think this actually needs to be that long--you just need to keep the index of the currently highlighted row. 我认为这实际上不需要那么久 - 你只需要保留当前突出显示的行的索引。

This has only been tested on Chrome (I don't have IE), but it should work. 这只在Chrome上测试过(我没有IE),但应该可以使用。

(function() {


/**
 * Gets the tr at the specified row or column
 */
var tbody = document.getElementsByTagName('tbody')[0];
function getRow(row) {
    return tbody.getElementsByTagName('tr')[row];
}

// store these so we won't have to keep recalculating
var numRows = tbody.getElementsByTagName('tr').length;

// index of the currently highlighted row
var curRow = 0;

// highlight the initially highlighted cell
getRow(curRow).className = 'highlighted';




// listen for keydown event
if (addEventListener) {
  window.addEventListener('keydown',keydownHandler, false);
} else if (window.attachEvent) {
  window.attachEvent('onkeydown', keydownHandler);
}



// handle keydown event
function keydownHandler (evt) {
    // return the old cell to normal
    getRow(curRow).className = 'normal';

    // increment/decrement the position of the current cell
    // depending on the key pressed
    if (evt.keyCode == 38 && curRow > 0) // up
        curRow--;
    else if (evt.keyCode == 40 && curRow < numRows-1) // down
        curRow++;

    // update the new cell
    getRow(curRow).className = 'highlighted';  
}


})();//end script

I have create a demo using JQuery here on JSBin 在JSBin上使用JQuery创建了一个demo

In general, we have 2 task: 一般来说,我们有2个任务:

  • highlight selected row 突出显示所选行
  • choose next/prev row 选择next / prev row

To highlight the "clicked" row, I use this code 要突出显示“单击”行,我使用此代码

$("#mstrTable tr").click(function(evt){
   var element = $(evt.target);
   var tableElement = element.parents('table');
   tableElement.find('tr').removeClass('highlighted');
   element.parents('tr').addClass('highlighted');
});

To choose next/prev row, I use jQuery tree traversal function with some exception when there is no tr inside your tbody . 要选择next / prev行,我使用jQuery 树遍历函数 ,当你的tbody没有tr时会有一些异常。 Note that keyCode of left, right, up, down arrow are 37, 39, 38, 40 respectively. 请注意,左,右,上,下箭头的keyCode分别为37,39,38,40。

$(document).keypress(function(evt){
          var highlightedRow = $("#mstrTable .highlighted");
          if (highlightedRow.length > 0) // table cell is selected
          {
            var tbodyElement = highlightedRow.parents('tbody');
            var trElements = tbodyElement.find('tr');
            var nextElement =  highlightedRow.next('tr');
            var prevElement = highlightedRow.prev('tr');
            trElements.removeClass("highlighted");
            switch(evt.keyCode)
            {
              case 40:
                if(nextElement.length)
                {
                  nextElement.addClass('highlighted');
                }
                else if (trElements.length)
                {
                  $(trElements[0]).addClass('highlighted'); 
                }
                break;
              case 38:
                if(prevElement.length)
                {
                  prevElement.addClass('highlighted');
                }
                else if (trElements.length)
                {
                  $(trElements[trElements.length - 1]).addClass('highlighted'); 
                }
                break;
            }
          }
        });

Here is the complete solution which selects rows in table just like a windows file selection works. 这是完整的解决方案,它选择表中的行,就像Windows文件选择一样。

add class multiSelect to you table and then place this code in a JS file 将类multiSelect添加到您的表中,然后将此代码放在JS文件中

$(document).ready(function() {  
var selectionPivot; 
// code for selected rows. 
$('.multiSelect tbody').on( 'click', 'tr', function (e) {
var tbodyElement = $(this).parents('tbody');
var trElements = tbodyElement.find('tr');
if(!e.ctrlKey && (!e.shiftKey) ){   
  trElements.removeClass("row_selected");
  selectionPivot=$(this);
 } 

if(e.shiftKey){ 
var bot = Math.min(selectionPivot[0].rowIndex, $(this)[0].rowIndex);
var top = Math.max(selectionPivot[0].rowIndex, $(this)[0].rowIndex);
trElements.removeClass("row_selected");
for(var i=bot; i<=top; i++){    
trElements[i-1].className+=" row_selected";
}     
}  
else  { 
   selectionPivot=$(this);
   trElements.removeClass("focus"); 
   $(this).addClass('focus');
    if ( $(this).hasClass('row_selected') ) {
    $(this).removeClass('row_selected');
    }
    else {      
        $(this).addClass('row_selected');
    }
}
});

$(document).keypress(function(evt){
if(evt.shiftKey){
      var highlightedRow = $(".multiSelect .focus");        
      if (highlightedRow.length > 0) // table cell is selected
      {
        var tbodyElement = highlightedRow.parents('tbody');
        var trElements = tbodyElement.find('tr');
        var nextElement =  highlightedRow.next('tr');
        var prevElement = highlightedRow.prev('tr');
        trElements.removeClass("focus");
        switch(evt.keyCode)
        {
          case 40:
            if(nextElement.length)
            {
              nextElement.addClass('row_selected');
              nextElement.addClass('focus');
            }
            else if (trElements.length)
            {
              $(trElements[0]).addClass('row_selected'); 
               $(trElements[0]).addClass('focus');
            }
            break;
          case 38:
            if(prevElement.length)
            {
              prevElement.addClass('row_selected');
              prevElement.addClass('focus');
            }
            else if (trElements.length)
            {
              $(trElements[trElements.length - 1]).addClass('row_selected'); 
                $(trElements[trElements.length - 1]).addClass('focus');
            }
            break;
        }
      }
      }
    });
    });

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

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