穿墙效果附加注释,附加鼠标进入方向算法
<!doctype html> <html><head><meta charset="UTF-8"><title>Title</title><style>* {margin: 0;padding: 0;list-style: none;}ul {overflow: hidden;width: 630px;margin: 100px auto;}ul li {float: left;position: relative;width: 200px;height: 200px;background: #ccc;margin: 5px;overflow: hidden;}ul li span {position: absolute;width: 100%;height: 100%;background: rgba(255, 0, 0, 0.3);left: -200px;top: 0;}</style><script>function getStyle(obj, sName) {// 获取元素对象的css属性值兼容ie和其他浏览器return (obj.currentStyle || getComputedStyle(obj, false))[sName];}function move(obj, json, options) {// obj 为元素对象、json为设定最后结果对象、options为设置对象// 给options设定默认值options = options || {};// 设定持续时间options.duration = options.duration || 700;// 设定运动方式options.easing = options.easing || 'ease-out';// 定义空对象var start = {};// 定义差值对象var dis = {};// 遍历设定设定最后结果对象for (var name in json) {// 将设定最后结果对象中的属性值与初始值取差值start[name] = parseFloat(getStyle(obj, name) );dis[name] = json[name] - start[name];}// 下方每30毫秒执行一次运动,这里获取运动总次数var count = Math.floor(options.duration / 30);// 设定运动初始次数var n = 0;// 清空间歇调用,如果以前定义过则清除动画次数 clearInterval(obj.timer);// 用obj.timer来代替动画次数obj.timer = setInterval(function() {n++;for (var name in json) {switch (options.easing) {case 'linear':var cur = start[name] + dis[name] * n / count;break;case 'ease-in':var a = n / count;var cur = start[name] + dis[name] * Math.pow(a, 3);break;// 次数默认使用ease-outcase 'ease-out':var a = 1 - n / count;// cur为每次运动后的元素的落脚位置var cur = start[name] + dis[name] * (1 - Math.pow(a, 3));break;}if (name == 'opacity') {obj.style.opacity = cur;obj.style.filter = 'alpha(opacity:' + cur * 100 + ')';} else {obj.style[name] = cur + 'px';}}// 如果运动完成,则清除运动(obj.timer)if (n == count) {// 清除动画次数 clearInterval(obj.timer);// 回调函数options.complete && options.complete();}}, 30);}function a2d(n) {// n 为弧度 ;弧度转化为角度return n * 180 / Math.PI;}function hoverDir(ev, obj) {// 领边长度var a = ev.clientX - obj.offsetLeft - obj.offsetWidth / 2;// 对边长度var b = obj.offsetTop + obj.offsetHeight / 2 - ev.clientY;// 通过角度来获得鼠标进入的方向;0为左侧、 1为下 、2为右、 3为上// Math.atan2(b, a)为获取弧度公式// a2d(n)为获取角度公式return Math.round((a2d(Math.atan2(b, a)) + 180) / 90) % 4;}function through(obj) {var oS = obj.children[0]; //这个是li里面的span// 鼠标进入的时候obj.onmouseenter = function(ev) {// 如果不知道ev是啥 就打印出来看看 console.log(ev)// 兼容ie浏览器var oEvent = ev || event;// obj为li,将oEvent和 li 作为参数,dir为返回值代表着鼠标的进入方向var dir = hoverDir(oEvent, obj);switch (dir) {case 0://左,oS为li中的 spanoS.style.left = '-200px';oS.style.top = 0;break;case 1://下oS.style.left = 0;oS.style.top = '200px';break;case 2://右oS.style.left = '200px';oS.style.top = 0;break;case 3://上oS.style.left = 0;oS.style.top = '-200px';break;}//oS是li里面的span,设置运动 // move(obj, json, options) obj = oS 、 json = { left: 0, top: 0 }、options取默认值,并且没有回调函数move(oS, { left: 0, top: 0 });};// 鼠标离开时obj.onmouseleave = function(ev) {var oEvent = ev || event;var dir = hoverDir(oEvent, obj);switch (dir) {case 0:// move(obj, json, options) obj = oS 、 json = { left: -200, top: 0 }、options取默认值,并且没有回调函数move(oS, { left: -200, top: 0 });break;case 1:move(oS, { left: 0, top: 200 });break;case 2:move(oS, { left: 200, top: 0 });break;case 3:move(oS, { left: 0, top: -200 });break;}};}window.onload = function() {var aLi = document.getElementsByTagName('li');for (var i = 0; i < aLi.length; i++) {through(aLi[i]);}};</script> </head><body><ul><li><span></span></li><li><span></span></li><li><span></span></li><li><span></span></li><li><span></span></li><li><span></span></li></ul> </body></html>