效果如下:
一般用于给购物车添加按钮时进行的特效
//html <div class="addToCart"> <span>+</span> </div> <!-- 这里的标签是为了写css样式 --> <!-- <div class="outer"> <div class="inner"></div> </div> --> <div class="shopCart"> <span>Cart</span> </div>
首先要先布局
然后设置其样式
//css样式 .addToCart { width: 36px; height: 36px; border-radius: 50%; top: 100px; left: 100px; position: absolute; background: #0f79b9; font-size: 30px; color: #fff; font-weight: bolder; line-height: 32px; text-align: center; cursor: pointer; z-index: 10; } .addToCart span { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .outer { z-index: 9; top: 100px; left: 100px; position: absolute; transition: -webkit-transform 1s linear; transition: transform 1s linear; transition: transform 1s linear, -webkit-transform 1s linear; } .outer .inner { border-radius: 50%; width: 36px; height: 36px; top: 0; left: 0; position: absolute; background: #e0c01b; opacity: 1; transition: all 1s cubic-bezier(.29,-0.48,.99,.19)} .shopCart { width: 100px; height: 40px; line-height: 40px; border-radius: 5px; background: #35b317; color: #fff; text-align: center; position: absolute; right: 100px; bottom: 100px; } /*# sourceMappingURL=cssway.css.map */
效果如图所示:
下面是给元素添加JS效果
var addToCart = document.querySelector('.addToCart'); var shopCart = document.querySelector('.shopCart'); // 对函数进行封装 function createBall() { // 创建一个outer var outer = document.createElement('div'); // 创建outer var inner = document.createElement('div'); //把inner塞到outer里面 // 生成两个节点 classlist:该属性适用于在元素中添加,移除以及切换CSS类 // classlist属性是只读的,但可以使用add()和remover()方法去修改它 outer.classList.add('outer'); //添加一个outer的节点 inner.classList.add('inner'); //添加一个inner的节点 // appendChild():向节点节点添加最后一个子节点 // insertBefore(newnode,existingnode):在已有子节点之前插入新的子节点newnode要插入的子节点,existingnode要添加新的节点前的子节点。两个值都要添加 outer.appendChild(inner); //把inner塞到outer里面 inner为变量,不是字符串,所以不需要加引号 // 在body里面增加一个outer document.body.appendChild(outer) return outer; }
然后调用createBall(),实现添加标签
核心是点击事件:
// createBall() /* 核心是点击事件 */ // 对盒子做一个点击事件 addToCart.addEventListener('click', function(e) { // 两个作用域不同,之间没有关系 var outer = createBall(), // firstchild可以获取多余文本节点 inner = outer.firstElementChild, //获取outer第一个子元素 // 起始的按钮就是点击的目标 startBtn = e.target, // getBoundingClientRect():可以获得页面中某个元素的上下左右别别相对浏览器视窗的位置 // +上下左右的间距 startPoint = startBtn.getBoundingClientRect(), // cart的上下左右的间距 endPoint = shopCart.getBoundingClientRect(), instanceX = endPoint.left - startPoint.left, // 结束的左边(cart) - 开始的左边(+) // 结束的上边(cart) - 开始的上边(+) // 可以获取两者之间的长度和高度 // 开始和结束必须使用定位,否则不会发生变化 instanceY = endPoint.top - startPoint.top; outer.style.transform = 'translate3d(' + instanceX + 'px,0,0)'; // 外面的小球控制他的水平方向 inner.style.transform = 'translate3d(0,' + instanceY + 'px,0)'; // 里面的小球控制它的垂直方向,形成一个抛物线 })
写到这里就可以实现给小球添加抛物线了
问题来了,如何让他的小球动画结束过后消失呢?有以下两种方法:
1、 inner.style.opacity = 0; //当完成之后可以让他过渡结束过后变成透明
效果:
让他变成透明放进来的东西实际上没有被移除,,点击过多,会影响到内存占用
建议使用第二种方案
function animateEnd(e) { var target = e.target; // classList.contains:是不是存在这个节点 if (target.classList.contains('outer')) { // 如果有outer,就把他的父节点给移除掉,他的子节点就不会存在 removeNode(target); } if (target.classList.contains('inner')) { // 移除目标值的parentNode removeNode(target.parentNode); } } //不能直接调用,他不知道这个动画在什么时候移除 // 应该在动画结束之后移除 function removeNode(ele) { //移除节点 ele.parentNode && ele.parentNode.removeChild(ele); //找到目标值的父节点同时移除节点 // 让这个元素变为空 ele = null; } // 加一个监听器,当过渡动画结束过后再去执行这个结束的动画 window.addEventListener('transitionend', animateEnd, false); // animageEnd:在css完成过渡后触发 //false:冒泡 //true:捕获
这样就不会有内存占用的问题了
如果想更改抛物线的话可以更改css样式中的贝塞尔曲线更换即可