【问题标题】:jquery .click() event issue (django)jquery .click() 事件问题(django)
【发布时间】:2013-11-22 07:38:05
【问题描述】:

我创建了一个生成帖子的视图,每个帖子都有一个 cmets_set,它生成用户创建的所有 cmets。当发布新评论时,将执行以下函数。

$("#comment-post-button").click(function(){ 
    var event_id = document.getElementById('event-id').value;
    var url= '/post-comments/'+event_id +'/';

    var data = {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
              content:document.getElementsByName('comment-post-content')[0].value
             }
    $.post(url , data, function(){
      $("#refresh-comments").load("/comments/" + event_id + '/', function(){
        $("#comment-post-content").val(""); 
      });
    });
    $("#comment-post-content").val("");  
    return false;
  });

问题是该页面包含多个帖子,并且每个评论提交按钮具有相同的 id “comment-post-button”。所以上面的函数只对顶帖有效,对其余的无效。我可以看到问题是什么,但不知道如何解决。请帮忙。

这里是html标记:

{% for event in events %}
    <div class="post">
      <div class="post-right">
        <div class="post-author"><a href="/{{ event.author.username }}/">{{ event.author.first_name }}</a></div>
        <div class="post-content">{{ event.description }}</div> 
        <div class="post-bar">
          <div class="post-likes">{{ event.up_votes }}<a href="#"><img src="/site-media/static/images/like.png" /></a></div>
          <div class="post-dislikes">{{ event.down_votes }}<a href="#"><img src="/site-media/static/images/dislike.png" /></a></div> 
          <div class="post-timestamp">{{ event.pub_date }}</div>
          <a href="#" class="post-comment-link">Comment</a>
        </div>
        <div class="post-comment">
          <form method="post" action="/post-comments/{{ event.id }}/">
            {% csrf_token %}
            <input type="text" id="comment-post-content" name="comment-post-content" maxlength="200" placeholder="Add a comment..." />
            <input type="hidden" id="event-id" value="{{ event.id }}">
            <input type="submit" id="comment-post-button" class="comment-post-button" value="Post comment" />
          </form>
        </div>
        <div id="refresh-comments" class="comments">
          {% include "comments.html" %}
        </div>
      </div>
      <div class="post-left">
        <a href="#"><img src="../FestJanta/site-media/static/images/post.jpg" /></a>
      </div>
    </div>
    {% endfor %}

cmets.html:

{% for comment in event.comment_set.all|slice:"3" %}
<div class="comments-right">
    <a href="/{{ name }}/" class="first_name">{{ comment.author.first_name }}</a>
    {{ comment.content }}<br>
    <div class="comment-timestamp">{{ comment.pub_date }}</div>
</div>
<div class="comments-left"><a href="#"><img src="../FestJanta/site-media/static/images/comment.jpg" /></a></div>
{% endfor %}

最终工作解决方案:

$(".comment-post-button").click(function(){ 
    var btn = $(this);
    var currentPost = btn.parents('.post');
    var event_id = currentPost.find('.event-id').val();
    var url= '/post-comments/'+event_id +'/';
    var data = {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
              content:currentPost.find('input[name="comment-post-content"]').val()
             }
    $.post(url , data, function(){
      $(currentPost.find('.refresh-comments')).load("/comments/" + event_id + '/', function(){
        $(currentPost.find('.comment-post-content')).val(""); 
      });
    }); 
    return false;
  });

【问题讨论】:

  • 您可以为所有的 Post 按钮提供相同的类,然后按类访问它们
  • @AjinderSingh 但是,这将如何解决问题。我需要唯一标识一个发布按钮
  • @karaxuna 你能详细说明一下吗?
  • @AjinderSingh 我试过这样做,但这会导致将所有 cmets 发布到第一个事件。
  • @Monique - 您可以使用 $(this) 访问当前单击的按钮

标签: javascript jquery python html django


【解决方案1】:

移除 id 并添加类:

<input type="hidden" class="event-id" value="{{ event.id }}">

做这样的事情:

