You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()))? 'حذف از علاقه&zwnj;مندی' : 'افزودن به علاقه&zwnj;مندی' }}</span>
    </a>
@else
    <button id="wishlist" href="#" class="btn-option wishlist-erroe">
        <i class="mdi mdi-heart-outline"></i>
        <span class="tooltip-short">افزودن به علاقه&zwnj;مندی</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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 11:40:04