简体   繁体   English

鼠标悬停时突出显示单行

[英]Highlight single line on mouse over

I want to change the background color of a single line in a multi-line paragraph when the mouse is over that line ( over any word in that line ) - can this be achieved using JQuery/JS? 当鼠标悬停在该行( 在该行中的任何单词上 )时,我想更改多行段落中单行的背景颜色 - 这可以使用JQuery / JS实现吗?

If so, how? 如果是这样,怎么样?

Edit: To clarify, I want any line to be highlighted once the mouse is over it. 编辑:为了澄清,我希望一旦鼠标悬停在任何一行上就会突出显示。
The script will have to dynamically isolate the line that the cursor is over and apply a temporary style to it while the mouse is over it. 该脚本必须动态隔离光标所在的行,并在鼠标悬停时对其应用临时样式。

Edit 2: 编辑2:
A picture for illustration - 一张图片 -
在此输入图像描述

It was a hard fought battle, but I came up with a way to do this without any requirements for styles on the container at all (including its font, alignment, etc.). 这是一场艰苦的战斗,但我提出了一种方法来做到这一点,根本不需要容器上的样式(包括它的字体,对齐等)。

This is not a perfect solution, but hopefully it works for your purposes. 这不是一个完美的解决方案,但希望它适用于您的目的。

var
    //Keeps the content (individual spans) as they are built.
    $keeper = $("<div>"),
    //Used to measure span width for comparison to container.
    $measurer = $("<div>"),
    //The container of the text content
    $p = $("p"),
    //An individual line of the content
    $line = $("<span>").appendTo($measurer),

//make this "invisible," but allow for measurement against container width
//with no restriction on measurer's own width (fixed)
$measurer.css({'position': 'fixed', 'top': '100%'}).appendTo("body");

//Iterate through each "word" derived from splitting on any space.
$p.text().split(/\s/).forEach(function (elem) {
    //Start forming line text.  Don't forget word spacing
    $line.text($line.text() + elem + ' ');

    //Enough words to make the line width longer than the p width.
    //This indicates the end of "line."
    if ($line.width() > $p.width()) {
        //Remove the last word.
        $line.text(function (_, text) {
            return text.slice(0, text.lastIndexOf(elem));
        });

        //Keep the currently formed line to add back later
        $line.appendTo($keeper);

        //Create a new line for measuring
        $line = $("<span>");
        $line.text(' ' + elem).appendTo($measurer);
    }
});
//Append any leftover words not big enough to form a whole line
$keeper.append($measurer.html());
//Add back content
$p.html($keeper.html());
//cleanup
$keeper.remove();
$measurer.remove();

http://jsfiddle.net/6Cx3h/2/ http://jsfiddle.net/6Cx3h/2/

You can also do this on window resize in case the container's width is window-dependent. 如果容器的宽度取决于窗口,您也可以在窗口调整大小时执行此操作。

