手写一个购买的商品放入购物车的效果

1,837 阅读8分钟

手写一个购买的商品放入购物车的效果

昨天因为看到了一个比较好玩的内容,于是研究了一下,没有更文。今天我就拿出来讲一讲。就是商品卡片,当我们置顶的时候,它的内容会有一个动画将它的商品内容滑出来给我们展示,并且点击加入购物车的时候,会出现一张缩小的图片移动到购物车的位置,并且购物车的数量也会加1。不过,我看到原文使用的jquery实现的,而且没有实现响应式布局.于是昨天我琢磨了一下,终于搞出来了,js版本,并且实现了响应式布局,为了模拟真实性还给它添加了一个判断属性,商品是否还有剩余。当商品显示已抢光时,会有一个alert,告诉我们商品已经没了。

模拟真实的图 image.png 自己做的图

image.png 效果图

响应式 image.png

image.png

实现步骤

整体页面布局格式包含了一个购物车和三个商品卡片。购物车包含了一个购物车图标和一个商品数量计数器,商品卡片包含了一个商品图片、商品名称、商品描述、商品价格和两个按钮(加入购物车和立即购买)。

在我的代码里,那个珊瑚的图标我是直接把掘金的页面那个svg全部扒下来的。然后html中引入的js是一个图标库,就是我们的那个购物车图标,大家也可以替换成自己喜欢的库。哦,对了,之前我文章的图片都是网上复制的链接,因为想到链接可能会失效,于是这次我把图片,存到了我的gitte搭建的图床里。

image.png

css布局

其实最主要的是为了调成响应式的花了我大部分时间。用@media比较具体,但是真的让我头秃了不止一点。

首先,文字和内容里面的大小都要调整,因为整个盒子都变小了,你不变小,就只能看到文字了。然后把文字部分移动的更远一点,因为这里并不是利用透明度让它消失不见,而是通过定位让它挡住,看不见了。

后面在当屏幕宽度小于等于760px时,我们让卡片变成相对定位,然后里面的图片是绝对定位,保证了图片大小一致,文字部分相对定位,使文字落在盒子的下面。

在最后当屏幕宽度小于等于380px时,我只是对按钮进行了一个调整,让按钮位置更美观。

/* 当屏幕宽度小于等于1000px时 */
@media (max-width:1000px) {
    /* 卡片内容部分向上移动,字体大小和间距调整 */
    .wrapper .card .content {
        bottom: -120%; /* 向上移动卡片内容的高度 */
        padding: 5px 10px 11px 10px; /* 调整卡片内容的内边距 */
        padding: 10px 20px 22px 20px; /* 调整卡片内容的内边距 */
        box-shadow: 0px -2px 5px 0px rgba(0, 0, 0, 0.15); /* 添加底部阴影 */
        transition: all 0.3s ease; /* 添加过渡效果 */
    }

    /* 调整详情部分的字体大小 */
    .content .row .details span {
        font-size: 18px;
        font-weight: 300;
    }

    /* 调整详情部分的字体大小 */
    .content .row .details p {
        font-size: 12px;
        font-weight: 250;
    }

    /* 调整价格部分的显示方式 */
    .content .row .price {
        display: flex;
        font-size: 15px;
        font-weight: 400;
    }

    /* 调整按钮部分的上边距 */
    .content .buttons {
        margin-top: 10px;
    }

    /* 调整按钮的样式 */
    .content .buttons button {
        width: 100%;
        padding: 6px 0;
        font-size: 12px;
        font-weight: 300;
        border-radius: 6px;
    }

    /* 调整第一个按钮的右边距 */
    .buttons button:first-child {
        margin-right: 5px;
    }

    /* 调整最后一个按钮的左边距 */
    .buttons button:last-child {
        margin-left: 5px
    }
}

/* 当屏幕宽度小于等于760px时 */
@media (max-width:760px) {
    /* 卡片图片变成相对定位 */
    .wrapper .card {
        position: relative;
        background: #fff;
    }

    /* 卡片图片变成绝对定位 */
    .wrapper .card img {
        position: absolute;
    }

    /* 卡片内容部分相对于卡片定位 */
    .wrapper .card .content {
        position: relative;
        width: 100%;
        margin-top: 100%; /* 卡片内容部分的上边距等于卡片高度 */
        background: #fff;
        padding: 10px 20px 22px 20px;
        box-shadow: 0px -3px 10px 0px rgba(0, 0, 0, 0.15);
        transition: all 0.3s ease;
    }
}

