【问题标题】:mouse hover with multiple td rowspan鼠标悬停多个 td 行跨度
【发布时间】:2014-12-05 14:46:47
【问题描述】:

我有一张包含多个td rowspan 的表格。在鼠标悬停时,整个字母行应变为红色。例如,如果我们将鼠标放在任何字母值上,整个字母部分应该显示为红色。数字也一样。

我尝试了一些 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");
});
body {
  padding: 50px;
}

table {
  width: 100%;
  border-collapse: collapse;
}

td,
th {
  padding: 20px;
  border: 1px solid black;
}

.hover {
  background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<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>

我们如何解决这个问题?

【问题讨论】:

  • 您的 JSFiddle 似乎工作正常 - 鼠标悬停时,数字/字母行变为红色。
  • 最简单的方法是使用嵌套表,可以改html代码吗?
  • @SamyS.Rathore 鼠标悬停整个字母行应该变成红色 - 猜测这意味着,“如果我将鼠标悬停在字母上,我希望突出显示三行。如果我将鼠标悬停在 A 上,我希望突出显示两行“
  • @RajasekharBammidi,如果我将鼠标悬停在“A”上,您是否也希望突出显示“字母”?是吗?
  • @MrCoder 如果我将鼠标悬停在 A 上,除了它之后的两行(bc 和 de)之外,第一列(带有“字母”文本)也会被选中,这意味着所有其他字母也应该是红色的。总而言之,他希望网格表现为两行,字母和数字,是这样吗??

标签: jquery html css


【解决方案1】:

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

编辑 2 - 提前做好工作 再次考虑这一点,最好从一开始就计算出每个块中有哪些行并将该列表与每一行一起存储,例如每个字母行存储对包含第 1-4 行的数组的引用。因此,当您悬停时,您只需要获取存储在父行中的行数组并将类应用于这些行。

通过检查块顶行中的最大行跨度,您不仅限于检查第一个单元格。在更新后的代码中,我将 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>

【讨论】:

  • 感谢您的解决方案。您已接近我的要求,但如果我还有一个行跨度,那么它不会突出显示整个部分,因为该表具有动态数据。这是 jsfiddle 链接:jsfiddle.net/y3q2bs85/14.. 如果我将鼠标悬停在“f”上,它不会以红色突出显示整个部分。
  • 太棒了,正是我现在正在寻找的 :)
【解决方案2】:

试试这个

        $(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】:

    您的表格结构是不规则的,因此很难找到可以选择视觉“行”的选择器,因为它跨越不同的行。一种解决方法是手动给单元格上色,看看http://jsfiddle.net/2szxsfcs/2/

    基本上你用相同的 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>
    

      $(".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"); 
        });
    

    .hovering { background-color:red; }
    

    【讨论】:

    • 这是一个干净的解决方案。即除非他必须动态添加行,否则在这种情况下,他必须添加逻辑以在必须悬停在一起的行上添加类。
    • 是的...这是唯一的缺点,但是您必须添加的东西是“动态友好的”,即只有 id 和类。
    【解决方案4】:

    让我试试

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

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

    它需要很少的 jquery 来查找内容单元格。没有子元素的 div 变成 .cell

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 2011-08-04
      • 2018-09-03
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多