1

这应该相当简单,但我似乎遗漏了一些东西。我正在做一个小项目,我正在编写的代码旨在在整个文档中做一些事情。这是我想将脚本的操作应用到的 HTML 代码:

<div class="entry">
    <p>First paragraph</p>
    <p>Second paragraph</p>
    <p>Third paragraph</p>
    <p>One more...</p>

    <div class="bttn"><a href="#">Click for More</a></div>
</div>

此模板(即,在具有类“entry”的包装div中包含几个p元素和一个具有类“bttn”的div)在整个文档中重复多次。用户将内容添加到段落中并最终将其发布到站点。这是我希望在我的 .js 文件中执行的操作:

  1. 使用类“entry”计算div元素内的所有p元素。
  2. 在整个文档中,如果每个div中有两个以上的p元素被归类为“entry”,我希望前两个保持不变,并将其余的移动到一个新的div元素,类为“slider”。这个新元素将被放置在“点击更多”按钮之后。
  3. 将类“show”添加到已存在的类“bttn”的div元素中,但仅限于属于包含两个以上段落的类“entry”并使用类“slider”移动到新div的那些元素。新按钮看起来像这样:div class="bttn slider"(加上锚标记和模板中显示的所有其他内容)。

所以基本上,如果发布内容的用户在 HTML 模板中添加了两个以上的段落,当文档准备好时,我希望脚本获取其他段落,将它们移动到新的div元素,并将新类添加到按钮。最后,当单击“单击更多”按钮时,随后删除和插入的额外段落将很好地淡入(因为一旦我重新插入它们,我会将它们隐藏在按钮下)。这是我到目前为止所做的:

$('.entry').each(function () {
    $counter = $('.entry p').length;

    if ($counter > 2) {
        $removeExtra = $(this).find('p').not(':eq(1)').not(':eq(0)').detach();

        $(this).find('.bttn').after(function () {
            return '<div class="slider">' + $removeExtra.html() + '</div>';
        }).addClass('show');
    }
});

问题:

  • 我们都知道html()方法只会返回第一组匹配的元素,所以在单击按钮时,我只会得到从每个类“条目”中删除的第一段,并且我需要取回所有分离的段落,我存储在变量 $removeExtra 中。
  • 每个具有“bttn”类的div元素都获得了新的“show”类,我希望这发生在那些属于“条目”类的那些看到一些额外段落被删除的人身上。从开头有两个段落的 div class="entry" 元素在按钮的类中应该没有修改。

非常感谢您对此的任何帮助。提前致谢!

4

3 回答 3

3

我最初的建议是使用:gt

$(".entry").each(function(){
    var ps = $("p:gt(1)", this);
    if ( ps.length ) {
        $(".bttn", this).addClass("show").after(function(){
            return $("<div>").addClass("slider").append(ps);    
        });
    }        
});​​​​​​​​​​​​​​​​​​​​​​​

如果我在任何程度上混淆了细节,我深表歉意 - 这个问题有点冗长。

小提琴:http: //jsfiddle.net/FfmaB/1/

于 2012-05-28T05:07:22.940 回答
3

这一行:

$counter = $('.entry p').length;

当您想要仅在当前“.entry” div 中的段落时,正在查找任何“.entry” div 中的所有段落。此外,您不需要使用回调函数语法,因为您使用它一次只在一个元素之后添加。.after()

试试这个:

$('.entry').each(function () {
    var $this = $(this),
        $p = $this.find('p');

    if ($p.length > 2) {
        $('<div class="slider"/>').appendTo(this).append($p.slice(2));
        $this.find('.bttn').addClass('show');
    }
});

我已经使用了该.append()方法,而不是.after()因为.append()会在您要附加到的元素的最后一个子元素之后自动添加它们。在将它们附加到新 div 之前,您不需要分离段落,因为它们.append()移动它们(至少,当只有一个目标元素时它会移动它们 - 就像这里的情况一样)。

我用过.slice()而不是你的.not(':eq(1)').not(':eq(0)').

请注意,您应该声明变量,var否则它们将成为全局变量。

于 2012-05-28T05:08:13.150 回答
1

查看$.html()函数文档: http:
//api.jquery.com/html/

如果选择器表达式匹配多个元素,则只有第一个匹配项才会返回其 HTML 内容。


我相信这就是你想要的:

$(document).ready(Process);

function Process() {
    $('.entry').each(function() {
        var $this = $(this);
        $counter = $this.find('p').length;

        if ($counter > 2) {
            var $Extras = $this.find('p').not(':eq(1)').not(':eq(0)');

            $($Extras.get().reverse()).each(function() {
                var extra = $(this).html();
                $this.find('.bttn').after('<div class="slider">' + extra + '</div>');
                $this.find('p').not(':eq(1)').not(':eq(0)').detach();
            })
            $this.find(".bttn").addClass('show');
        }
    });
}​

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

问候,
尼廷 J。

于 2012-05-28T05:34:40.080 回答