【问题标题】:Can a set of classes be stored in memory, so I can do things to them before I display them on a page? (JQuery)可以将一组类存储在内存中,以便在将它们显示在页面上之前对它们进行处理吗? (jQuery)
【发布时间】:2012-04-23 18:05:27
【问题描述】:

我正在实现这个:http://jsfiddle.net/xkfqN/85/

html:

<div id="posts">
    <div class="more">Show More</div>
    <div class="commentsContainer">
        <div class="comment">Comment 1</div>
        <div class="comment">Comment 2</div>
        <div class="comment">Comment 3</div>
        <div class="comment">Comment 4</div>
        <div class="comment">Comment 5</div>
        <div class="comment">Comment 6</div>
        <div class="comment">Comment 7</div>
        <div class="comment">Comment 8</div>
        <div class="comment">Comment 9</div>
        <div class="comment">Comment 10</div>
    </div>
</div>

css:

.comment { 
    display: none;
    border:3px solid whiteSmoke;
    width:280px;
}

.more {
    cursor:pointer

}​

JQuery:

function toggleComment(index, hide) {
    //check the index to make sure it is in range
    if (index > -1 && $('.comment').length > index) {
        //get the comment at the given index and apply the animation
        $('.comment:eq(' + index + ')')
            .slideToggle(18, function() { 
                //if hiding then decrement
                var next = hide ? index + 1 : index - 1;
                //call toggle on the next index
                toggleComment(next , hide);
            });
            //set to display block so they show up on their own line
           // .css('display', 'block'); 
    }
}

$('.more').click(function() {

    //are the comments already open... returns true or false
    var hide = $(this).hasClass('open');

    //default to start at the begining... each click brings the index to 0
    var index = 0;
    //if the comments are not open then start at the end
    if (!hide) {
        index = $('.comment').length - 1
    }

    //toggle the comments
    toggleComment(index, hide);    

    //used to remember state.. adds class to more and takes it away hence toggle class
    $(this).toggleClass('open');
});
​

默认情况下,我打算下拉的 cmets 不显示,并且像示例链接所示的那样用 css 隐藏,因为默认情况下为每个用户加载所有 cmets 是不明智的。

它们只会在点击“显示全部”链接/提交时加载。无论如何,在下面的代码中,我的 cmets 在页面上呈现后是从文件“show_all_cmets”中获取的。在该文件中有一个循环,它遍历每个评论并显示数据及其 html。

我想做的事:

我不想在页面上呈现它,但是在内存中如何能够访问这些类,就好像我试图从实际页面访问它们一样。这样我就可以访问每个 cmets 类并与 JSFiddle 代码一起使用。

如果这对您有意义,这可能吗?如果是这样,我将如何实现这一目标?

JQuery:

 var postContent = $(this).parents('.post_content'),
    commentContainer = postContent.find('.comment_container');

    commentContainer.slice(0, -2).remove();
    postContent.find('.comment_container:first')
    .before("<%= j render 'users/partials/show_all_comments', :comments => @comments %>");

【问题讨论】:

  • 坦率地说,我不明白你想要做什么,或者你想要从中获得什么。你不能隐藏元素吗? jQuery 可以像任何其他元素一样访问它们,但用户无法看到它们或与它们交互。
  • 完成。我过去总是发布代码,但后来我让某些用户总是请求 JSFiddle 链接。以后我会同时发布。
  • @LondonGuy:很好。问题中的代码是必要的。 JSFiddle 链接(或我的偏好,jsbin.com)是一个不错的选择,但非常nice 很不错。 :-)
  • Juhana:想象一个用户有一个 4000 cmets 的微博。每次用户进入带有该微博的页面时,都会从数据库中加载所有 4000 个 cmets,然后将其隐藏。即使用户没有点击显示全部链接。那不是我想做的事。想象一下有 1000 名用户查看该微博。这意味着 4000 cmets 被加载然后隐藏 1000 次,无论用户是否点击全部显示。
  • @LondonGuy:既然如此,我可能不会加载我根本不会显示的 cmets。当用户单击“更多”链接时,触发 ajax 请求以检索附加的 cmets。只是将它们从 HTML 移动到 JavaScript 并不会产生太大的影响。

标签: javascript jquery jquery-selectors


【解决方案1】:

听起来您想要断开 DOM 元素并通过它们进行搜索。你可以很容易地做到这一点:

var elements = $('<div><div class="one">one</div><div class="two">two</div></div>');
var divOne = elements.find('.one');

在那里,我创建了一个具有单个顶级 div 的结构,其中包含所有其他结构,并在其周围包装了一个 jQuery 实例。元素不在 DOM 中,它们与它完全断开。然后我可以使用像find这样的jQuery方法来提取我想要的位。

如果您想将提取的位实际放在页面上的某个位置,您可能想clone它:

// Put "one" on the page
elements.find(".one").clone().appendTo(document.body);

但是看看你对 Juhana 的评论:

