如何将特定元素包装成一行?

时间:2014-02-11 16:24:07

标签: javascript jquery html

我正在构建一个WordPress插件来生成短代码。

最终用户可以选择生成推荐书。这将返回例如以下短代码,它将作为滑块(你可能知道我的意思):

[testimonial]Content 1[/testimonial]
[testimonial]Content 2[/testimonial]
[testimonial]Content 3[/testimonial]

上面的短代码将输出以下HTML:

<li class="shortcode-testimonial">Content 1</li>
<li class="shortcode-testimonial">Content 2</li>
<li class="shortcode-testimonial">Content 3</li>

现在,我可以做一个WrapAll来实现我想要的。但我还想让用户添加第二个滑块,同时还有3个推荐。我将这些与以下短代码分开:

[spacer height="50"]

以上将输出:

<div style="height:50px;" class="shortcode-spacer"></div>

现在我添加了另一个短代码来显示推荐书:

[testimonial]Content 4[/testimonial]
[testimonial]Content 5[/testimonial]
[testimonial]Content 6[/testimonial]

HTML中的最终输出是:

<li class="shortcode-testimonial">Content 1</li>
<li class="shortcode-testimonial">Content 2</li>
<li class="shortcode-testimonial">Content 3</li>

<div style="height:50px;" class="shortcode-spacer"></div>

<li class="shortcode-testimonial">Content 4</li>
<li class="shortcode-testimonial">Content 5</li>
<li class="shortcode-testimonial">Content 6</li>

WrapAll的问题在于,即使中间有间隔符,它仍然会将两个推荐组包装在一个元素中。

所以我在jQuery中编写了以下函数来实现我想要的东西:

//Handling Testimonials Shortcodes 
function testimonial_shortcodes(){    
    var $html = '';
    var $counter = 0;
    $('.shortcode-testimonial').each(function(){              
        var $this = $(this);
        var $prev = $this.prev();
        var $next = $this.next();
        if((!$prev.hasClass('shortcode-testimonial')) && ($counter==0)){
            $counter++;
            $html += '<div class="shortcode-testimonials"><ul>';
            $html += $this[0].outerHTML;
            if(!$this.next().hasClass('shortcode-testimonial')){
                $html += '</ul></div>';
                $this.replaceWith($html);
                $html = '';
                $counter = 0;
            }else{
                $this.remove();
            }
        }else{
            if(!$next.hasClass('shortcode-testimonial')){
                $html += $this[0].outerHTML;
                $html += '</ul></div>';
                $this.replaceWith($html);
                $html = '';
                $counter = 0;
            }else{
                $html += $this[0].outerHTML;
                $this.remove();
            }
        } 
    });
}

此功能将为我生成以下内容:

<div class="shortcode-testimonials">
  <ul>
    <li class="shortcode-testimonial">Content 1</li>
    <li class="shortcode-testimonial">Content 2</li>
    <li class="shortcode-testimonial">Content 3</li>
  </ul>
</div>

<div style="height:50px;" class="shortcode-spacer"></div>

<div class="shortcode-testimonials">
  <ul>
    <li class="shortcode-testimonial">Content 4</li>
    <li class="shortcode-testimonial">Content 5</li>
    <li class="shortcode-testimonial">Content 6</li>
  </ul>
</div>

处理[推荐]短代码的WordPress函数是:

public static function testimonial_func($atts, $content=null){
    return '<li class="shortcode-testimonial">'.do_shortcode($content).'</li>';
}

我仍然认为有更好的方法可以做到这一点,因为我可能会更频繁地执行此功能,也可能需要某种包装来实现幻灯片效果的其他短代码或其他东西。

1 个答案:

答案 0 :(得分:1)

这应该做你想要的,简短的:

var set = $(".shortcode-testimonial:first").nextUntil(":not(.shortcode-testimonial)");
while (set.length > 0) {
    set = set.addBack().wrapAll("<ul>").parent().nextAll(".shortcode-testimonial").first().nextUntil(":not(.shortcode-testimonial)");
}

http://jsfiddle.net/qG67d/4/

获取第一组,然后循环,直到没有更多的设置。

如果推荐书嵌套在不同的容器中,则会出现问题。

这是一个处理嵌套的版本:

$(".shortcode-testimonial").parent().each(function () {
    var set = $(this).children(".shortcode-testimonial").first().nextUntil(":not(.shortcode-testimonial)");
    while (set.length > 0) {
        set = set.addBack().wrapAll("<ul>").parent().nextAll(".shortcode-testimonial").first().nextUntil(":not(.shortcode-testimonial)");
    }
})

http://jsfiddle.net/qG67d/6/