javascript - Highlight single line on mouse over - Stack Overflow

I want to change the background color of a single line in a multi-line paragraph when the mouse is 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?

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:
A picture for illustration -

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?

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:
A picture for illustration -

Share Improve this question edited Aug 31, 2019 at 9:14 Glorfindel 22.7k13 gold badges90 silver badges119 bronze badges asked Mar 1, 2013 at 0:11 AcidicAcidic 6,29013 gold badges51 silver badges80 bronze badges 3
  • Please define a line. – Vlad Commented Mar 1, 2013 at 0:21
  • @Vlad a line as it is rendered by the browser and seen by the user. – Acidic Commented Mar 1, 2013 at 0:22
  • See if this helps: stackoverflow./questions/1966441/… – Vlad Commented Mar 1, 2013 at 0:27
Add a ment  | 

4 Answers 4

Reset to default 3

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 parison 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/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/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: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 -

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. This approach can not be consider as a native highlight but it has some advantages over the other suggestions. First, it can be acmodated 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.

The HTML:

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

The 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:

//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/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.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745305662a4621694.html

相关推荐

  • javascript - Highlight single line on mouse over - Stack Overflow

    I want to change the background color of a single line in a multi-line paragraph when the mouse is over

    7小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信