Laravel中jQuery Ajax商品收藏按钮无刷新切换问题求助
Laravel Ajax收藏按钮切换问题解决方案
问题
在Laravel项目中使用jQuery Ajax实现商品收藏爱心按钮,添加和移除收藏的功能已实现,但存在问题:添加收藏后无法直接点击按钮执行移除操作,必须刷新页面才能再次交互。
问题原因
原代码中直接将点击事件绑定在.add-wishlist和.remove-wishlist元素上,而通过Ajax动态生成的新元素不会继承这些事件绑定,导致新生成的按钮无法触发点击事件。
解决方案
1. 使用事件委托绑定点击事件
将事件绑定到document上,利用事件冒泡机制处理动态生成元素的点击事件,同时优化DOM操作,无需删除重建元素,直接切换类名和状态。
修改后的JS代码:
// 移除收藏事件(事件委托) $(document).on('click', '.remove-wishlist', function(e){ e.preventDefault(); var $btn = $(this); var idProduct = $btn.data('wishlist'); $.get({ type: 'GET', url: '/remove-from-wishlist/' + idProduct, dataType: 'json', success: function (data) { console.log(data); $.growl({ title: "توجه", message: data.message, style: "warning", location: "br", namespace: 'growl', }); // 直接切换类名和文本,无需重建元素 $btn.removeClass('remove-wishlist btn-option-favorites').addClass('add-wishlist'); $btn.find('.tooltip-short').text('افزودن به علاقه‌مندی'); }, error: function(xhr) { console.log(xhr.responseText); $.growl({ title: "توجه", message: "مشکی رخ داده است ", style: "error", location: "br", }); } }); }); // 添加收藏事件(事件委托) $(document).on('click', '.add-wishlist', function(e){ e.preventDefault(); var $btn = $(this); var idProduct = $btn.data('wishlist'); $.ajax({ type: 'GET', url: '/add-to-wishlist/' + idProduct, dataType: 'json', success: function (data) { console.log(data); $.growl({ title: "توجه", message: data.message, style: "notice", location: "br", }); // 直接切换类名和文本 $btn.removeClass('add-wishlist').addClass('remove-wishlist btn-option-favorites'); $btn.find('.tooltip-short').text('حذف از علاقه‌مندی'); }, error: function(xhr) { console.log(xhr.responseText); $.growl({ title: "توجه", message: "مشکی رخ داده است ", style: "error", location: "br", }); } }); });
2. 优化HTML初始状态
调整按钮文本,根据初始收藏状态显示对应内容:
@auth <a id="wishlist" href="#" class="btn-option btn-option-wishes{{ ($product->checkUserWishlist(auth()->id()))? ' btn-option-favorites remove-wishlist ':' add-wishlist' }}" data-wishlist="{{ $product->id }}"> <i class="mdi mdi-heart-outline"></i> <span class="tooltip-short">{{ ($product->checkUserWishlist(auth()->id()))? 'حذف از علاقه‌مندی' : 'افزودن به علاقه‌مندی' }}</span> </a> @else <button id="wishlist" href="#" class="btn-option wishlist-erroe"> <i class="mdi mdi-heart-outline"></i> <span class="tooltip-short">افزودن به علاقه‌مندی</span> </button> @endauth
3. 优化Laravel控制器逻辑
完善未登录校验、重复操作拦截,简化删除逻辑:
class WishlistController extends Controller { public function add(Product $product) { if (!auth()->check()) { return response()->json(['success' => false, 'message' => 'لطفاً ابتدا وارد حساب کاربری خود شوید'], 401); } // 避免重复添加 if (!$product->checkUserWishlist(auth()->id())) { Wishlist::create([ 'user_id' => auth()->id(), 'product_id' => $product->id ]); return response()->json(['success' => true, 'message' => 'محصول مورد نظر به لیست علاقه مندی ها شما اضافه شد']); } return response()->json(['success' => false, 'message' => 'این محصول قبلاً به لیست علاقه مندی شما اضافه شده است']); } public function remove(Product $product) { if (!auth()->check()) { return response()->json(['success' => false, 'message' => 'لطفاً ابتدا وارد حساب کاربری خود شوید'], 401); } $deleted = Wishlist::where('product_id', $product->id) ->where('user_id', auth()->id()) ->delete(); if ($deleted) { return response()->json(['success' => true, 'message' => 'محصول مورد نظر از لیست علاقه مندی ها شما حذف شد']); } return response()->json(['success' => false, 'message' => 'این محصول در لیست علاقه مندی شما وجود ندارد']); } public function usersProfileIndex() { $wishlist = Wishlist::where('user_id', auth()->id())->get(); return view('home.users_profile.wishlist', compact('wishlist')); } }
4. 模型方法保持不变
public function checkUserWishlist($userId) { return $this->hasMany(Wishlist::class)->where('user_id', $userId)->exists(); }
关键改进点
- 采用事件委托替代直接元素绑定,解决动态生成元素的事件触发问题
- 简化DOM操作,直接切换类名和文本内容,提升性能
- 完善控制器的错误处理和重复操作校验
- 修复原JS中错误回调里
data未定义的问题,改用xhr.responseText查看错误信息
内容的提问来源于stack exchange,提问作者RASOOL FALLAH
相关产品推荐
相关产品推荐

