2

我有一个 div 元素,其中有一个包含一些文本的跨度。当鼠标悬停在每个元素上时,我需要向元素添加一个大纲类。

当我从一个 div 开始然后移动到跨度时,它似乎有效,但反之则不然。如果我在一个跨度上 - 它是轮廓的,但是如果我将鼠标从它移到 div 上,跨度上的轮廓会按预期消失,但 div 上的轮廓不会出现。

这是我所拥有的:

CSS

.outline {
    outline: 5px solid #66ff66;
}

JS

function divColor() {
    $('.myDiv').hover(
        function() {
            $('.outline').removeClass('outline');
            $(this).attr('title', 'Change background').addClass('outline');             
        },
        function () {
            $(this).attr('title', '').removeClass('outline');
        }
    );
}

function textColor() {
    $('.myText').hover(
        function() {
            $('.outline').removeClass('outline');
            $(this).attr('title', 'Change color').addClass('outline');              
        },
        function() {
            $(this).attr('title', '').removeClass('outline');
        }
    );
}

$('.myDiv, .myText').mousemove(function(){
    divColor();
    textColor();            
});

HTML

<div class="myDiv">
    <span class="myText">some text</span>    
</div>
4

1 回答 1

2

你的 CSS 块中有一些 JS,我认为你不需要跟踪 mousemove,你可以绑定到悬停功能。即使用这个JavaScript:

$('.myText').hover(
    function() {
        $(this).mouseIn = true;           
    },
    function() {
        $(this).attr('title', '').removeClass('outline');
        $('.myDiv').addClass('outline');
    }
);

$('.myDiv').hover(
    function() {
        $(this).attr('title', 'Change background').addClass('outline');             
    },
    function () {
        $(this).attr('title', '').removeClass('outline');
    }
);

小提琴

mousemove 的问题在于它附加到这些元素上,因此当您在这些元素之外时它不会被调用(这是删除类所必需的)。要么您必须跟踪容器 div 上的所有鼠标移动,这太过分了,要么执行以下操作:

function mouseIn() {
    $(this).data('mouseIn', true);
}

function mouseOut() {
    $(this).data('mouseIn', false);
    $(this).removeClass('outline'); 
}

$('.myDiv').hover(mouseIn, mouseOut);
$('.myText').hover(mouseIn, mouseOut);

$('.myDiv, .myText').mousemove(function(){
    if ($('.myDiv').data('mouseIn')) {
        // Mouse is in the div
        if ($('.myText').data('mouseIn')) {
            // Mouse is in the span
            $('.myDiv').removeClass('outline');
            $('.myText').addClass('outline');
        } else {
            // In the div but not the span
            $('.myDiv').addClass('outline');
            $('.myText').removeClass('outline');            
        }
    } 
    // No else as the span is contained in the div, otherwise the 
    // else clause would mean mouse is in the span. Since this is 
    // only called when it's inside one or other (or both) 
});

小提琴

编辑

在您的评论中,您寻找一种更通用的方式,如果我们创建一个“可提升”类来定义我们可以概述/提升的事物,那么我们可以尝试做一些聪明的事情来关闭父母的班级。但是,这依赖于以正确顺序发生的悬停事件。代码如下所示:

function mouseIn() {
    $(this).parent().removeClass('outline'); 
    $(this).addClass('outline'); 
}

function mouseOut() {
    $(this).removeClass('outline');     
}

$('.raiseable').hover(mouseIn, mouseOut);

小提琴

然而,正如你所看到的,悬停事件并不总是以正确的顺序发生,所以我们不能依赖它。

我们可以使用这个逻辑,以及之前添加一些东西来指示鼠标位置的逻辑。我们将添加另一个类来指示鼠标的位置,而不是添加数据元素,因为以后使用它更容易。然后我们可以遍历每个raiseable类,看看它是否有孩子,hasMouse如果有,那么它不会被勾勒出来,循环最终会勾勒出最后一个有鼠标但没有孩子有鼠标的元素。

代码如下所示:

function mouseIn() {
    $(this).data('mouseIn', true);
    $(this).addClass('hasMouse');
}

function mouseOut() {
    $(this).removeClass('hasMouse');
    $(this).data('mouseIn', false);
    // Still need to remove the outline class as 
    // mousemove may not be triggered outside the elements
    $(this).removeClass('outline');
}

$('.raiseable').hover(mouseIn, mouseOut);

$('.container').mousemove(function(){

    var best = null;
    $('.raiseable').each( function() { 

        // Count the number of children with the class 
        // 'hasMouse'. 
        if (($(this).children('.hasMouse').length == 0) && 
            ($(this).data('mouseIn'))) { 
            best = $(this);
        } else {
            $(this).removeClass('outline');
        }
    });
    if (best) {
        $(best).addClass('outline');
    }                         
});

新的 HTML:

<div class='container'>
    <div class="raiseable">
        <span class="raiseable">some text</span>   
        <span class="raiseable padded">
            <span class="raiseable">some other text</span>    
        </span>
    </div>
</div>

新的 CSS:

.outline {
    outline: 5px solid #66ff66;
}

.padded {
    padding: 20px;
    margin: 20px;
}

最终小提琴

很有可能有一种更优雅的方式来做到这一点,或者我已经错过了一些已经内置的东西。但这似乎可行,我相信你可以从那里调整它来做你想做的任何事情。

于 2013-09-04T02:42:19.227 回答