效果如下:
一般用于给购物车添加按钮时进行的特效
//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样式中的贝塞尔曲线更换即可