Juhana:假设用户有一个包含 4000 cmets 的微博。每次用户进入带有该微博的页面时,都会从数据库中加载所有 4000 个 cmets,然后将其隐藏。即使用户没有点击显示全部链接。那不是我想做的事。想象一下有 1000 名用户查看该微博。这意味着 4000 cmets 被加载,然后被隐藏 1000 次,无论用户是否点击全部显示。

...我根本不会加载额外的 cmets (不在 HTML 中,也不在脚本中)。相反,我只会加载我要显示的 cmets,然后在用户单击它时让“更多”链接触发其余的 ajax 请求。仅仅将它们从 HTML 移动到脚本中并不会获得太多(如果有的话)。

这是一个例子 - live example | source:

HTML:

<div id="commentsContainer">
  <div class="comment">Comment 1</div>
  <div class="comment">Comment 2</div>
  <div class="comment">Comment 3</div>
  <div class="comment">Comment 4</div>
  <div class="comment">Comment 5</div>
  <div class="comment">Comment 6</div>
  <div class="comment">Comment 7</div>
  <div class="comment">Comment 8</div>
  <div class="comment">Comment 9</div>
  <div class="comment">Comment 10</div>
  <div><a href="fallback.php" id="moreComments">more</a></div>
</div>

JavaScript:

jQuery(function($) {

  $("#moreComments").click(function(event) {
    var $this = $(this),
        moreDiv,
        container;

    event.preventDefault();
    moreDiv = $this.parent();
    container = moreDiv.parent();
    $this.replaceWith("<em>Loading...</em>");
    $.ajax({
      method: 'get',
      url:    'http://jsbin.com/ijarov',
      dataType: 'html',
      success: function(data) {
        moreDiv.remove();
        container.append(data);
      }
    });
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});

ajax 调用返回的内容:

<div class="comment">Comment 11</div>
<div class="comment">Comment 12</div>
<div class="comment">Comment 13</div>
<div class="comment">Comment 14</div>
<div class="comment">Comment 15</div>
<div class="comment">Comment 16</div>
<div class="comment">Comment 17</div>
<div class="comment">Comment 18</div>
<div class="comment">Comment 19</div>
<div class="comment">Comment 20</div>

在下方回复您的评论:

假设您不想附加“数据”,但要访问该文件中的类。这可能吗?

我不知道您所说的 “...访问类...” 是什么意思,但是如果您的意思是与返回的元素进行交互而不附加它们,则只需实例化它们,就像我在这个答案的顶部使用文字字符串所做的那样。例如,在 ajax 成功处理程序中执行此操作:

var elements = $(data);

这是上面带有不同返回数据的示例(混合了div 元素,一些具有comment 类和一些具有other 类),我在添加数据之前查看数据,然后只附加 cmets,而不是“其他”:Live example | source

HTML:

<div id="commentsContainer">
  <div class="comment">Comment 1</div>
  <div class="comment">Comment 2</div>
  <div class="comment">Comment 3</div>
  <div class="comment">Comment 4</div>
  <div class="comment">Comment 5</div>
  <div class="comment">Comment 6</div>
  <div class="comment">Comment 7</div>
  <div class="comment">Comment 8</div>
  <div class="comment">Comment 9</div>
  <div class="comment">Comment 10</div>
  <div><a href="fallback.php" id="moreComments">more</a></div>
</div>
<hr>

JavaScript (仅在success 函数中进行更改)

jQuery(function($) {

  $("#moreComments").click(function(event) {
    var $this = $(this),
        moreDiv,
        container;

    event.preventDefault();
    moreDiv = $this.parent();
    container = moreDiv.parent();
    $this.replaceWith("<em>Loading...</em>");
    $.ajax({
      method: 'get',
      url:    'http://jsbin.com/ijarov/2',
      dataType: 'html',
      success: function(data) {
        var elements = $(data);
        moreDiv.remove();
        display("Number of <code>.comment</code> elements: "+
                elements.filter('.comment').length);
        display("Number of <code>.other</code> elements: "+
                elements.filter('.other').length);
        display("Appending only the <code>.comment</code> ones.");
        elements.filter('.comment').appendTo(container);
      }
    });
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});

ajax 调用返回的数据:

<div class="comment">Comment 11</div>
<div class="other">Other 11</div>
<div class="comment">Comment 12</div>
<div class="other">Other 12</div>
<div class="comment">Comment 13</div>
<div class="comment">Comment 14</div>
<div class="comment">Comment 15</div>
<div class="comment">Comment 16</div>
<div class="comment">Comment 17</div>
<div class="comment">Comment 18</div>
<div class="comment">Comment 19</div>
<div class="comment">Comment 20</div>

【讨论】:

  • 我会试一试并报告。谢谢
  • @LondonGuy:我已经更新了答案,提出了另一种方法的建议。
  • 假设您不想附加“数据”但访问该文件中的类。这可能吗?
  • 存储 jQuery 元素也是一种很好的性能实践。详情请见here
  • @ADC:这对我来说似乎完全离题了。
猜你喜欢
  • 2018-09-16
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 2021-04-06
  • 2010-11-24
相关资源
最近更新 更多