You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery hover行号整行高亮时如何获取同级文本节点设置样式

问题背景

当前HTML结构由XSLT生成,无法直接修改初始DOM,结构如下:

<div class="testoorig">
  <h3>Testo originale</h3>
  <div id="pag_10"></div>
  <br><span class="lineNumb"><b>1</b></span>
  <orig>d</orig> sometext sometext
  <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>;
  <mentioned><u>punirai</u></mentioned>,
  <mentioned><u>punir</u></mentioned>

  <!-- Next line (totally 31) -->

  <br><span class="lineNumb"><b>2</b></span> .....

</div>
<!-- #testoorig -->

现有jQuery代码实现hover行号高亮逻辑:

jQuery.fn.getParent = function (num) {
  var last = this[0];
  for (var i = 0; i < num; i++) {
    last = last.parentNode;
  }
  return jQuery(last);
};
$(document).on("mouseover", ".lineNumb", function(g){
  target = $(this);
  target.css("background", "antiquewhite");
  arr = target.getParent(0).nextUntil(".lineNumb");

  for(i=0;i<arr.length;i++) {
    $(arr[i]).css("background", "antiquewhite");
  }
});
现存问题

jQuery的nextUntil()方法仅能获取同级的元素节点,会自动忽略未被标签包裹的裸文本节点,导致只有标签包裹的内容能应用高亮样式,裸文本(如示例中的sometext sometext)无法被选中高亮,需要实现整行全内容(含裸文本)的hover高亮效果,允许通过JS动态包裹元素的方案实现。

解决方案

核心原因

jQuery默认的节点遍历方法只会筛选nodeType=1的元素节点,文本节点(nodeType=3)、注释节点会被直接跳过,因此无法直接通过jQuery方法拿到裸文本。
最优方案是页面初始化时做一次DOM预处理,遍历原生DOM节点拿到每行包含的所有内容(含文本节点),统一包裹在行内容容器中,后续hover逻辑直接操作容器即可,性能更高逻辑更简单。
完整实现代码如下:

$(function() {
  // 预处理:遍历所有行号,将每行所有内容包裹进容器
  $('.lineNumb').each(function() {
    const currentLineNode = this;
    const lineContentNodes = [];
    let pointer = currentLineNode.nextSibling;

    // 从行号后第一个节点开始遍历,直到遇到下一个行号/换行br为止
    while (pointer) {
      if (pointer.nodeType === 1) {
        const $pointer = $(pointer);
        if ($pointer.hasClass('lineNumb') || pointer.tagName === 'BR') break;
      }
      lineContentNodes.push(pointer);
      pointer = pointer.nextSibling;
    }

    // 把收集到的所有节点(含文本、元素)包裹在统一容器内
    if (lineContentNodes.length) {
      $(lineContentNodes).wrapAll('<span class="line-content"></span>');
    }
  });

  // 绑定hover事件,补充鼠标移出清除样式的逻辑
  $(document)
    .on('mouseenter', '.lineNumb', function() {
      $(this).add($(this).next('.line-content')).css('background', 'antiquewhite');
    })
    .on('mouseleave', '.lineNumb', function() {
      $(this).add($(this).next('.line-content')).css('background', '');
    });
});

代码说明

  • 用原生DOM属性nextSibling做遍历,不会跳过文本节点,能完整收集当前行的所有内容
  • DOM预处理仅在页面加载时执行一次,后续hover不需要重复遍历节点,性能更好
  • 补充了mouseleave事件逻辑,解决鼠标移开后高亮残留的问题
  • 完全不需要修改原有XSLT生成的初始DOM结构,适配现有场景
  • 原有自定义的getParent方法如果没有其他业务用途可以直接删除,新逻辑不需要依赖该方法

内容的提问来源于stack exchange,提问作者JustAnotherSimpleProgrammer__

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:54:22