/* 当屏幕宽度小于等于380px时 */
@media (max-width:380px) {
    /* 调整按钮部分的样式 */
    .content .buttons {
        margin: 0;
        padding: 0;
        margin-top: 10px;
        display: flex;
        justify-content: center;
    }

    /* 调整按钮的样式 */
    .content .buttons button {
        width: 100%;
        padding: 3px 0;
        font-size: 12px;
        font-weight: 300;
        border-radius: 10px;
        border: 2px solid #ff7979;
        text-transform: uppercase;
        transition: all 0.3s ease;
    }
}

js具体实现过程如下:

先看一看我们的js是怎么实现的吧! 这段代码实现了一个简单的购物车功能,当用户点击“加入购物车”按钮时,会将对应商品的图片复制一份,并以动画的形式将其移动到购物车图标处。同时,购物车中的商品数量会增加,对应商品的库存数量会减少。

  1. 首先,我们通过 document.querySelectorAll() 函数获取了所有的“加入购物车”按钮、商品图片、商品库存和购物车图标等元素,并将它们分别保存在 cartBtnsimgsishave 和 cartNav 变量中。

  2. 然后,我们使用一个 for 循环遍历所有的“加入购物车”按钮,并为每个按钮添加一个 click 事件监听器。在事件处理函数中,我们首先判断对应商品的库存数量是否大于 0,如果是,则执行以下操作:

    • 获取对应商品的库存数量,并将其减 1。
    • 复制对应商品的图片,并设置其样式属性,使其在页面上与原图片重叠。
    • 将复制的图片添加到页面中,并以动画的形式将其移动到购物车图标处。
    • 在动画结束后,将复制的图片从页面中移除,并将购物车中的商品数量增加 1。
  3. 如果对应商品的库存数量为 0,则弹出一个提示框,告诉用户该商品已经抢完了。

注意的要点

我这里单独拿出来解释。

  • 因为不同的浏览器对于获取页面滚动距离的方式不同,所以这里使用了多个属性来获取页面的滚动距离,最终得到的值就是页面在垂直方向和水平方向上已经滚动的距离。
 var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; // 获取页面的滚动距离
 var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
  • 设置图片的定位方式,因为只有绝对定位,我们才能更好的通过知道它们的位置来进行移动。
var imgPosition = 'absolute'; 
  • 图片位置的移动的实现
imgClone.style.transform = 'translate(' + (imgFinalLeft - imgLeft) + 'px, ' + (imgFinalTop - imgTop) + 'px)'; // 设置图片的最终变换
  • 这行代码的作用是设置复制的图片的最终位置,具体来说:

    • imgFinalLeft 和 imgFinalTop 分别表示购物车图标在页面中的左上角的横坐标和纵坐标,加上一些偏移量,就可以得到复制的图片的最终位置。
    • imgLeft 和 imgTop 分别表示复制的图片在页面中的左上角的横坐标和纵坐标,两者的差值就是复制的图片需要移动的距离。
    • translate() 函数可以将元素在平面上移动指定的距离,其中第一个参数表示横向移动的距离,第二个参数表示纵向移动的距离。

因此,imgClone.style.transform 的值就是一个 translate() 函数,它的参数是复制的图片需要移动的横向和纵向距离,这样就可以将复制的图片移动到购物车图标的位置。

js源码
// 获取所有的“加入购物车”按钮、商品图片、商品库存和购物车图标等元素
var cartBtns = document.querySelectorAll('.cart-btn'); // 获取所有的“加入购物车”按钮
var itemCount = document.querySelector('.item-count'); // 获取购物车中的商品数量显示元素
var cartNav = document.querySelector('.cart-nav'); // 获取购物车图标元素
var imgs = document.querySelectorAll('img') // 获取所有的商品图片
var ishave = document.querySelectorAll('h6') // 获取所有的商品库存元素

console.log(itemCount)

// 初始化购物车中的商品数量为 0
var count = 0;

