【问题标题】:Question about selecting form children jquery关于选择表单子jquery的问题
【发布时间】:2010-02-20 14:10:10
【问题描述】:

我再次询问有关评论表单的问题,我正在制作一个图片网站,每张图片都有自己的评论表单,所以当我提交表单时,我会这样做:

$('#comment_form').live('submit', function() {
 ...

所以为了只选择这个表单 textearea 值,我尝试使用它,但我得到未定义的错误,这是我尝试的方法:

$('#comment_form').live('submit', function() {
 image_comment_text=$(this).closest("#comment_text").val(); //textarea id is comment_text

我尝试使用 find(),它可以正常工作,但是当我为几张图片提交 cmets 时,我应该得到 2 或 3 次 cmets,因为 find 会找到所有出现带有 comment_text id 的 textarea .. 我该怎么做?

@molf,这里是 javascript 生成的 HTML:

var xHTML = "<div class=\"addComment\">";
   xHTML += "<form action=\"<?=base_url()?>images/post_comment/" + post + "\" method=\"post\" class=\"comment_form\" name=\"comment_form\">";
   xHTML += "<input type=\"hidden\" class=\"comment_post_id\" name=\"comment_post_id\" value=\"" +post + "\"/>"; 
   xHTML += "<textarea class=\"comment\" name=\"comment_text\" rows=\"8\" cols=\"40\"></textarea>";
      xHTML += "<input type=\"submit\" name=\"submit\" class=\"post_image_comment\" value=\"Comment\"><span> Don't make it too big!</span>";
   xHTML += "</form></div>";

编辑

当我打印到控制台记录 textarea 的值时,我只得到一个结果,现在当我尝试附加 ul cmets 时,我得到 2 个相同的值..这里是怎么回事..

<ul class="comments"></ul> 

下面是根本不在文档中的评论表单,当单击某个锚点时,表单会在.comments下方弹出,当表单提交时,我想附加 cmets 以添加新评论以列出现有项目无序列表 cmets ,这是整个代码:

$('form[name^="comment_form"]').live('submit', function(event) {
  r= $(this).find('> .comment').val();

                $('<div class="overlay"></div>')
    .appendTo('.addComment')
             .fadeIn(200, function() {
          $('.comments')
             .append('<li id="new_append">' + r + '</li>')
              .children(':last')
           .height($('.comments li:last').height())
           .hide()
           .slideDown(800, function() { 
             var bodyHeight = $('html').height();
            $('.addComment').fadeOut(500, function() {
              $('html').height(bodyHeight);
           $('h2#leaveAComment').fadeOut(200, function(){$(this).text('Thank you for your comment!').fadeIn(200)});
          });
         });  
        $('html, body').scrollTo( $('#new_append'), 800 );
        });
    event.preventDefault();
            }); 

编辑二@patrick

加载评论表单的javascript在上面..这里是HTML:

-------------每个都开始--------------

<div id="image-12" class="image_content">
<img src="..." />
 <ul class="comments hidden"> //This is where the comments are appended to <li></li>

 </ul>

<div style="float: left; display: block; width: 100%;">
<a id="image_comment-12" class="image_comment" onclick="showComments('12');" href="javascript:;">Add Comment</a>
</div>

  <div id="addComment-12">//this is where the comment form loads

  </div>

</div>

---------END--- FOR EACH--------- 图片 ...

【问题讨论】:

  • closest 找到一个元素的最近的parent。 IE。它会从您的表单中搜索到 html 元素,而不是在您的表单中。
  • @vava 我如何在其中进行搜索,但只能应用于具有特定类的一个元素
  • @c0mrade,molf 给了你正确的答案,在你的查询中使用:first(或:last)修饰符。
  • @vava 再次获得多个选定值
  • 没问题@c0mrade。我认为您当前的解决方案并不难/棘手,但因为@patrick 和我只能看到您的一半代码,因此帮助调试它是一项艰苦的工作。如果您能够托管您目前拥有的东西,以便我们可以看到它的实际效果,我们很可能会为您解决它。

标签: javascript jquery


【解决方案1】:

首先,更改表单的选择器。我认为您可以使用 id 选择器按名称选择表单,但您不应该在页面上复制 id,因此 jQuery live 可能只观看第一个表单。不过,这只是一个猜测。

此外,您为 textarea 使用的类/ID 并不重要。如果每个表单只有一个文本区域,则可以使用:text 选择器。在寻找孩子时,我喜欢使用孩子选择器。

$('form[name="comment_form"]').live('submit', function() {
  image_comment_text = $(this).find('> :text').val();
});

如果您使用 name 而不是 id 因为您将拥有多个表单,我建议将 name 更改为 comment_form_'image_id',那么您的选择器将是:$('form[name^="comment_form"]')
请注意^,它要求名称以“comment_form”开头。这样,您可以拥有唯一的表单名称(comment_form_234、comment_form_235),并且仍然具有所需的效果。

编辑:

我查看了您的代码更新,在我看来您忽略了函数中当前表单的上下文。例如,当您使用选择器 $('.comments').append(... 时,您将附加到页面上与该选择器匹配的所有元素。为了检索正确的元素,您必须始终将选择器用作$(this).find(' &gt; .comments').append(...,这将在提交的表单的上下文中工作。

我花了几分钟来编辑你的代码,我没有运行它或任何东西,但它应该接近你想要做的。我希望它至少能让你朝着正确的方向开始:

$('form[name^="comment_form"]').live('submit', function (event) {
    r = $(this).find('> .comment').val();
    /* get addComment-classed element */
    var addComment = $(this).find(' > .addComment:first');

    /* get comments-classed element */
    var comments = $(this).find(' > .comments:first');

    $('<div class="overlay"></div>').appendTo(addComment).fadeIn(200, function () {
        /* note comments element, not selector */
        $(comments).append('<li id="new_append">' + r + '</li>').children(':last').height(
        /* again, element */
        $(comments).find(' > li:last').height()).hide().slideDown(800, function () {
            var bodyHeight = $('html').height();

            /* again, element */
            $(addComment).fadeOut(500, function () {
                $('html').height(bodyHeight);
                $('h2#leaveAComment').fadeOut(200, function () {
                    $(this).text('Thank you for your comment!').fadeIn(200)
                });
            });
        });
        $('html, body').scrollTo($('#new_append'), 800);
    });
    event.preventDefault();
});

我在代码中添加了 cmets,但请注意 addComments 和 cmets 选择器是“缓存的”。如果您要多次访问这些元素,在使用它们之前将它们存储在一个变量中将减少 DOM 遍历。这应该真正解决您的 cmets 添加到页面上的多个元素的问题。

【讨论】:

  • @Jim Schubert 感谢 jim 的回答.. 当我使用您的选择器时,我的控制台日志未定义.. 我如何喜欢您使用 for name 的方法
  • @Jim Schubert r= $(this).find('> :text').val();这是未定义的,当我将其更改为 r= $(this).find('> .comment').val();它的工作,但再次出现问题仍然得到双值,我编辑了我的问题顺便说一句
  • @c0mrade 我认为您不能为表单提交返回 false。尝试将$('selector').live('submit', function() { 更改为$('selector').live('submit', function(event) { 并在函数结束时将return false 替换为event.preventDefault(); 但是,您必须在函数中使用$.post 或$.ajax 在服务器端处理表单提交, 否则 cmets 仅在每个页面视图中存在。
  • @Jim Schubert 谢谢我做到了,我现在不太担心ajax,我更担心的是为什么我只选择一个时会附加多个cmets,我编辑了问题也许你可以看看代码,显然有问题..
  • @c0mrade 我用一些我认为你会发现有用的代码更新了我的答案。如果您愿意,可以使用$(this).find('.comments:first-child'),但我个人喜欢&gt;,因为它在视觉上暗示了元素的位置。此外,我一直使用元素,但我相信:first 返回一个 jQuery 对象。实际的 html 元素可以被缓存,例如,$(this).find(' &gt; .comments:first').get(0)
【解决方案2】:

每个页面上有多少个comment_forms?对于正确的 HTML,每页应该只有一个 id='comment_text' 和一个 id='comment_form'。

考虑将您的 id 更改为 class='comment_text' 并使用 .comment_text 而不是 #comment_text 进行查找


我认为从您最新的 cmets 来看,问题可能是您将表单/cmets 文本框动态添加到页面的方式。

一旦您输入并提交了 cmets,您是否会删除您动态添加的表单?我会推荐这个,好像不是我认为您的 DOM 结构变得混乱导致您遇到的问题。

【讨论】:

  • 我有一个图像搜索功能,用户可以选择每页需要多少个结果,默认情况下我会说 25 个,我会这样做.. 从 ID 切换到类,但我想让这个工作..
【解决方案3】:

首先,如果在适当的上下文中使用 find() 方法是正确的方法。

其次,听起来您正在重复使用 ID。这是不允许的。一个 ID 在一个页面上只能使用一次。

closest() 函数从(包括)DOM 元素中搜索“向上”。 find() 函数搜索元素的内容。

编辑:

我假设用户单击提交按钮时正在提交表单。我还假设您的submit() 处理程序比显示的要多。对吗?

有时您需要添加 $(this).preventDefault(); 以防止表单在您的代码中提交,以及“提交”按钮的默认行为。

以下内容(本质上)与 find() 执行相同的操作。它将在提交的表单中找到具有 .comment_text 类的项目。所以它应该只获取一项的价值:

image_comment_text=$(".comment_text", this).val();

【讨论】:

  • @patrick 这是真的我打算这样做,用类替换 ids,但最后我得到了同样的东西 juqery 选择类和 ID 都是一样的
  • 多个 ID 会混淆。永远不要这样做,因为它会导致事情发生意外。
  • @c0mrade - 也许表单被多次提交?试试$(this).preventDefault();。 (见编辑)
  • @patrick 我编辑了我的问题,我用你建议的作为其他人的建议工作..但是我的附加内容可能是错误的..
【解决方案4】:

您收到重复的 cmets,因为您没有删除以前的添加评论表单。尝试将此添加到您的 .slideDown 回调函数的末尾:

$(this).remove();

这是完整的提交功能,我做了一些更改/添加:

  • 我从find('.comment') 中删除了&gt;,因为它没有必要
  • 将新追加更改为一个类,然后在滚动到它后将其删除。
  • 完成后删除表单
  • event.preventDefault(); 更改为return false;...这更多的是个人喜好。

我希望这会有所帮助:)

 $('form[name^="comment_form"]').live('submit', function(event) {
  r = $(this).find('.comment').val();
  $('<div class="overlay"></div>')
   .appendTo('.addComment')
   .fadeIn(200, function() {
    $('.comments')
     .append('<li class="new_append">' + r + '</li>')
     .children(':last')
     .height($('.comments li:last').height())
     .hide()
     .slideDown(800, function() {
      var bodyHeight = $('html').height();
      $('.addComment').fadeOut(500, function() {
       $('html').height(bodyHeight);
       $('h2#leaveAComment').fadeOut(200, function(){$(this).text('Thank you for your comment!').fadeIn(200)});
       $(this).remove();
      });
     });
     $('html, body').scrollTo( $('.new_append:last'), 800 );
     $('.new_append').removeClass('new_append');
   });
  return false;
 });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 2011-07-27
    相关资源
    最近更新 更多