Django项目中for循环渲染的帖子点击书签按钮如何正确切换对应元素class
帖子书签功能问题修复方案
你提供的Django视图代码逻辑没有问题,问题集中在前端代码部分,核心错误点如下:
- DOM中id必须全局唯一,你循环渲染所有帖子的书签按钮都使用了同一个
id="bookmark_add",会导致选择器只能匹配到第一个符合条件的元素,无法准确定位当前点击的按钮 - Ajax的success回调函数默认
this指向的是jQuery ajax配置对象,不是你点击的按钮元素,所以直接在回调里写$(this)无法获取到目标按钮 - data属性取值逻辑错误:使用jQuery的
data()方法取自定义属性时,不需要加data-前缀,你写的$(this).data("data-id")必然返回undefined - 后续测试的jQuery选择器写法不符合规范,无法匹配到对应元素
修复后代码
HTML部分
将重复的id改为class,同时给计数span的id加前缀避免和其他元素id冲突:
<span id="bookmark_count_{{post.id}}" class="bookmark_coun text-muted">{{ post.get_bookmarks_count }}</span> {% if request.user.is_authenticated %} {% if request.user not in post.bookmarks.all %} <button class="bookmark_btn bookmark" name="bookmark" data-id="{{post.id}}"><i class="far fa-bookmark fa-lg"></i></button> {% else %} <button class="bookmark_btn bookmark" name="bookmark" data-id="{{post.id}}"><i class="fad fa-bookmark fa-lg"></i></button> {% endif %} {% else %} <a href="{% url 'users:register' %}" class="bookmark"><i class="far fa-bookmark fa-lg"></i></a> {% endif %}
Ajax部分
提前存储当前点击的按钮元素解决this指向问题,绑定点击事件到class上,根据后端返回的状态直接设置图标class(比toggle更稳妥,可避免多次快速点击导致的前端状态和后端状态不一致问题):
// 书签功能 $(document).on('click', '.bookmark_btn', function (e) { e.preventDefault(); // 提前存储当前点击的按钮元素 let $curBtn = $(this); let postId = $curBtn.data("id"); $.ajax ({ type: 'POST', url: '{% url "users:add-post-bookmark" %}', data: { 'id': postId, csrfmiddlewaretoken: '{{ csrf_token }}', action: 'post' }, success: function (response) { // 更新书签计数 $('#bookmark_count_' + response.post_id).text(response.bookmark_count); // 根据后端返回的状态设置图标class let $icon = $curBtn.find('i'); if (response.is_bookmark) { $icon.removeClass('far').addClass('fad'); } else { $icon.removeClass('fad').addClass('far'); } }, error: function (xhr, errmsg, err) { console.log("Error bookmarking post!"); } }); })
内容的提问来源于stack exchange,提问作者iamcoder
相关产品推荐
相关产品推荐

