【问题标题】:to apply sequential line numbering to lines in a paragraph: is it possible?将连续行编号应用于段落中的行:可能吗?
【发布时间】:2013-10-23 20:15:19
【问题描述】:

是否可以让 jquery/javascript 在段落中所有行的开头插入连续的行号,更好的是,按照顺序一直到后续段落?

我希望能够快速向学生推荐文章的特定行(在课堂环境中)。我有很多文章想要应用此功能,每篇文章都有不同数量的段落。

我希望这可能是可能的,即使在响应式页面中,段落的宽度会根据显示设备而变化,并且随后每个段落中的行数会变得更多或更少。

提前感谢任何可以提供帮助的人。

【问题讨论】:

  • 作为参考,你不希望行号不响应段落的宽度变化吗?
  • 是的,有可能——你有什么尝试过的吗?
  • 是的,这当然是可能的。但是,我看不出响应式页面上的行号有何意义,其中行号因设备而异,因此您无法引用它们。
  • 显然,改变内容的宽度将是一个大问题,通过行号引用此内容非常无用,因为每个不同环境的行号都会不同。在我看来,最好按段落引用它们,或者通过包装<span id="ref1">sometext</span> 将特定部分作为目标,这样你就可以说“转到参考 1”以及他们要做的所有事情是点击指向#ref1的参考链接一
  • Bergi,给段落编号是不够的。它必须是段落中的行。我正在撰写的许多文章都包含 4 或 5 个外语的长段落......所以单独引用这些行很重要。

标签: javascript jquery


【解决方案1】:

这是一种可能适合您目的的方法。

  1. 获取单行段落的高度,供参考。
  2. 对于每个段落,获取实际高度,并推断行数。
  3. 遍历行并在绝对位置添加编号。

var refHeight = $("p").eq(0).height();
$("p").eq(0).remove();
var cnt = 1;
$("p").each(function(index) {
    var pos = $(this).position();
    var h = $(this).height();
    var lines = h / refHeight;
    var lineHeight = h / lines;
    for (var i=pos.top ; i<pos.top+h ; i += lineHeight) {
        var num = $("<p>", { class: "number" });
        num.text(cnt++);
        num.css("top", i);
        $(this).before(num);
        console.log(i);
    }
});

(Fiddle)


编辑

如果您想使用固定的行长(以便每个人看到相同的数字),您可以将上述内容与以下内容结合起来:

  1. 将段落分成几行。
  2. 将每一行包装在一个 span/div 中,然后重新附加。
  3. Block the browser from text wrapping.

$("p").each(function() {
    var text = $(this).text();
    $(this).html("");
    var i=0;
    while (i<text.length) {
        lineCharWidth = charWidth;
        while (i+lineCharWidth < text.length && text[i+lineCharWidth] != ' ') {
            lineCharWidth++;
        }
        var line = $("<span>", { class: "line" }).text(text.substr(i, lineCharWidth));
        $(this).append(line).append("<br/>");
        i += lineCharWidth;
    }
});

(Fiddle)

【讨论】:

    【解决方案2】:

    Here's a solution 使用函数根据预定的行长将段落文本拆分为空格字符,然后将文本替换为由 &lt;li&gt; 元素组成的 &lt;ol&gt;,每个元素包含一行文本:

    var lineNum = 1;
    
    function splitLines(text, lineLen) {
        var words = text.split(/\s/g), line = '', lines = [];
        $.each(words, function(idx) {
            line += this + ' ';
            if (line.length > lineLen || idx == words.length - 1) {
                lines.push(line);
                line = '';
                lineNum += 1;
            }
        });
        return lines;
    }
    
    $('p').each(function() {
        var $p = $(this), $ol = $('<ol start="' + lineNum + '">'), lineLen = 50;
    
        $.each(splitLines($p.text(), lineLen), function(idx) {
            $ol.append('<li>' + this + '</li>');
        });
    
        $p.text('').append($ol);
    });
    

    我不确定是否支持&lt;ol&gt;start 属性。它确实在 Chrome 中工作。尽管如此,我还是喜欢使用列表元素,因为我认为它在语义上更有意义。

    【讨论】:

    • 非常好。现在必须弄清楚如何将列表项中数字的颜色设置为与文本不同的颜色..
    • 我将把它作为练习留给读者。可以这么说,谷歌搜索“有序列表的 css”会带来几个线索。 :)
    • 啊,是的,我以前总是在计数器周围使用跨度(在 php 中生成)来进行不同颜色的编号。但是 css :before 伪类对此非常有用。感谢您的帮助,FishBasketGordo。
    【解决方案3】:

    当然。只需确保您正在编码您的换行符,并使用它通过简单的替换来分割文本。

    示例文本:

    The quick
    brown fox
    jumped over
    the lazy dog
    

    为此,实际的字符串如下:

    The quick\r\nbrown fox\r\njumped over\r\nthe lazy dog
    

    我认为这样的事情会起作用(没有 document.write,并且可能会提高性能):

    var input = '\r\nThe quick\r\nbrown fox\r\njumped over\r\nthe lazy dog';
    input = input.replace(/\r\n/g, '<div class=\'index\'></div>');
    document.write(input);
    var idx = 0;
    $('.index').each(function(){
        $(this).text(idx++);
    });
    

    如果我没记错的话,这应该在每一行写出一个索引号。不过可以使用一些测试/调试:)

    有关如何完成此操作的示例,请查看 Github 的差异页面。

    【讨论】:

    • 谢谢......但是......你说“确保你正在编码你的线路返回”,这就是我不确定它会如何工作的地方。我正在使用 php/mysql 将内容放入数据库。当我拉回内容时,我如何才能让这些行返回,而不是在工作流程的某个点手动插入返回?
    • 行返回必须作为数据的一部分存在。您可以通过确定每行的长度来更早地执行此操作。这可能不是一个完美的解决方案,这只是我想到的第一件事。
    猜你喜欢
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 2020-08-30
    • 2021-09-08
    • 2018-05-07
    • 2021-11-28
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多