简体   繁体   English

CSS / JS:将鼠标悬停在元素上会突出显示另一个元素

[英]CSS/JS: Hover over element highlights another element

I'm creating a grid that can have n rows and is separated into two views: a leftChild and a rightChild. 我正在创建一个可以有n rows并分为两个视图的网格:leftChild和rightChild。 The leftChild has the same amount of rows as the rightChild but the leftChild stays in its place. leftChild与rightChild的行数相同,但leftChild保留在原处。 The only difference with the rightChild is that it can be scrolled horizontally. 与rightChild的唯一区别是它可以水平滚动。 When I hover over a leftChild or rightChild element, I want to add some sort of hovering effect... that's easy, but what I want to do is add a hovering effect across the entire row. 当我将鼠标悬停在leftChild或rightChild元素上时,我想添加某种悬停效果……这很容易,但是我想要做的是在整个行中添加悬停效果。 So if I hover over the 3rd row in the leftChild, I want to highlight the 3rd row in the rightChild. 因此,如果将鼠标悬停在leftChild的第三行上,则要突出显示rightChild的第三行。

Now, ideally, I'd love a complete CSS solution, similar to this , but that's not possible because my rows don't follow directly after each other. 现在,理想情况下,我希望有一个类似于this的完整CSS解决方案,但这是不可能的,因为我的行不会紧跟彼此。 I was trying to think of another way of solving this, but it doesn't seem possible with straight CSS. 我试图考虑解决此问题的另一种方法,但是使用直接CSS似乎不可能。

Enter JavaScript. 输入JavaScript。 I'm thinking the next step is to combine JavaScript with CSS. 我在想下一步是将JavaScript与CSS结合起来。 I can add a hover effect to a row, and then use JavaScript to add a hover class to the corresponding row in the other child. 我可以将悬停效果添加到一行,然后使用JavaScript将悬停类添加到另一个孩子的相应行中。 This is quite simple with jQuery, but I'm looking for a native JavaScript approach. 使用jQuery相当简单,但是我正在寻找一种本机JavaScript方法。

The main approach I'm thinking of is adding a mouseenter and mouseleave on each row class element. 我正在考虑的主要方法是在每个行类元素上添加mouseentermouseleave I don't really like this approach because then I'm setting up 2 event listeners on each row element... which seems a bit inefficient. 我真的不喜欢这种方法,因为那时候我在每个行元素上设置了2个事件侦听器……这似乎效率不高。 Anyway, when you enter, you grab the row number of what you hovered, then add the hover class to all of these row number elements. 无论如何,当您输入时,您将获取要悬停的行的行号,然后将悬停类添加到所有这些行号元素中。 When you leave, you just find all elements with hover, and remove accordingly. 离开时,只需找到所有带有悬停的元素,然后相应地将其删除。 The corresponding code is as follows: 相应的代码如下:

HTML 的HTML

<body onload="loaded()">
    <div id="parent">
        <div id="leftChild">
            <div>left child</div>
            <div class="row row1">some content</div>
            <div class="row row2">other content</div>
            <div class="row row3">more content</div>
        </div>
        <div id="rightChild">
            <div>right child</div>
            <div class="row row1">
                <span class="col1">column 1 content</span>
                <span class="col2">column 2 content</span>
                <span class="col3">column 3 content</span>
                <span class="col4">column 4 content</span>
                <span class="col5">column 5 content some really long content to trigger scrolling just for the purpose of this example</span>
            </div>
            <div class="row row2">
                <span class="col1">column 1 content</span>
                <span class="col2">column 2 content</span>
                <span class="col3">column 3 content</span>
                <span class="col4">column 4 content</span>
                <span class="col5">column 5 content some really long content to trigger scrolling just for the purpose of this example</span>
            </div>
            <div class="row row3">
                <span class="col1">column 1 content</span>
                <span class="col2">column 2 content</span>
                <span class="col3">column 3 content</span>
                <span class="col4">column 4 content</span>
                <span class="col5">column 5 content some really long content to trigger scrolling just for the purpose of this example</span>
            </div>
        </div>
    </div>
</body>

JS JS