// 遍历所有的“加入购物车”按钮,并为每个按钮添加一个 click 事件监听器
for (let i = 0; i < cartBtns.length; i++) {
    var cartBtn = cartBtns[i];

    cartBtn.addEventListener('click', function () {
        // 判断对应商品的库存数量是否大于 0
        var ishad = (ishave[i].textContent !== '已抢完');

        if (ishad) {
            // 复制对应商品的图片,并设置其样式属性,使其在页面上与原图片重叠
            var imgToDrag = imgs[i];
            var imgClone = imgToDrag.cloneNode(); // 复制图片
            var imgRect = imgToDrag.getBoundingClientRect(); // 获取图片在页面中的位置和大小
            var cartRect = cartNav.getBoundingClientRect(); // 获取购物车图标在页面中的位置和大小
            //因为不同的浏览器对于获取页面滚动距离的方式不同,所以这里使用了多个属性来获取页面的滚动距离,最终得到的值就是页面在垂直方向和水平方向上已经滚动的距离。
            var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; // 获取页面的滚动距离
            var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
            var imgTop = imgRect.top + scrollTop; // 计算图片在页面中的绝对位置
            var imgLeft = imgRect.left + scrollLeft;
            var cartTop = cartRect.top + scrollTop;
            var cartLeft = cartRect.left + scrollLeft;
            var imgWidth = imgRect.width; // 获取图片的宽度和高度
            var imgHeight = imgRect.height;
            var imgOpacity = 0.8; // 设置图片的透明度
            var imgPosition = 'absolute'; // 设置图片的定位方式
            var imgZIndex = 100; // 设置图片的层级
            var imgTransform = 'translate(0, 0)'; // 设置图片的初始变换
            var imgTransition = 'transform 1s ease-in-out'; // 设置图片的动画效果
            var imgFinalWidth = 75; // 设置图片最终的宽度和高度
            var imgFinalHeight = 75;
            var imgFinalTop = cartTop + 20; // 计算图片最终的位置
            var imgFinalLeft = cartLeft + 30;

            imgClone.style.opacity = imgOpacity; // 设置图片的透明度
            imgClone.style.position = imgPosition; // 设置图片的定位方式
            imgClone.style.width = imgWidth + 'px'; // 设置图片的宽度和高度
            imgClone.style.height = imgHeight + 'px';
            imgClone.style.zIndex = imgZIndex; // 设置图片的层级
            imgClone.style.transform = imgTransform; // 设置图片的初始变换
            imgClone.style.transition = imgTransition; // 设置图片的动画效果
            imgClone.style.top = imgTop + 'px'; // 设置图片的初始位置
            imgClone.style.left = imgLeft + 'px';

            // 将复制的图片添加到页面中,并以动画的形式将其移动到购物车图标处
            document.body.appendChild(imgClone);

            setTimeout(function () {
                imgClone.style.transform = 'translate(' + (imgFinalLeft - imgLeft) + 'px, ' + (imgFinalTop - imgTop) + 'px)'; // 设置图片的最终变换
                imgClone.style.width = imgFinalWidth + 'px'; // 设置图片的最终宽度和高度
                imgClone.style.height = imgFinalHeight + 'px';
            }, 0);

            // 在动画结束后,将复制的图片从页面中移除,并将购物车中的商品数量增加 1
            setTimeout(() => {
                // 获取对应商品的库存数量,并将其减 1 因为textContent是字符串'库存:1200'所以我们要正则拿到数值
                var Number = parseInt(ishave[i].textContent.replace(/\D/g, ""));
                count++; // 增加购物车中的商品数量
                Number--;
                ishave[i].textContent = '库存:' + Number // 更新对应商品的库存数量显示
                itemCount.textContent = count; // 更新购物车中的商品数量显示
                imgClone.parentNode.removeChild(imgClone); // 移除复制的图片
            }, 1000)

        } else {
            // 如果对应商品的库存数量为 0,则弹出一个提示框,告诉用户该商品已经抢完了
            alert('商品已经抢完了')
        }
    })
}


源码

希望大家能点个赞,谢谢!

image.png

源码自取地址掘金/购物车 · Mr-W-Y-P/Html-css-js-demo - 码云 - 开源中国 (gitee.com)