在一个范围中包装段落的每一行

时间:2014-08-06 21:54:31

标签: javascript jquery html

我想在这里创建样式http://codepen.io/timprint/pen/dumjF。我99%肯定只用CSS是不可能的,但如果我能弄清楚如何用另一个元素包裹跨度的每一行(另一个跨度?它并不重要)我应该能够相当容易地做到这一点。这是一个响应式网站,因此我无法控制线路端。

我有带内联跨度的段落。

<p>Hong Kong Phooey, number one super guy. Hong Kong Phooey, quicker than the
human eye <span class="highlight">He's got style, a groovy style, and a car
that just won't stop. When the going gets tough, he's really rough, with a
Hong Kong Phooey chop. Hong Kong Phooey, number one super guy.</span> Hong Kong
Phooey, quicker than the human eye. Hong Kong Phooey, he's fan-riffic!</p>`

我想在第二个范围内包装.highlight的每一行,并给第一个和最后一个一个类.first&amp; 。持续。如果窗口宽度发生变化,它需要重新计算并重新应用跨度。

页面上可能有几个,所以我需要一些方法来重复使用它。

Obtain a line of a paragraph in HTML是我能找到的最接近的,但我很难为此修改它。

1 个答案:

答案 0 :(得分:6)

在链接问题中,一种方法是将元素的每个单词拆分为自己的单个元素,评估$(el).offset().top,如果它与之前的兄弟相同,则添加当前单词的内容,以前的兄弟姐妹。

以下工作,但不是明确地为第一行和最后一行添加特定类,而是简单地使用CSS&#39; :first-child:last-child选择器。也就是说,jQuery(一个简单的插件,有点笨重,可以很好地优化):

(function ($) {
    $.fn.lines = function (opts) {
        var s = $.extend({
            'lineClass' : 'line'
        },opts);
        return this.each(function () {
            var self = this,
                $self = $(self),
                $line,
                $prev;
            $self.find('.' + s.lineClass).contents().unwrap();
            $self.html(function (i, h) {
                return h.replace(/(\b[\w']+\b)/g, '<span class="' + s.lineClass + '">$1</span>');
            });

            $self.find('.line + .line').each(function(i, el){
                $line = $(this),
                $prev = $line.prev('.line');
                if ($line.offset().top === $prev.offset().top) {
                    $prev.append(el.previousSibling, $line.contents());
                    $line.remove();
                }
            });
        });
    };
})(jQuery);

$(window).on('resize', function(){
    $('p .highlight').lines();
});
$(document).ready(function(){
    $('p .highlight').lines();
});

JS Fiddle demo

请注意,这是一种简单的方法,并且因为它重写了.highlight元素的html,所以这些元素上的事件处理程序将被删除/销毁/删除;因此,如果.line元素必须具有互动性,则您需要使用on()来提供事件委派:

$('.highlight').on('click', '.line:first-child', function(e){
    console.log(this, e.target);
    // <span class=​"line" style=​"color:​ blue;​">​…​</span>​ <span class=​"line" style=​"color:​ blue;​">​…​</span>
    $(this).css('color','blue');
});

JS Fiddle demo

参考文献: