What is the best way to select just the innermost row of a nested table for emphasis?

I am working on a project with multiple nested tables and I am looking for a way to highlight the innermost row below the mouse pointer. How can I achieve this?

Just to provide some context, I am using nested tables to present recursive tabular data, with the potential for nesting up to 10 levels deep. The structure of the nesting is straightforward, resembling the following:

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

It is worth noting that there are rows within the tables that do not contain nested tables. My goal is to highlight the deepest/innermost <tr> that the mouse cursor is hovering over.

I am open to implementing this using either CSS or jQuery. Thank you for any guidance you can provide.

Answer №1

Allow me to suggest a more concise and sophisticated approach:

Utilizing 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');
});

This method stores the currently highlighted node in a persistent delegated data object and manages the mouse events with the following logic:

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

The primary benefits of using event delegation solutions like $.delegate() and $.on() with a selector include having just a single event listener (as opposed to potentially numerous listeners with traditional methods) and the ability to accommodate dynamic changes to the element.

I opted for this solution over using the mouseover event because I believe the enter/leave events offer better performance, as they do not bubble.

JSFiddle.

Please note:

There is an issue with jQuery 1.9.x, but it functions properly with other versions I tested, including newer and older releases. This problem arises from an inconsistency with the :hover pseudo-selector in that particular version.


CSS4

CSS level-4 proposes a feature that could facilitate this behavior using CSS exclusively:

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

Although this feature is not yet finalized and lacks support from major browsers currently, this section will serve as a reference for future advancements.

Answer №2

Incorporating JavaScript mouse events is essential for targeting the deepest element:

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

Additionally, the following code is included to remove the hover effect when the mouse exits the table:

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

For a live example, visit: http://jsfiddle.net/tN865/1/

Answer №3

Creating a CSS selector to target elements with children possessing specific attributes is not a straightforward task. CSS selectors typically only target the last element in a chain. However, by utilizing some jQuery techniques, achieving this effect is possible. First, let's define the style:

.hover {
    background: #eaf0ff;
}

Next, trigger this function whenever new tables are inserted into the document:

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 function will apply the class hover-hint to all rows beneath the cursor. Then, it will identify elements with the class hover-hint and add the hover class to those elements without any children containing hover-hint. This will encompass just the innermost row.

Nevertheless, implementing this may result in an unsightly flickering effect when moving the mouse between rows of a nested table due to the cell spacing causing triggering of the parent row. To address this, remove the cell spacing as follows:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to transfer parameters from the Vue root to a component?

Currently, I am attempting to transfer a string value from index.cshtml to the main Vue element. The specific parameter I want to pass is: userId Location: Index.cshtml (this is where the parameter is obtained) @using Microsoft.AspNetCore.Identity @inje ...

Creating responsive images using Bootstrap CSS framework

I have been focusing on optimizing the banner below the navigation menu on this website. My goal is to make it responsive so that the player in the banner remains visible even when scaling down to iPhone size portrait. You can find the code for this secti ...

Tips for postponing the initiation of multiple carousels on a single page?

On my webpage, there are several bootstrap 5.3 carousels that I want to start with a delay. The plan is for each carousel to begin at different intervals – the first one after 1 second, the second after 2 seconds, the third after 3 seconds, and so forth. ...

Creating a Distinctive HTML Structure with Div Percentage (HTML 4)

I am new to web design and have a unique approach; I believe in the importance of flexibility. It puzzles me why pixels (px) are commonly used instead of percentages, maybe my perspective is misunderstood. I've been on the hunt for a basic HTML layo ...

If a quote character is detected in a string, color the line red

My goal is to highlight each line from a string in red if it contains the ">" character. I am applying this logic to a database query result, and while it's successful, I'm encountering an issue where an HTML line break is inserted after each ...

Creating a bar chart in Chart JS using an array of data objects

I need to create a unique visualization using a bar chart where each bar represents a user or student. Each bar will have an xAxis label displaying the student's name. The code below is a VueJS computed property named chartData For my bar chart data ...

Initial button click fails to trigger onclick event

After researching and reading various articles on the issue, I have tried several solutions but nothing seems to work. The problem occurs when the button is clicked for the first time - nothing happens. It is only after clicking the button a second time th ...

`The issue with the masked input feature``

Why is the Masked Input Plugin not working on a newly added input? For example: http://jsfiddle.net/yx5wa/1/ $('a.add_input').live('click', function (event) { event.preventDefault(); var newDiv = $($(this).closest('.addin ...

Creating a fixed list with top-sticking elements on a webpage using HTML

Creating a single page webapp using Vue/Vuetify, I am facing an issue with building a list (v-list) of items on the right side that requires scrolling. Even though the list is longer than the page height, I want to prevent the rest of the page from scrolli ...

Utilizing Google's Text-to-Speech Service to Download Audio Files on the Front-end

I have a specific need to transform text into audio by utilizing Google Text to Speech. Currently, I am implementing Nodejs to convert the text into an audio file and aiming to transmit the audio result to the user interface. The NodeJS code snippet is a ...

Sending an array through AJAX using JavaScript/JQuery

Check out the following JavaScript code: function SaveOrReview(Me) { var frm = document.forms[0]; var arrayDisposals; var intCount; var arrayDisposals = new Array(); for (i = 0; i < frm.elements.length; i++) ...

Utilizing Chart.js to extract and display specific data values from an external JSON file

I am currently engaged in a journey of self-exploration where I aim to create a chart depicting the number of anime shows with comedy or fantasy genres. The data for my chart will be sourced from an external JSON file (anime.json) on my computer. Initially ...

Expanding and hiding content using jQuery while also utilizing cookies for persistence

Hey there! I have a piece of code that I'm working on and could use some help. I'm trying to create a cookie that can remember the current state of a div even if the user reloads the page. Any assistance would be greatly appreciated! jQuery(fun ...

Modify the second dropdown list using Jquery when the first dropdown list changes

I have encountered an issue with using two dropdown lists. Specifically, I am trying to implement a feature where if the user selects the option "2" in the first dropdown list, a script should be executed. Here is the script: $('select[name="servic ...

Showcasing MySQL Data With Divs

Is it possible to display images from a MySQL database, specifically two images in a row, using div tags instead of tables? I've searched through various articles on Stack Overflow which all suggest using the table tag. However, I am curious if there ...

What steps do I need to take to integrate the turn.js JavaScript library with a Vue.js and Laravel project?

I am a Vuejs beginner currently working on a project that involves both Vuejs (front end) and Laravel (Backend). I have been trying to integrate the JQuery library turn.js into my project, but I keep encountering errors. While I have managed to run jQuery ...

How to execute a system command or external command in Node.js

I am encountering an issue with Node.js. When using Python, I would typically perform an external command execution like this: import subprocess subprocess.call("bower init", shell=True) Although I have explored child_process.exec and spawn in Node.js, I ...

Tips for fetching form data transmitted via HTTPS in Node.js?

As someone new to back-end security, I'm hoping for some guidance without judgement: When receiving values over HTTP in my node application, the form data is easily accessible in the request object using req.body.{name of input element} However, whe ...

Combining video.js and vue.js for seamless integration

Can anyone guide me on how to display a youtube video using a video.js player within vue.js? I'm new to integrations and not sure what it entails. Any assistance will be greatly appreciated. ...

Leveraging the power of jQuery's $.when and $.then methods for efficiently managing multiple AJAX requests that do not

My goal is to utilize jQuery to retrieve data from both an XML and JSON feed, and then only log the data when both requests are successful. When I comment out getRoomFeed() within the $.when, it returns the correct responseText object for the XML. However ...