$('.comment-post-button').click(function(){
    var $btn = $(this);
    var $currentPost = $btn.parents('.post');
    var event_id = $currentPost.find('.event-id').val();
    //...
});

$currentPost 范围内查找每个元素: 而不是这个:

content: document.getElementsByName('comment-post-content')[0].value

这样做:

content: $currentPost.find('input[name="comment-post-content"]').val()

【讨论】:

  • 它仍然无法获取“内容”输入。
【解决方案2】:

您可以执行以下操作:

  • 标识所有发布按钮,例如通过类似 .comment-button 的类
  • 使用 jQuery 的 .on() 表示法
  • 传递事件并使用其target 属性来识别触发事件的DOM 元素
  • 使用遍历获取帖子的正确 DOM 元素

结果应该是这样的(未经测试):

标记(我基本上只是摆脱了 ID;不确定 django 如何/是否自动处理):

{% for event in events %}
<div class="post">
  <div class="post-right">
    <div class="post-author"><a href="/{{ event.author.username }}/">{{ event.author.first_name }}</a></div>
    <div class="post-content">{{ event.description }}</div> 
    <div class="post-bar">
      <div class="post-likes">{{ event.up_votes }}<a href="#"><img src="/site-media/static/images/like.png" /></a></div>
      <div class="post-dislikes">{{ event.down_votes }}<a href="#"><img src="/site-media/static/images/dislike.png" /></a></div> 
      <div class="post-timestamp">{{ event.pub_date }}</div>
      <a href="#" class="post-comment-link">Comment</a>
    </div>
    <div class="post-comment">
      <form method="post" action="/post-comments/{{ event.id }}/">
        {% csrf_token %}
        <input type="text" name="comment-post-content" maxlength="200" placeholder="Add a comment..." />
        <input type="hidden" name="event-id" value="{{ event.id }}">
        <input type="submit" class="comment-post-button" value="Post comment" />
      </form>
    </div>
    <div class="comments">
      {% include "comments.html" %}
    </div>
  </div>
  <div class="post-left">
    <a href="#"><img src="../FestJanta/site-media/static/images/post.jpg" /></a>
  </div>
</div>
{% endfor %}

Javascript:

$("body") // Could be any ancestor, body is not the best option
.on('click', '.comment-post-button' function(ev){ 
    var clickTarget = ev.target, // The element clicked on
    postElement = $(clickTarget).closest('.post'), // the div enclosing a post
    commentSection = $(postElement).find(".comments"), // the div enclosing the comments
    commentInputField = $(clickTarget).siblings("[name='comment-post-content']"),
    event_id = $(clickTarget).siblings("[name='event-id']").val(),
    url= '/post-comments/'+event_id +'/';

    // Not sure what this token is, so I will not change that part
    var data = {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
          content: commentInputField.val()
         }
    $.post(url , data, function(){
        $(commentSection).load("/comments/" + event_id + '/', function(){
            $(commentInputField ).val("").prop('disabled', false); // In the callback, empty and reenable
        });
    });
    $(commentInputField ).prop('disabled', true); // I guess disabling the field makes sense
    return false;
});

另一个优点是您最终只会得到一个点击处理程序。请注意,可以优化解决方案(例如,通过改进选择器)。另外,jslint会给出一些警告。

【讨论】:

    【解决方案3】:

    按照某人的建议,为每个帖子和 post_Comment_button 提供一个唯一的 ID,更改标记如下:

    {% for event in events %}
        <div class="post" id="post_{{forloop.counter}}">
    
        [...]
    
        <input type="submit" id="comment-post-button_{{forloop.counter}}" class="comment-post-button" value="Post comment" />
    

    然后修改js函数如下:

    $("#comment-post-button").click(function(event){ 
        var buttonNr = event.target.id.replace('comment-post-button_', ''); 
        var postId = 'post_' + buttonNr;
    
        $("#" + postId)... --> and do whatever with it..
    

    【讨论】:

    • 但是,如果我这样做,我将不得不为每个函数编写一个 jquery 函数。这并不能解决它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多