(you can see my attempt using height instead of width at http://jsfiddle.net/6Cx3h ) (你可以在http://jsfiddle.net/6Cx3h看到我尝试使用高度而不是宽度)

Each line shoud be a single tag, you could use <span> if you want, and then with css (better than javascript or jQuery) you could do 每一行都应该是一个标签,你可以使用<span> ,然后使用css (比javascript或jQuery更好)你可以做

span:hover{
  background-color: #ccc;
}

It all depends on how your text is formatted originally. 这一切都取决于您的文本最初的格式。 From the screen shot you show, it looks to me like the text is being wrapped in an element that is enforcing line wraps. 从您显示的屏幕截图中,它看起来像文本被包裹在强制换行的元素中。 In this case there is no real "new line" in the whole text. 在这种情况下,整个文本中没有真正的“新行”。 It's would change if the size of the element changed... As an example, the text you are reading now is being wrapped within the constrains of the site... 如果元素的大小发生变化,它会发生变化......例如,您正在阅读的文本正在包含在网站的约束内...

But if I were to 但是,如果我去
insert my own line 插入我自己的行
breaks, then the 休息,然后
following method 以下方法
might be of use. 可能有用。

// extract the text
var paragraph = $("#text").text();
// split the text into lines by searching for linebreaks
var lines = paragraph.split(/\r?\n/);
// clear the original text
$("#text").text('');
$.each(lines,function(index,elem){
  if (elem != ''){
    // for each line, wrap it with a span and bring back the linebreak
    $("#text").append('<span>'+elem+'</span><br/>');      
  }
});

Now all you would have to do is make some css rule to highlight the span elements on a hover event - 现在你所要做的就是制定一些css规则来突出悬停事件中的span元素 -

span:hover { background:#DDD }

A live example 一个现实的例子

You can simulate highlighting of a single line in a non-formatted paragraph by creating a block that will be placed behind each line of text. 您可以通过创建将放置在每行文本后面的块来模拟非格式化段落中单行的突出显示。 This block will have the same size as your p line-height and according to the mouse y-position the top position can change. 此块的大小与p line-height ,根据鼠标y位置, top位置可以更改。 This approach can not be consider as a native highlight but it has some advantages over the other suggestions. 这种方法不能被视为原生的亮点,但它比其他建议有一些优势。 First, it can be accommodated to any text. 首先,它可以适应任何文本。 Second, it can calculate the number of lines even after resizing a fluid text block. 其次,即使在调整流体文本块的大小后,它也可以计算行数。 Third, you keep your text clean from any extra markup ( <br/> ) or other breaks . 第三,保持文本清晰,不受任何额外标记( <br/> )或其他breaks

The HTML: HTML:

<p>Some long non-formatted - fluid text</p>

The CSS: CSS:

p {
    position:relative;
    text-align:justify;
    font: 14px/18px Arial; /*Line-height is essential to be defined because not all browsers translate the default value in px - e.g. Chrome returns "normal" and FF returns pixels*/
}
p span {  /*The highlighter*/
    background:yellow; /*Highlight color*/
    display:none; /*Hide it until we have a hover*/
    position:absolute;
    left:0;
    z-index:-1; /*Place it behind the text*/
}

The jQuery: jQuery:

//get the line-height
var theLineheight = $('p').css('line-height'); 
//strip it from the 'px'
var Lineheight = parseInt(theLineheight); 
//get the text height
var thePheight = $('p').height(); 
//update the height after resize
window.onresize = function () {
    return thePheight = $('p').height(); 
}
//create the highlight box
$('p').append('<span style="height:' + theLineheight + ';width:100%"></span>'); 
//detect mouse movement in the text container
$('p').mousemove(function (e) {
    //show the highlighter
    $('p span').show();
    //get the mouse position
    mouseTop = e.pageY - this.offsetTop;
    //round it to a line-height scale
    topPos = Math.ceil(mouseTop / Lineheight) * Lineheight - Lineheight;
    //position the highlighter vertical
    $('p span').css('top', topPos + 'px');
    //hide the highlighter when mouse is at the end of the text - including the space that highlighter takes
    if (topPos > (thePheight - Lineheight)) {
        $('p span').hide();
    }
//hide the highlighter when mouse is not over the text
}).mouseout(function (e) {
    $('p span').hide();
});

Here's the demo: http://jsfiddle.net/gh8gZ/1/ 这是演示: http//jsfiddle.net/gh8gZ/1/

The only disadvantages I can see to my suggestion is that when you have a text block with empty lines they will be highlighted as well and also, the highlighted area takes the whole width of the line - although this doesn't bother me at all but I have to indicate that this is not a perfect solution. 我可以看到我的建议的唯一缺点是,当你有一个空行的文本块时,它们也会被突出显示,并且突出显示的区域占据整行的宽度 - 虽然这不会打扰我我必须表明这不是一个完美的解决方案。

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

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