鼠标悬停在多个td rowspan上

时间:2023-05-12 17:44:25

I have a table with multiple td rowspan. On mouse hover the entire alphabet row should come in red colour. For example, if we keep the mouse on any alphabet value the entire alphabet section should appear red. Same case for numbers also.

我有一个有多个td rowspan的表。鼠标悬停时,整个字母行应为红色。例如,如果我们将鼠标放在任何字母值上,则整个字母表部分应显示为红色。数字的情况也是如此。

Had some jQuery to achieve this but couldn't get the entire row of alphabet or numbers in same colour. Try this: http://jsfiddle.net/y3q2bs85/6/

有一些jQuery实现这一点,但无法得到相同颜色的整行字母或数字。试试这个:http://jsfiddle.net/y3q2bs85/6/

HTML code:

HTML代码:

<table>
    <tbody>
        <tr>
            <td rowspan="3">Alphabet</td>
            <td rowspan="2">a</td>
            <td>b</td>
            <td>c</td>
        </tr>
        <tr>
            <td>d</td>
            <td>e</td>
        </tr>
        <tr>
            <td>f</td>
            <td>g</td>
            <td>h</td>
        </tr>
        <tr>
            <td rowspan="3">Number</td>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>4</td>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr>
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>
    </tbody>
</table>

CSS code:

CSS代码:

body {
    padding: 50px;
}
table {
    width: 100%;
    border-collapse: collapse;
}
td, th {
    padding: 20px;
    border: 1px solid black;
}
.hover {
    background: red;
}

jQuery code:

jQuery代码:

$("td").hover(function() {
  $el = $(this);
  $el.parent().addClass("hover");

  if ($el.parent().has('td[rowspan]').length == 0)

    $el
      .parent()
      .prevAll('tr:has(td[rowspan]):first')
      .find('td[rowspan]')
      .addClass("hover");
}, function() { 

  $el
    .parent()
    .removeClass("hover")
    .prevAll('tr:has(td[rowspan]):first')
    .find('td[rowspan]')
    .removeClass("hover");

});

How can we solve this?

我们怎么解决这个问题?

4 个解决方案

#1


6  

EDIT: Added a way to find the top of each block.

编辑:添加了一种查找每个块顶部的方法。

EDIT 2 - Do the hard work up front Thinking about this again, it is better to just work out at the start which rows are in each block and store that list with each row, e.g. each alphabet row stores a reference to an array containing rows 1-4. So when you hover, you just need to get the array of rows stored in the parent row and apply the class to those.

编辑2 - 事先做好工作再考虑一下这个问题,最好在开始时解决每个块中的行,并将每个行存储在列表中,例如:每个字母行存储对包含行1-4的数组的引用。因此,当您悬停时,您只需要获取存储在父行中的行数组并将类应用于这些行。

By checking the maximum rowspan in the top row of the block, you aren't restricted to just checking the first cell. In the updated code, I have moved Alphabet to the middle to demonstrate this and add a couple of other blocks to demonstrate single row blocks work.

通过检查块顶行中的最大行距,您不仅可以检查第一个单元格。在更新的代码中,我已将Alphabet移到中间以演示此内容并添加几个其他块来演示单行块的工作原理。

function findBlocks(theTable) {
    if ($(theTable).data('hasblockrows') == null) {
        console.log('findBlocks'); // to prove we only run this once

        // we will loop through the rows but skip the ones not in a block
        var rows = $(theTable).find('tr');
        for (var i = 0; i < rows.length;) {

            var firstRow = rows[i];

            // find max rowspan in this row - this represents the size of the block
            var maxRowspan = 1;
            $(firstRow).find('td').each(function () {
                var attr = parseInt($(this).attr('rowspan') || '1', 10)
                if (attr > maxRowspan) maxRowspan = attr;
            });

            // set to the index in rows we want to go up to
            maxRowspan += i;

            // build up an array and store with each row in this block
            // this is still memory-efficient, as we are just storing a pointer to the same array
            // ... which is also nice becuase we can build the array up in the same loop
            var blockRows = [];
            for (; i < maxRowspan; i++) {
                $(rows[i]).data('blockrows', blockRows);
                blockRows.push(rows[i]);
            }

            // i is now the start of the next block
        }

        // set data against table so we know it has been inited (for if we call it in the hover event)
        $(theTable).data('hasblockrows', 1);
    }
}

