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

时间:2013-06-19 01:27:32

标签: javascript css mouseenter onmouseout mousehover

我正在创建一个可以有n rows的网格,并分为两个视图:leftChild和rightChild。 leftChild与rightChild具有相同的行数,但leftChild保持在其位置。与rightChild的唯一区别是它可以水平滚动。当我将鼠标悬停在leftChild或rightChild元素上时,我想添加某种悬停效果......这很容易,但我想要做的是在整个行中添加悬停效果。因此,如果我将鼠标悬停在leftChild的第3行,我想突出显示rightChild中的第3行。

现在,理想情况下,我喜欢一个完整的CSS解决方案,类似于this,但这是不可能的,因为我的行不会直接跟在彼此之后。我试图想出另一种方法来解决这个问题,但直接CSS似乎不可能。

输入JavaScript。我认为下一步是将JavaScript与CSS结合起来。我可以向行添加悬停效果,然后使用JavaScript将悬停类添加到另一个子对应的行中。使用jQuery非常简单,但我正在寻找原生的JavaScript方法。

我想到的主要方法是在每个行类元素上添加mouseentermouseleave。我真的不喜欢这种方法,因为我在每个行元素上设置了2个事件监听器......这似乎有点低效。无论如何,当你输入时,你获取你所盘旋的行号,然后将悬停类添加到所有这些行号元素。当您离开时,您只需找到悬停的所有元素,并相应地删除。相应的代码如下:

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

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

.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

所以我想知道一些事情。

  1. 只用简单的CSS就可以了吗?
  2. 如果没有,我如何才能提高效率?
  3. 拥有一个事件处理程序或多个事件处理程序是否更有效?
  4. 我知道我在这里问了很多,但我讨厌提出多个问题,特别是如果我不得不重复一遍。我很感激任何帮助。谢谢!

2 个答案:

答案 0 :(得分:0)

  1. 通过具有此结构的css:no,而不是在css level 4可用之前。
  2. 使用this并检查className是否附加新规则
  3. moouse hovering&amp;老鼠离开?
  4. 我得到了这个:通过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

答案 1 :(得分:0)

基于this jsPerf,我所拥有的直接JavaScript方法是最快的,混合方法紧随其后 - 我的意思是非常接近本机JS方法 - 而且(几乎完全)jQuery方法最后是死的 - 与其他两个相比,它真的很慢。

所有这些都可以在this jsFiddle看到。

<强> 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');
        };
    }
});*/