如何针对交替的奇偶文本行进行定位

7
假设我有一个包含大约10-15行文本的

元素或

元素,现在我的客户有个奇怪的要求,需要奇数/偶数行具有不同的文本颜色。例如第1行是黑色,那么第2行应该是灰色,第3行再次是黑色,以此类推...
因此,我决定使用元素并更改颜色,但变量分辨率会导致问题,我知道:first-line选择器(在这种情况下无用),还有像:odd和:even这样的选择器将被排除在外,因为我没有使用表格,所以是否有任何方法可以使用CSS实现这一点,还是需要使用jQuery?
简而言之:我想针对段落或div中的奇偶行进行目标设置。
我需要一个CSS解决方案,如果没有,欢迎使用jQuery和JavaScript。

1
它是“TL;DR”的缩写,意思是“太长了,没看”。不是“TLTR”或“太长了,读不完” :) - BoltClock
无论如何,你不能使用CSS样式化第n行。你需要使用JavaScript。 - BoltClock
@BoltClock 只是一个打字错误 :p - Mr. Alien
这是无法通过CSS实现的,你需要使用jQuery。我认为你正在寻找的答案在这里。另一个有用的答案在这里 - Bill
3个回答

12

Demo 1

http://jsfiddle.net/Fptq2/2/
适用于所有现代浏览器。

主要步骤:

  1. 将源代码分成单个单词
  2. 使用一个 span 将每个单词包装起来(虽然不美观但有效——任何样式都可以应用到 span 上)
  3. 使用简单的位置计算来确定元素是否低于之前的位置
  4. 根据索引更改颜色
  5. 在调整大小时执行#3-5(这应该被限制!)
$(".stripe").each(function(){
  var obj = $(this);
  var html = obj.html().replace(/(\S+\s*)/g, "<span>$1</span>");
  obj.html(html);
});

function highlight(){
    var offset = 0;
    var colorIndex = 0;
    var colors = ["#eee","#000"];
    var spans = $(".stripe span");

    // note the direct DOM usage here (no jQuery) for performance
    for(var i = 0; i < spans.length; i++){
        var newOffset = spans[i].offsetTop;  

        if(newOffset !== offset){
            colorIndex = colorIndex === 0 ? 1 : 0;
            offset = newOffset;
       }

       spans[i].style.color = colors[colorIndex];
    }
}

highlight();
$(window).on("resize", highlight);

演示2

Fiddle: http://jsfiddle.net/Fptq2/4/

  • 使用较长的文本块
  • 显示应用于多个元素的效果
  • 缓存“所有跨度”选择器
  • 添加调整大小节流
(function () {
    $(".stripe").each(function () {
        var obj = $(this);
        var html = obj.html().replace(/(\S+\s*)/g, "<span>$1</span>");
        obj.html(html);
    });

    var offset = 0;
    var colorIndex = 0;
    var colors = ["#ccc", "#000"];
    var spans = $(".stripe span");

    function highlight() {
        for (var i = 0; i < spans.length; i++) {

            var newOffset = spans[i].offsetTop;
            if (newOffset !== offset) {
                colorIndex = colorIndex === 0 ? 1 : 0;
                offset = newOffset;
            }

            spans[i].style.color = colors[colorIndex];
        }
    }

    highlight(); // initial highlighting

    var timeout;
    function throttle(){
        window.clearTimeout(timeout);
        timeout = window.setTimeout(highlight, 100);
    }

    $(window).on("resize", throttle);
})();

输出

在此输入图片描述


1
真棒 +1 和一个绿色的饼干,即使是 VisioN 也值得拥有 :) 谢谢你们两个。 - Mr. Alien

4
这里有一个可能的解决方案。它生成一些位于文本后面的div元素。div元素继承父容器的字体大小,因此标记不应受到损坏。
HTML:
<div id="test">Lorem ipsum ...</div>

JavaScript:

var div = document.getElementById("test"),
    layer = document.createElement("div"),
    text = div.innerHTML,
    lineHeight;

layer.appendChild(document.createTextNode("\u00A0"));
div.insertBefore(layer, div.firstChild);

lineHeight = layer.offsetHeight;
div.style.position = "relative";
div.style.overflow = "hidden";
div.style.color = "transparent";
layer.style.position = "absolute";
layer.style.zIndex = "-1";

window.addEventListener("resize", (function highlight() {
    while (layer.firstChild)
        layer.removeChild(layer.firstChild);

    for (var i = 0, n = Math.ceil(div.offsetHeight / lineHeight); i < n; i++) {
        var line = document.createElement("div"),
            block = document.createElement("div");

        line.style.height = lineHeight + "px";
        line.style.color = i % 2 ? "#ccc" : "#aaa";
        line.style.overflow = "hidden";

        block.innerHTML = text;
        block.style.marginTop = -i * lineHeight + "px";

        line.appendChild(block);
        layer.appendChild(line);
    }
    return highlight;
})(), false);

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


我也有同样的想法,但是OP想要文本颜色而不是背景 :/ - Bill
太棒了,但是它无法检测到换行符,不过很不错 +1。有没有想法改变文本的颜色或者针对一个元素而不是伪造背景? - Mr. Alien
@VisioN 如果你这样做,那么你即将成为一颗星 :p - Mr. Alien
1
@Mr.Alien 哎呀!检查一下更新的解决方案。现在它完全符合预期。我尝试优化代码,使其快速而简短。与以前一样,它不需要任何第三方库。 - VisioN
@VisioN 干杯 :) 顺便说一下,如果你愿意的话我可以再找到更多的bug,现在无法选择文本,呵呵,但这真的是一个不错的尝试。 - Mr. Alien
1
@Mr.Alien 你用哪个浏览器?我在Chrome和FF中都能完美选择它。我已经为内部绝对块指定了z-index,你现在可以尝试一下。 - VisioN

1
这个问题已经晚了,但如果这个答案能帮助其他想将包装文本段落分成单独行的人,我会非常高兴。
将包装文本转换为行(用于行编号或将每行拆分为单独元素)是一个经常出现在论坛上的问题,我最终有了这样的需要,所以这里就有了MooTools和jQuery两个版本(jQuery版本未经过测试,如果有任何问题,请留言)。这个特定的版本将每个包装行都分成一个新的不同元素,但可以很容易地修改为只计算行数。
使用以下代码可以实现此操作 $("#someElement").linify()
这里是下面链接的概念证明 jquery-mootools

这是一个快速演示包装文本行转换为单独div项的小窗口。 http://jsfiddle.net/UANeP/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接