$("td").hover(function () {
    $el = $(this);
    //findBlocks($el.closest('table')); // you can call it here or onload as below
    $.each($el.parent().data('blockrows'), function () {
        $(this).find('td').addClass('hover');
    });
}, function () {
    $el = $(this);
    $.each($el.parent().data('blockrows'), function () {
        $(this).find('td').removeClass('hover');
    });
});

findBlocks($('table'));
body {
    padding: 50px;
}
table {
    width: 100%;
    border-collapse: collapse;
}
td, th {
    padding: 20px;
    border: 1px solid black;
}
.hover {
    background: red;
}
<table>
    <tbody>
        <tr>
            <td>Symbols</td>
            <td>+</td>
            <td>-</td>
            <td>*</td>
        </tr>
        <tr>
            <td rowspan="2">a</td>
            <td>b</td>
            <td rowspan="4">Alphabet</td>
            <td>c</td>
        </tr>
        <tr>
            <td>d</td>
            <td>e</td>
        </tr>
        <tr>
            <td rowspan="2">f</td>
            <td>g</td>
            <td>h</td>
        </tr>
        <tr>
            <td>i</td>
            <td>j</td>
        </tr>
        <tr>
            <td>Bitwise</td>
            <td>&amp;</td>
            <td>|</td>
            <td>^</td>
        </tr>
        <tr>
            <td rowspan="3">Number</td>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>4</td>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr>
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>
    </tbody>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

#2


2  

Try this

尝试这个

        $(function () {
        $("td").hover(function () {
            $el = $(this);
            $el.parent().addClass("hover");
            var tdIndex = $('tr').index($el.parent());
            if ($el.parent().has('td[rowspan]').length == 0) {
                $el.parent().prevAll('tr:has(td[rowspan]):first')
                        .find('td[rowspan]').filter(function () {
                            return checkRowSpan(this, tdIndex);
                        }).addClass("hover");
            }
        }, function () {
            $el.parent()
    .removeClass("hover")
    .prevAll('tr:has(td[rowspan]):first')
    .find('td[rowspan]')
    .removeClass("hover");

        });
    });
    function checkRowSpan(element, pIndex) {
        var rowSpan = parseInt($(element).attr('rowspan'));
        var cIndex = $('tr').index($(element).parent());
        return rowSpan >= pIndex + 1 || (cIndex + rowSpan) > pIndex;
    }

Fiddler here

提琴手在这里

#3


1  

Your table structure is irregular, so it's very hard to find a selector that will select the visual "row", as it spans different rows. One solution is to color the cells by hand, take a look at http://jsfiddle.net/2szxsfcs/2/

您的表结构是不规则的,因此很难找到一个选择器来选择视觉“行”,因为它跨越不同的行。一种解决方案是手工着色细胞,看看http://jsfiddle.net/2szxsfcs/2/

Basically you tag the rows that are meant to be colored together with the same id, then using jquery you color / uncolor all related TR's:

基本上你用相同的id标记要着色的行,然后使用jquery为所有相关的TR着色/取色:

<table>
  <tbody>
        <tr class="fullrow row1" data-id="1">
            <td rowspan="3">Alphabet</td>
            <td rowspan="2">a</td>
            <td>b</td>
            <td>c</td>
        </tr>
        <tr  class="fullrow row1" data-id="1">
            <td>d</td>
            <td>e</td>          
        </tr>
        <tr class="fullrow row1" data-id="1">
            <td>f</td>
            <td>g</td>
            <td>h</td>
        </tr>
        <tr class="fullrow row2" data-id="2">
            <td rowspan="3">Number</td>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr class="fullrow row2" data-id="2">
            <td>4</td>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr class="fullrow row2" data-id="2">
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>   
    </tbody>
</table>

