4

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

4

2 回答 2

9

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

另请参阅我的答案,以突出显示可变宽度容器中的交替行。

于 2013-04-11T23:49:08.930 回答
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));
于 2013-04-12T01:28:29.367 回答