【问题标题】:How to target alternate odd/even text lines如何定位交替的奇/偶文本行
【发布时间】:2013-03-27 15:54:58
【问题描述】:

假设我有一个 p 元素或 div 元素,其中包含大约 10-15 行的文本,现在我的客户对此有一个奇怪的调用,他需要具有不同文本颜色的奇数/偶数行。假设第 1 行 - 黑色,所以第 2 行应该是灰色,第 3 行应该再次是黑色等等......

所以我决定使用跨度并更改颜色,但可变分辨率在这里杀死了东西,我知道 :first-line 选择器(在这种情况下不会有用),还有像 :odd:even 这样的选择器由于我不使用表格,这里将被排除在外,那么有什么方法可以使用 CSS 实现这一点,还是需要使用 jQuery?

TL; DR:我想定位段落或 div 中的奇数/偶数行

我需要一个 CSS 解决方案,如果没有,欢迎使用 jQuery 和 JavaScript

【问题讨论】:

  • 它是“TL;DR”表示“太长;没有读”,而不是“TLTR”/“太长读不完”:)
  • 无论如何,你不能用 CSS 设置第 n 行的样式。你需要 JavaScript。
  • @BoltClock 只是一个错字:p
  • 没有办法做到这一点是css;你将不得不使用jQuery。我认为您正在寻找的答案是here 另一个有用的答案here

标签: javascript jquery css


【解决方案1】:

演示1

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

基本上是这样的:

  1. 一次将源拆分为单个单词
  2. 将每个单词包装在一个 span 中(丑陋但有效 -any 样式现在可以应用于 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

小提琴: 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 和一个绿色 Cookie,即使是 VisioN 也应该得到这个 :) 谢谢你们俩
【解决方案2】:

现在回答这个问题为时已晚.. 但是如果这个答案对其他想要将包装的文本段落分成单独的行的人有所帮助,那么我很高兴
将换行的文本转换为行(用于行编号或将每行分成单独的元素)是一个经常出现在板上的问题,我最终需要这样做,所以这里是(对于 MooTools和 jQuery – jQuery 版本未经测试,因此如果有任何问题,请发表评论)。这个特殊的化身将每个包裹的行分成一个不同的新元素,但可以修改为只计算行数。
使用代码你可以实现这一点 $("#someElement").linify()
以下 URL 是此
jquery-mootools

的概念证明 这是一个快速小提琴,它演示了单个 div 项的包装文本行。
http://jsfiddle.net/UANeP/

【讨论】:

    【解决方案3】:

    这是一种可能的解决方案。它会生成许多放在文本后面的&lt;div&gt; 元素。 &lt;div&gt; 元素从父容器继承字体大小,因此不应损坏标记。

    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 想要文本颜色,而不是背景:/
    • 太棒了,这无法检测到换行符,但很好的尝试 +1,任何想法改变文本的颜色或定位元素而不是欺骗背景?
    • @VisioN 如果你这样做了,那么你将成为明星:p
    • @Mr.Alien Yeeeeah!检查更新的解决方案。现在它完全符合预期。我试图将代码优化得又快又短。和以前一样,它不需要任何第三方库。
    • @Mr.Alien 您使用哪种浏览器?我能够在 Chrome 和 FF 中完美地选择它。我已经为内部绝对块指定了z-index,你现在可以试试。
    猜你喜欢
    • 2021-11-04
    • 2019-03-08
    • 2021-08-10
    • 1970-01-01
    • 2021-11-17
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多