function loaded() {
    /*var parent = document.getElementById('parent');
    parent.onmouseenter = function(event) {
        console.log(event.target);
    };
    parent.onmouseleave = function(event) {
        console.log(event.target);
    };*/

    var rows = document.getElementsByClassName('row');
    for (var i = 0; i < rows.length; i++) {
        rows[i].onmouseenter = function(event) {
            var splits = event.target.className.split(" ");
            var elems = document.getElementsByClassName(splits[splits.length - 1]);
            for (var j = 0; j < elems.length; j++) {
                elems[j].className += " hover";
            }
        };

        rows[i].onmouseleave = function(event) {
            var hovers = document.getElementsByClassName('hover');
            var len = hovers.length;
            for (var j = 0; j < len; j++) {
                hovers[0].className = hovers[0].className.replace(/\shover(\s|$)/, '');
            }
        };
    }
}

CSS 的CSS

.row:hover, .hover {
    background-color: lightblue;
}

.row {
    height: 50px;
    padding: 5px;
    white-space: nowrap;
}

.row > span {
    display: inline-block;
    border: 5px solid black;
}

#leftChild, #rightChild {
    float: left;
}

#rightChild {
    width: 300px;
    overflow: auto;
}

#rightChild .row {
    display: inline-block;
}

jsFiddle : Here jsFiddle这里

So I'd like to know a few things. 所以我想知道几件事。

  1. Is this possible with just straight CSS? 单纯的CSS是否有可能?
  2. If not, how can I make my approach more efficient? 如果没有,如何使我的方法更有效?
  3. Is it more efficient to have one event handler or multiple event handlers? 有一个事件处理程序或多个事件处理程序更有效吗?

I know I'm asking a lot here, but I hate asking multiple questions, especially if I'd have to repeat myself. 我知道我在这里要问很多问题,但是我讨厌问多个问题,特别是如果我不得不重复自己的话。 I'd appreciate any help. 我将不胜感激。 Thanks! 谢谢!

  1. via css with this structure: no, not before css level 4 is usable. 通过具有以下结构的css:不,不在css 4级可用之前。
  2. use this and check on className to append to it for while a new rule 使用this并检查className以在新规则后附加到它
  3. moouse hovering & mouse leaving ? 鼠标悬停和鼠标离开?

i get this: via jquery, but for the test I removed the class .row and kept the numbered one 我得到这个:通过jquery,但是为了测试,我删除了类.row并保留了编号

$("[class*='row']").hover(
  function () {
      $('head').append('<style class="'+this.className+'" rel="stylesheet" > .'+this.className+' {background-color:lightblue;} </style>'); 
$(this).mouseleave(function() {  $('style.'+this.className).remove();});
});

http://codepen.io/gcyrillus/pen/bhglr http://codepen.io/gcyrillus/pen/bhglr

Based on this jsPerf , the straight JavaScript approach that I have there is the fastest, the hybrid approach comes in a close second--and I mean really close to the native JS approach--and the (almost completely) jQuery approach comes in dead last--and it's really slow compared to the other two. 基于这个jsPerf ,我所拥有的直接JavaScript方法是最快的,混合方法紧随其后 -我的意思是真的很接近本机JS方法-并且(几乎完全是)jQuery方法已死了最后-与其他两个相比确实很慢。

All of these can be seen at this jsFiddle . 所有这些都可以在jsFiddle中看到。

JS JS

// Native JS approach... fastest (according to my jsPerf http://jsperf.com/removeclass-vs-native-js-remove-class/2)
function loaded() { 
    var rows = document.getElementsByClassName('row');
    for (var i = 0; i < rows.length; i++) {
        rows[i].onmouseenter = function(event) {
            var row = this.className.match(/row-[\d]+/);
            var elems = document.getElementsByClassName(row[0]);
            for (var j = 0; j < elems.length; j++) {
                elems[j].className += " hover";
            }
        };

        rows[i].onmouseleave = function(event) {
            var hovers = document.getElementsByClassName('hover');
            var len = hovers.length;
            for (var j = 0; j < len; j++) {
                hovers[0].className = hovers[0].className.replace(/\shover(\s|$)/, '');
            }
        };
    }
}

// jQuery approach (slowest)
/*$(document).ready(function() {
    $('.row').on('mouseenter', function(event) {
        var row = this.className.match(/row-[\d]+/);
        $('.' + row).addClass('hover');
    });

    $('.row').on('mouseleave', function(event) {
        $('.hover').removeClass('hover');
    });
});*/

// Hybrid approach (basically as fast as native JS approach)
/*$(document).ready(function() {
    var rows = document.getElementsByClassName('row');
  for (var i = 0; i < rows.length; i++) {
    rows[i].onmouseenter = function(event) {
      var row = this.className.match(/row-[\d]+/);
      $('.' + row[0]).addClass('hover');
    };

        rows[i].onmouseleave = function(event) {
            $('.hover').removeClass('hover');
        };
    }
});*/

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

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