and

  $(".fullrow")
    .hover(function() {
        var id=this.getAttribute("data-id");
        // on hover, we get an "id", and all tr's that have class "row<id>" are the ones to color
        $(".row"+id).addClass("hovering"); 
    })
    .on ("blur mouseleave", function() {
      var id=this.getAttribute("data-id");
      $(".row"+id).removeClass("hovering"); 
    });

and

.hovering { background-color:red; }

#4


0  

Let me try the <div> way. This solves several problems, but new ones araise.

让我试试

方式。这解决了几个问题,但新的问题。

fiddle here: http://jsfiddle.net/cforcloud/3wj20bmL/
Note: this uses bootstrap grid system

这里小提琴:http://jsfiddle.net/cforcloud/3wj20bmL/注意:这使用bootstrap网格系统

Its needs little jquery to find the content cells. divs which have no children become .cell

找到内容单元需要很少的jquery。没有孩子的div成为.cell

$('.row div').filter(function () {
    return $(this).children().length == 0;
})
    .addClass('cell')
    .hover(

function () {
    $(this).parent('.row')
        .addClass('sele');


}, function () {});

#1


6  

EDIT: Added a way to find the top of each block.

编辑:添加了一种查找每个块顶部的方法。

EDIT 2 - Do the hard work up front Thinking about this again, it is better to just work out at the start which rows are in each block and store that list with each row, e.g. each alphabet row stores a reference to an array containing rows 1-4. So when you hover, you just need to get the array of rows stored in the parent row and apply the class to those.

编辑2 - 事先做好工作再考虑一下这个问题,最好在开始时解决每个块中的行,并将每个行存储在列表中,例如:每个字母行存储对包含行1-4的数组的引用。因此,当您悬停时,您只需要获取存储在父行中的行数组并将类应用于这些行。

By checking the maximum rowspan in the top row of the block, you aren't restricted to just checking the first cell. In the updated code, I have moved Alphabet to the middle to demonstrate this and add a couple of other blocks to demonstrate single row blocks work.

通过检查块顶行中的最大行距,您不仅可以检查第一个单元格。在更新的代码中,我已将Alphabet移到中间以演示此内容并添加几个其他块来演示单行块的工作原理。

function findBlocks(theTable) {
    if ($(theTable).data('hasblockrows') == null) {
        console.log('findBlocks'); // to prove we only run this once

        // we will loop through the rows but skip the ones not in a block
        var rows = $(theTable).find('tr');
        for (var i = 0; i < rows.length;) {

            var firstRow = rows[i];

            // find max rowspan in this row - this represents the size of the block
            var maxRowspan = 1;
            $(firstRow).find('td').each(function () {
                var attr = parseInt($(this).attr('rowspan') || '1', 10)
                if (attr > maxRowspan) maxRowspan = attr;
            });

            // set to the index in rows we want to go up to
            maxRowspan += i;

            // build up an array and store with each row in this block
            // this is still memory-efficient, as we are just storing a pointer to the same array
            // ... which is also nice becuase we can build the array up in the same loop
            var blockRows = [];
            for (; i < maxRowspan; i++) {
                $(rows[i]).data('blockrows', blockRows);
                blockRows.push(rows[i]);
            }

            // i is now the start of the next block
        }

        // set data against table so we know it has been inited (for if we call it in the hover event)
        $(theTable).data('hasblockrows', 1);
    }
}

$("td").hover(function () {
    $el = $(this);
    //findBlocks($el.closest('table')); // you can call it here or onload as below
    $.each($el.parent().data('blockrows'), function () {
        $(this).find('td').addClass('hover');
    });
}, function () {
    $el = $(this);
    $.each($el.parent().data('blockrows'), function () {
        $(this).find('td').removeClass('hover');
    });
});

