4

Is it possible to highlight only the line that the mouse pointer is hovering on? Let's say I have this paragraph:

<p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Nam in nisi eleifend, efficitur ligula vel, scelerisque risus. 
    Interdum et malesuada fames ac ante ipsum primis in faucibus. 
    Nam semper diam sodales eros dictum euismod. Duis ut hendrerit leo. Sed iaculis sem ac est porttitor facilisis. 
    In convallis facilisis libero ut interdum. Phasellus scelerisque ex in lacus tempus mollis. Integer scelerisque viverra elit id fringilla. Proin nibh arcu, imperdiet a lacus ac, feugiat interdum sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse ultrices vestibulum orci, a varius quam cursus ut. Nulla ut suscipit sapien. Morbi et urna elementum, pretium augue non, tristique nulla. Nulla massa tellus, facilisis at fringilla et, rutrum ac libero.
</p>

Would it be possible to highlight the first line if I hover over it, second line if I hover over it and so on and so forth?

Illustration: enter image description here Source: http://www.crossboweducation.us/

I'm looking for a solution that would apply for multi-line paragraphs. One where I don't have to add span in every word manually.

EDIT (21.06.2016): - (solution to highlight entire paragraph)
Rory McCrossan's solution works basically but when I tried to implement it in my wordpress blog there was a problem with the highlighting, at first it works well, i scroll down a bit and the highlight position is calculated wrong. So, there's a neat solution I just found while working on this website, you need to load hover.css and add the class hvr-fade to each <p> tag... this of course doesn't take care of the original question but it's another approach to solving a similar problem very easily with a great css hover effect collection. Hope this helps someone...

odedta
  • 2,430
  • 4
  • 24
  • 51

1 Answers1

9

There's no direct way to get a single line of text within a larger element. To achieve what you require you could wrap each word of the p tag in its own span. Then on hover of the span tags you can highlight the siblings which are at the same offset().top. Something like this:

$('p').html(function() {
    return $(this).text().replace(/\w+[,.]?\s+?/g, "<span>$&</span>")
});

$('p').on('mouseenter', 'span', function() {
    var $span = $(this);
    $('p span').filter(function() {
        return $(this).offset().top == $span.offset().top;
    }).toggleClass('hover');
}).on('mouseleave', 'span', function() {
    $('p span').removeClass('hover');
})

Working example

Alternatively you could append a single div element to a parent of the p which follows the mouse movement when hovered over the p and acts as a line reading guide:

$('.text-block')
    .append('<div class="line-marker">&nbsp;</div>')
    .on('mousemove', function(e) {
        $(this).find('.line-marker').css('top', e.clientY);
    })
.line-marker {
    display: none;
}

.text-block:hover .line-marker {
    position: absolute;
    width: 100%;
    background-color: #CC0;
    display: block;
    z-index: -1;
}

Working example

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • I see, it seems like your solution is most elegant! I appreciate your help Rory, thanks! – odedta Mar 16 '16 at 13:43
  • I just checked the developers console on Google Chrome and I have a question: "When I hover the first lines all the `` tags get a class "hover" but when I hover any other line they don't... how why does it happen"? – odedta Mar 16 '16 at 13:45
  • That's odd, only the `span` tags which are on the same line as the current one being hovered should get that class. I just checked on the fiddle and it appears to be working. Which version of Chrome do you have? – Rory McCrossan Mar 16 '16 at 13:47
  • That's exactly what I was thinking, but this weird thing happened so I asked :) it works well by the way, it's just weird that the console is showing something else than what actually happens. I am using Version 49.0.2623.87 m (64-bit). – odedta Mar 16 '16 at 13:48
  • Nevermind that, forget what I said, my bad. – odedta Mar 16 '16 at 13:49
  • I added an alternative solution for you if it's of any help. – Rory McCrossan Mar 16 '16 at 13:52
  • Excellent building on my idea; upvoted and my own answer removed. – Bobby Jack Mar 16 '16 at 14:04
  • Need to add `body { overflow-x: hidden; }` though, cool. :) – odedta Mar 16 '16 at 14:05
  • Oh, this removes all styling from the paragraphs such as bold, underlines etc. – odedta Mar 16 '16 at 14:17
  • 1
    Unfortunately that's a caveat of the first method. You'd have to write something to recursively wrap direct and sub-level text nodes in spans too, which will get complicated very quickly. the second method will work with any text styling though. – Rory McCrossan Mar 16 '16 at 14:20
  • Alright, I've tried to implement the second solution in a Wordpress website and it seems like the `e.clientY` calculation is out of whack. Check this out: http://cpanel14.tempdomain.co.il/~schechter/when-should-selihot-be-recited/ - It seems that the highlight `top` changes if you scroll. I've tried a few things to get this fixed but couldn't find any solution. – odedta Mar 16 '16 at 15:14