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. position を使用して行番号を計算します。
  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 に答える