findBlocks($('table'));
body {
    padding: 50px;
}
table {
    width: 100%;
    border-collapse: collapse;
}
td, th {
    padding: 20px;
    border: 1px solid black;
}
.hover {
    background: red;
}
<table>
    <tbody>
        <tr>
            <td>Symbols</td>
            <td>+</td>
            <td>-</td>
            <td>*</td>
        </tr>
        <tr>
            <td rowspan="2">a</td>
            <td>b</td>
            <td rowspan="4">Alphabet</td>
            <td>c</td>
        </tr>
        <tr>
            <td>d</td>
            <td>e</td>
        </tr>
        <tr>
            <td rowspan="2">f</td>
            <td>g</td>
            <td>h</td>
        </tr>
        <tr>
            <td>i</td>
            <td>j</td>
        </tr>
        <tr>
            <td>Bitwise</td>
            <td>&amp;</td>
            <td>|</td>
            <td>^</td>
        </tr>
        <tr>
            <td rowspan="3">Number</td>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>4</td>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr>
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>
    </tbody>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

#2


2  

Try this

尝试这个

        $(function () {
        $("td").hover(function () {
            $el = $(this);
            $el.parent().addClass("hover");
            var tdIndex = $('tr').index($el.parent());
            if ($el.parent().has('td[rowspan]').length == 0) {
                $el.parent().prevAll('tr:has(td[rowspan]):first')
                        .find('td[rowspan]').filter(function () {
                            return checkRowSpan(this, tdIndex);
                        }).addClass("hover");
            }
        }, function () {
            $el.parent()
    .removeClass("hover")
    .prevAll('tr:has(td[rowspan]):first')
    .find('td[rowspan]')
    .removeClass("hover");

        });
    });
    function checkRowSpan(element, pIndex) {
        var rowSpan = parseInt($(element).attr('rowspan'));
        var cIndex = $('tr').index($(element).parent());
        return rowSpan >= pIndex + 1 || (cIndex + rowSpan) > pIndex;
    }

Fiddler here

提琴手在这里

#3


1  

Your table structure is irregular, so it's very hard to find a selector that will select the visual "row", as it spans different rows. One solution is to color the cells by hand, take a look at http://jsfiddle.net/2szxsfcs/2/

您的表结构是不规则的,因此很难找到一个选择器来选择视觉“行”,因为它跨越不同的行。一种解决方案是手工着色细胞,看看http://jsfiddle.net/2szxsfcs/2/

Basically you tag the rows that are meant to be colored together with the same id, then using jquery you color / uncolor all related TR's:

基本上你用相同的id标记要着色的行,然后使用jquery为所有相关的TR着色/取色:

<table>
  <tbody>
        <tr class="fullrow row1" data-id="1">
            <td rowspan="3">Alphabet</td>
            <td rowspan="2">a</td>
            <td>b</td>
            <td>c</td>
        </tr>
        <tr  class="fullrow row1" data-id="1">
            <td>d</td>
            <td>e</td>          
        </tr>
        <tr class="fullrow row1" data-id="1">
            <td>f</td>
            <td>g</td>
            <td>h</td>
        </tr>
        <tr class="fullrow row2" data-id="2">
            <td rowspan="3">Number</td>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr class="fullrow row2" data-id="2">
            <td>4</td>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr class="fullrow row2" data-id="2">
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>   
    </tbody>
</table>

and

  $(".fullrow")
    .hover(function() {
        var id=this.getAttribute("data-id");
        // on hover, we get an "id", and all tr's that have class "row<id>" are the ones to color
        $(".row"+id).addClass("hovering"); 
    })
    .on ("blur mouseleave", function() {
      var id=this.getAttribute("data-id");
      $(".row"+id).removeClass("hovering"); 
    });

and

.hovering { background-color:red; }

#4


0  

Let me try the <div> way. This solves several problems, but new ones araise.

让我试试

方式。这解决了几个问题,但新的问题。

fiddle here: http://jsfiddle.net/cforcloud/3wj20bmL/
Note: this uses bootstrap grid system

这里小提琴:http://jsfiddle.net/cforcloud/3wj20bmL/注意:这使用bootstrap网格系统

Its needs little jquery to find the content cells. divs which have no children become .cell

找到内容单元需要很少的jquery。没有孩子的div成为.cell

$('.row div').filter(function () {
    return $(this).children().length == 0;
})
    .addClass('cell')
    .hover(

function () {
    $(this).parent('.row')
        .addClass('sele');


}, function () {});