如何突出显示最接近鼠标的文本行?

时间:2010-03-16 17:00:55

标签: javascript html text line highlight

我有一个很长的文字,我想为用户提供阅读帮助:当前行应该突出显示。为了使它更容易,我将只使用鼠标的Y坐标(这样,鼠标指针不会妨碍)。我有一个标识为content的大型DIV,它填充了整个宽度,还有一个小型DIV,其中包含content类的{{1}}字段。

我正在使用jQuery 1.4。如何突出显示最接近当前鼠标位置的文本行?

3 个答案:

答案 0 :(得分:17)

不确定jQuery是否会在这里为您提供帮助,但您可以查看MSDNMDC上记录的element.getClientRects方法。更具体地说,MSDN上的this example有点类似于您想要实现的内容,使用巧妙的z索引div元素突出显示行,该元素位于由{{1返回的坐标的文本后面的文本后面}}

你应该能够通过循环文档getClientRects()中返回的TextRectangle对象并检查鼠标光标的y值是否为>来实现相同的功能。顶部和<每个矩形的底部,将巧妙的z-indexed div移动到相同的位置/高度。

所有当前主流浏览器都支持onmousemove


http://jsbin.com/avuku/15

更新 - 在Chrome,IE6 / 7/8,Firefox,Opera,Safari中工作。我在其他浏览器中遇到的初始问题与getClientRects()需要DIV有关 再次更新 - 我不得不在一些较新的问题上参考这个答案,所以我花时间更新它以重新调整窗口调整大小的行。看起来其他人也一直在玩,现在是修订版15.

答案 1 :(得分:5)

如果没有明确包装的文本(即换行符或<br>元素),我不知道如何做到这一点。

据我所知,DOM无法发现特定文本片段的位置,字符方式像素方式 ​​- 包括我所知道的{{ 3}} - 更不用说文本可以假设的动态本质,例如浏览器的文本缩放功能。

但如果你能以某种方式设法生成/注入明确的行结尾,那么我认为我有一个解决方案。

修改

感谢Pekka答案中的精彩信息,我拼凑了一个功能原型,但它有一个重要的警告 - 仅适用于纯文本内容。任何HTML存在元素的主体都将被剥离。

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript"> google.load("jquery", "1.4.1"); </script>
<script type="text/javascript">

  jQuery.fn.wrapLines = function( openTag, closeTag )
  {
    var dummy = this.clone().css({
            top: -9999,
            left: -9999,
            position: 'absolute',
            width: this.width()
        }).appendTo(this.parent())
      , text = dummy.text().match(/\S+\s+/g);

    var words = text.length
      , lastTopOffset = 0
      , lines = []
      , lineText = ''
    ;

    for ( var i = 0; i < words; ++i )
    {
      dummy.html(
          text.slice(0,i).join('') +
          text[i].replace(/(\S)/, '$1<span/>') +
          text.slice(i+1).join('')
      );

      var topOffset = jQuery( 'span', dummy ).offset().top;

      if ( topOffset !== lastTopOffset && i != 0 )
      {
        lines.push( lineText );
        lineText = text[i];
      } else {
        lineText += text[i];
      }

      lastTopOffset = topOffset;
    }
    lines.push( lineText );

    this.html( openTag + lines.join( closeTag + openTag ) + closeTag );
  };

  $(function()
  {
    $('p').wrapLines( '<span class="line">', '</span>' );
  });

</script>

<style type="text/css">
span.line:hover {
  background-color: lightblue;
}
</style>

<p style="width: 400px;">
 one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three
</p>

答案 2 :(得分:3)

想到的最佳方法是将每一行拆分为<span><div>元素,其中:hover CSS类具有“突出显示”设置集:

span.line:hover { background-color: lightblue; }

这将是最便宜的解决方案,因为浏览器将负责所有突出显示本身。如果您想要花哨的效果,您仍然可以通过向每一行添加mouseovermouseout事件来实现这一目标。

当然,困难的部分是在浏览器的换行符中将内容分成几行。您需要动态地执行此操作,以便行实际反映浏览器中断文本的位置。

也许接受这个问题的答案是迈向正确方向的一步:

Getting a specific line using jQuery

  

工作原理:

     

它遍历每个单词中插入元素的整个元素(实际上是元素的克隆)。跨度的顶部偏移量被缓存 - 当此偏移量发生变化时,我们可以假设我们处于新线上。