在HTML中获取段落的一行

时间:2013-04-11 23:30:46

标签: javascript html

在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/

2 个答案:

答案 0 :(得分:9)

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

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

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

    (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

答案 1 :(得分:1)

如果您想使用纯JavaScript来提高性能,并且不必包含jQuery,则可以使用它。

DEMO: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));