【问题标题】:Highlight single line on mouse over鼠标悬停时突出显示单行
【发布时间】:2019-08-31 17:14:16
【问题描述】:

当鼠标悬停在多行段落中时(在该行中的任何单词上),我想更改多行段落中单行的背景颜色 -这可以使用 JQuery/JS 来实现吗?

如果有,怎么做?

编辑: 澄清一下,我希望鼠标悬停在任何一行上时都会突出显示它。
脚本必须动态隔离光标所在的行,并在鼠标悬停时对其应用临时样式。

编辑 2:
用于说明的图片 -

【问题讨论】:

标签: javascript jquery html css


【解决方案1】:

这是一场艰苦的战斗,但我想出了一种方法来做到这一点,完全不需要容器上的样式(包括它的字体、对齐方式等)。

这不是一个完美的解决方案,但希望它适用于您的目的。

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

    每一行都应该是一个标签,如果你愿意,你可以使用&lt;span&gt;,然后你可以使用css(比javascript或jQuery更好)

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

    【讨论】:

    • 不幸的是,这是不可能的。有数千条线,它们的宽度将来可能会发生变化。
    【解决方案3】:

    这完全取决于您的文本最初是如何格式化的。从您显示的屏幕截图中,在我看来,文本被包裹在一个强制换行的元素中。在这种情况下,整个文本中没有真正的“新行”。如果元素的大小发生变化,它会发生变化...例如,您现在正在阅读的文本被包含在站点的约束中...

    但如果我要
    插入我自己的行
    休息,然后
    以下方法
    可能有用。

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

    现在你要做的就是制定一些 css 规则来突出显示悬停事件中的 span 元素 -

    span:hover { background:#DDD }
    

    A live example

    【讨论】:

    • 如果您要在每一行添加&lt;br/&gt;,为什么不添加&lt;span&gt;?我不认为这就是 Acidic 想要的。
    • @oti - 我不关注你...我正在添加一个跨度。
    • 我不太确定性能...您可能需要自己测试一下...
    • 哦,实际上,您的编辑是正确的。我的示例中的换行符是由浏览器通过段落的宽度强制使用的;文本本身没有任何内容来指示新行的开始位置。
    • 我的意思是段落没有格式化。如果可以用换行符格式化,为什么不用&lt;span&gt;s 格式化呢?
    【解决方案4】:

    您可以通过创建一个放置在每行文本后面的块来模拟突出显示非格式化段落中的单行。该块将具有与您的p line-height 相同的大小,并且根据鼠标的 y 位置,top 的位置可以改变。这种方法不能被视为 native 亮点,但它比其他建议具有一些优势。首先,它可以适应任何文本。其次,即使在调整流体文本块的大小后,它也可以计算行数。第三,保持文本干净,避免任何额外的标记 (&lt;br/&gt;) 或其他 breaks

    HTML:

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

    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*/
    }
    

    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();
    });
    

    这是演示:http://jsfiddle.net/gh8gZ/1/

    我可以看到我的建议的唯一缺点是,当您有一个带有空行的文本块时,它们也会被突出显示,并且突出显示的区域占据了行的整个宽度 - 尽管这不会打扰我完全没有,但我必须指出这不是一个完美的解决方案。

    【讨论】:

      猜你喜欢
      • 2014-03-17
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      • 2019-12-26
      • 1970-01-01
      相关资源
      最近更新 更多