DOM Manipulation with jQuery

DOM Manipulation with jQuery

本文关键字:jQuery with Manipulation DOM      更新时间:2023-09-26

这应该很简单,但我似乎错过了一些东西。我正在做一个小项目,其中我正在编写的代码旨在在整个文档中做一些事情。以下是我要应用脚本操作的 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. 用类计算 div 元素内的所有 p 元素"进入"。
  2. 在整个文档中,如果每个分类的div "条目"中有两个以上的 p 元素,我想保持前两个不变,并将其余元素移动到带有类"slider"的新 div 元素中。这个新元素将放在"点击查看更多"按钮之后。
  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",我希望这发生在那些属于类"entry"的元素上,这些元素删除了一些额外的段落。从开头有两个段落的div class="entry" 元素应该在按钮的类中看到任何修改。

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

这一行:

$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 声明变量,否则它们将成为全局变量。

我最初的建议是使用 :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/

查看$.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/

问候
尼廷·