【问题标题】:Obtain a line of a paragraph in HTML获取 HTML 中段落的一行
【发布时间】:2013-04-12 10:12:47
【问题描述】:

在 JavaScript 中,是否可以从页面上显示的段落中获取特定行?

例如,这里我试图将段落的第 3 行作为字符串获取:

JavaScript:

//this function should return the specified line from the specified paragraph.
function getLine(paragraphId, lineNum){
    //for example, getLine("sampleParagraph", 1); should return
    // tore but year. An from mean on with when sing pain. Oh to as principles devonshire
}

HTML:

<p id = "sampleParagraph">
Instrument cultivated alteration any favourable expression law far nor. Both new like tore but year. An from mean on with when sing pain. Oh to as principles devonshire companions unsatiable an delightful. The ourselves suffering the sincerity. Inhabit her manners adapted age certain. Debating offended at branched striking be subjects.
</p>

在 jsfiddle 上(显示段落的显示方式):http://jsfiddle.net/RrXWW/

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    演示 1: http://jsfiddle.net/LeTW6/2/
    演示 2: http://jsfiddle.net/LeTW6/3/

    为了简单起见,我在这里使用 jQuery,但这适用于纯 JavaScript。事实上,我在某些部分使用直接 DOM 访问来提高性能。

    1. 将所有单词分成单独的元素。
    2. 使用位置计算行号。
    3. 在选定的行,开始构建所有单词元素的缓冲区。
    4. 大于所选行,退出。
    5. 在调整大小时,重新计算(这可能不需要,或者可能从不同的事件中调用)。

    代码

    (function () {
    
        // wrap all words
        $(".count").each(function () {
            var obj = $(this);
            var html = obj.html().replace(/(\S+\s*)/g, "<span>$1</span>");
            obj.html(html);
        });
    
        var offset = 0; // keeps track of distance from top
        var spans = $(".count span"); // collection of elements
    
        function getLine(index) {
            var top = 0,
                buffer = [];
    
            for (var i = 0; i < spans.length; i++) {
    
                if (top > index) {
                    break; // quit once the line is done to improve performance
                }
    
                // position calculation
                var newOffset = spans[i].offsetTop;
                if (newOffset !== offset) {
                    offset = newOffset;
                    top++;
                }
    
                // store the elements in the line we want
                if (top === index) {
                    buffer.push(spans[i]);
                }
            }
    
            // buffer now contains all spans in the X line position
    
            // this block is just for output purposes
            var text = "";
            for (var i = 0; i < buffer.length; i++) {
                text += buffer[i].innerHTML;
            }
    
            $("#output").html(text);
        }
    
        var line = 3; // the line to select/highlight
        getLine(line); // initial highlighting
    
        // other recalculation triggers can be added here, such as a button click
    
        // throttling to handle recalculation upon resize
        var timeout;
        function throttle() {
            window.clearTimeout(timeout);
            timeout = window.setTimeout(function () {
                getLine(line);
            }, 100);
        }
    
        $(window).on("resize", throttle);
    })();
    

    另请参阅可变宽度容器中的my answer for highlighting alternate lines

    【讨论】:

      【解决方案2】:

      如果你想使用纯 JavaScript 来提高性能并且不必包含 jQuery,你可以使用这个。

      演示:http://jsfiddle.net/PX7cj/2/

      function getLine(paragraphId, lineNum) {
          lineNum--;
          var elem = document.getElementById(paragraphId);
          var spanChildren = elem.getElementsByTagName("span");
          var paragraphText = elem.innerHTML.replace(/(\r\n|\n|\r)/gm, "");
          var newParagraphText = "";
          var words = [];
          if (spanChildren.length === 0) {
              words = paragraphText.split(" ");
              for (var i = 0; max = words.length, i < max; i++)
              newParagraphText += '<span>' + words[i] + "</span> ";
              elem.innerHTML = newParagraphText;
          }else{
              for(var i=0; max = spanChildren.length, i<max; i++){
                  words[words.length] = spanChildren[i].innerHTML;
              }
          }
          var lineCounter = 0;
          var previousY = spanChildren[0].offsetTop;
          var returnText = "";
          var startReturning = false;
          for (var i = 0; max = words.length, i < max; i++) {
              if (spanChildren[i].offsetTop != previousY) lineCounter++;
              if (lineCounter === lineNum) startReturning = true;
              if (lineCounter !== lineNum && startReturning) return returnText.substring(0, returnText.length - 1);
              if (startReturning) {
                  returnText += words[i] + " ";
                  if (i + 1 === words.length) return returnText.substring(0, returnText.length - 1);
              }
              previousY = spanChildren[i].offsetTop;
          }
      }
      
      alert(getLine("sampleParagraph", 5));
      alert(getLine("sampleParagraph", 4));
      

      【讨论】:

      • +1 用于纯 JS 解决方案。我稍微更新了您的演示以添加更多文本;它在我的宽屏显示器上警告“未定义”。
      • 谢谢。是的,如果您要求的行号不存在,它将返回 undefined。
      猜你喜欢
      • 2014-08-20
      • 2020-08-30
      • 1970-01-01
      • 2015-08-29
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多