How do I highlight only the innermost table row of a nested table?

你。 提交于 2019-12-23 09:38:04

问题


I have several nested tables and I want to highlight the innermost row that is below the mouse pointer. How can I do that?

Some pointers: I use nested tables to display recursive tabular data. The tables can be nested 10 levels deep. The nesting is just like you would expect:

<table><tr><td>
   <table><tr><td>
      <table><tr><td>
          ...

There are can be rows which don't have nested tables. I want the highlight on the deepest / innermost <tr> that is under the mouse cursor.

I can use CSS or jQuery.


回答1:


I would like to propose something slightly more elegant (at least shorter):

Using delegated mouse events:

$('#mainTable').on('mouseenter mouseleave', 'tr', {el: false}, function (e) {
    var hl = e.data.el;
    hl && hl.removeClass('hover');

    e.data.el = (e.type === 'mouseenter') ?
        $(this).addClass('hover') :
        $(this).parent().closest('tr:hover').addClass('hover');
});

It stores the currently highlighted node in the (persistent) delegated data object and handles the mouse events, as follows:

  • If the mouse enters an element (the innermost hovered tr), remove the current highlight and highlight current element.
  • If the mouse leaves an element, highlight the closest hovered ancestor tr instead of the current one.

The main advantages of solutions using event delegation (such as $.delegate() and $.on() with a selector) are attaching only a single event listener (compared to potentially dozens, hundreds or more using traditional, per-element, methods) and being able to support dynamic changes to the element.

I chose this solution over the use if the mouseover event since I believe the enter/leave events should provide better performance, as they do not bubble.

JSFiddle.

Note:

It has a problem with jQuery 1.9.x but works with the rest, as far as I tested, including newer and older releases. This is due to an issue with the :hover pseudo-selector in that version.


CSS4

CSS level-4 has a suggested feature that can enable this behavior using CSS only:

tr, !tr:hover tr:hover {
    background-color: transparent;
}
tr:hover {
    background-color: #DDFF75;
}

Of course, since this feature is not currently final and is not supported by any major browser at the moment, this section will serve as future reference.




回答2:


Using javascript mouse events, the event target should be the deepest element:

$('tr').mouseover(function(e){
    $(e.target).parents('tr').removeClass('hover').first().addClass('hover');
});

And this to clear when mouse leaves the table:

$('#main-table').mouseout(function(e){
    $(this).find('tr').removeClass('hover');
});         

http://jsfiddle.net/tN865/1/




回答3:


This isn't as simple as it sounds since there is no "element with children with certain attributes" in CSS; selectors always only match the last element in the chain. But with a little jQuery magic, you can make it work. First the style:

.hover {
    background: #eaf0ff;
}

Then call this function whenever new tables are added:

var installInnerMostHover = function(){

    var updateHover = function() {
        $('.hover').removeClass('hover');
        $('.hover-hint').each(function(index,e) {
            if($(e).find('.hover-hint').length === 0) {
                $(e).addClass('hover');
            }
        });
    };

    $("tr").off("mouseenter mouseleave");
    $("tr").hover( function(){
        $(this).addClass('hover-hint');
        updateHover();
    },  function(){ 
        $(this).removeClass('hover-hint');
        updateHover();
    } );
};

This little gem will add hover-hint to all rows below the cursor. Afterwards, it will look for any element with the class hover-hint and then add the class hover to the all elements which don't have any children with hover-hint. There will be only one such element: The innermost row.

But when you try this, you will get an ugly flicker when you move the mouse in the space between rows of a nested table because this gap (the cell spacing) isn't part of the row as far as CSS is concerned, so the parent row will be triggered. To prevent this, you need to remove the cell spacing:

table { 
    border-spacing:0;
    border-collapse:collapse;
}


来源:https://stackoverflow.com/questions/18874829/how-do-i-highlight-only-the-innermost-table-row-of-a-nested-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!