Dom_坐标属性及动画算子等(三)
- 事件对象中的坐标的几个属性
- offsetX, offsetY
- 事件触发点相对于target元素的左边和上边的偏移量
- 或者认为现在的坐标系原点:target元素的左上角
- clientX, clientY
- 相对于游览器的左边和上边的偏倚量
- screenX ,screenY
- 显示器的左上角作为坐标原点
- 别名: X, Y
- pageX, pageY
-
把页面的左上角作为坐标原点
-
事件代理
循环式的注册事件
- 当有新元素添加的时候,这些元素不会自动的有事件,必须要手动添加
- 当那些已经有事件的元素删除的时候,那些事件永远用不到了但是不会被内存回收,容易引起内存泄漏。
事件委托, 事件代理
把事件委托给它的上层元素来处理
var btn = document.querySelector("button");
btn.onclick = function (){
var li = document.createElement("li");
li.innerHTML = "python";
ul.appendChild(li);
}
ul.onclick = function (e){
var target = e.target;
if(target.className == "item"){
alert(target.innerHTML);
}
/*if (target.tagName.toLowerCase() == "li"){
alert(target.innerHTML);
}*/
}
-
open方法
var btn = document.querySelector("#btn"); var btn2 = document.querySelector("#btn2"); btn.onclick = function (){ // 参数1:url 参数2:给新打开的网页起个名字 /* 参数2: _black 如果传入一个空字符串,也是_blank _self 表示在当前的tab页面中打开. "普通的名字" 表示给打开的页面起个名字, 将来再使用 open打开的时候, 会先查看有这个名字的页面是否已经打开 如果是, 就刷新已经打开的页面 返回值:就是新打开的窗口(其实就是一个新的页面中的window对象) */ win = open("abc.html", "b", "width=300,height=200,left=400,top=500"); } var win; btn2.onclick = function (){ win.close(); // close(); }
-
小广告
- open: 打开新的窗口
- close: win.close() 调用那个window的close,就可以关掉哪个window
- moveBy(): 移动窗口
- moveBy(-10, 10)
- moveTo(): 移动到指定位置
-
moveTo(100, 100)
setTimeout(function (){ win = open("abc.html", "_blank", "width=400,height=400,left=200,top=200"); }, 10); var lastI; setInterval(function (){ /*if (win && win.innerWidth == 0){ win = open("abc.html", "_blank", "width=400,height=400,left=200,top=200"); }*/ win.moveBy(10, 10); }, 200)
-
-
location
<button>assign:加载新的文档</button> <button>reload:重新加载当前文档</button> <button>replace:用新的页面当前页面</button> <script> var btns = document.querySelectorAll("button"); btns[0].onclick = function (){ // 会把访问记录添加到history中 location.assign("https://www.baidu.com"); } btns[1].onclick = function (){ // 重新加载当前网页 // true:表示总是从服务器加载 false: 表示允许从缓存加载 location.reload(false); } btns[2].onclick = function (){ // 不会把访问记录添加到history location.replace("https://www.baidu.com"); } </script> <!--<script> document.write("协议:" + location.protocol + "<br>") document.write("host:" + location.host + "<br>") document.write("hostname:" + location.hostname + "<br>") document.write("href:" + location.href + "<br>") document.write("port:" + location.port + "<br>") document.write("pathname:" + location.pathname + "<br>") document.write("search:" + location.search + "<br>") </script>-->
-
history
<button>直接去第三个</button> <a href="second.html">去第二个页面</a> <script> // 记录你在当前这个页面中访问过的url的个数 console.log(history.length); var btn = document.querySelector("button"); btn.onclick = function (){ history.go(); }
-
navigator
-
screen
-
以前用到的动画的一些问题
增量动画
- setTimeout
- setInterval
时间的动画
-
var p = Math.min(1, (new Date() - starTime) / 2000);
-
p: 时间的归一化. p就是我们归一化的时间
<button id="btn">开始运动</button> <script> // 1000ms 10s走完 var btn = document.querySelector("button"); var div = document.querySelector("div"); var duration = 2000; btn.onclick = function (){ var starTime = new Date(); // 动画的开始时间 requestAnimationFrame(function step(){ var p = Math.min(1, (new Date() - starTime) / duration); div.style.left = 1000 * p + "px"; if (p < 1){ requestAnimationFrame(step); } }); }
匀加速运动
<button id="btn">开始运动</button>
<script>
// 1000ms 10s走完
var btn = document.querySelector("button");
var div = document.querySelector("div");
var duration = 1000;
var dis = 500;
btn.onclick = function (){
var starTime = new Date(); // 动画的开始时间
requestAnimationFrame(function step(){
var p = Math.min(1, (new Date() - starTime) / duration);
// div.style.left = dis * p * p + "px"; // 匀加速
// div.style.left = dis * p * (2 - p) + "px"; //匀减速
// div.style.left = 2 * dis * p + "px"; //
// div.style.top = dis * p * p + "px"; //
div.style.left =200 - 200 * Math.sin(Math.PI * 2 * p) + "px";
div.style.top = 200 - 200 * Math.cos(Math.PI * 2 * p) + "px";
if (p < 1){
requestAnimationFrame(step);
}
});
}
- 使用动画算子
- 写一个框架,可以完成大部分的动画动作
- 给框架需要输入数据
-
周期 —— 计算归一化的时间
-
动画算子函数 —— 用来计算动画算子
-
函数、动画具体的动作 —— 框架计算出来动画算子,帮助我们去执行这些动作
动画算子: e = p e = p*p e = p*(2-p) <button id="btn">开始运动</button> <script src="easing.js"></script> <script> var btn = document.querySelector("button"); var div = document.querySelector("div"); var duration = 2000; // 动画周期, 表示动画应该多长时间执行完毕 var dis = 500; btn.onclick = function (){ // var initLeft = div.offsetLeft; var starTime = new Date(); // 动画的开始时间 requestAnimationFrame(function step(){ var p = Math.min(1, (new Date() - starTime) / duration); // 归一化的时间 // div.style.left = dis * p + "px"; // div.style.left = dis * p * p + "px"; div.style.top = dis * Easing.easeBoth(p) + "px"; if (p < 1){ requestAnimationFrame(step); } }); } <div></div> <p></p> <button id="btn">开始运动</button> <script src="easing.js"></script> <script src="animator.js"></script> <script> var btn = document.querySelector("button"); var div = document.querySelector("div"); var anim = new MyAnimator(2000, Easing.bounce, function (e){ div.style.left = 1000 *(1 - e) + "px"; }) anim.start(); //---- var p = document.querySelector("p"); var anim1 = new MyAnimator(5000, Easing.bounce, function (e){ // p.style.left = 1000 * (1 - e) + "px"; p.style.opacity = 1 - e; }); anim1.start(); </script> var pow = Math.pow, BACK_CONST = 1.70158; // t指的的是动画进度 归一化的时间 前面的p Easing = { // 匀速运动 linear: function (t){ return t; }, // 匀加速运动 easeIn: function (t){ return t * t; }, // 减速运动 easeOut: function (t){ return (2 - t) * t; }, //先加速后减速 easeBoth: function (t){ return (t *= 2) < 1 ? .5 * t * t : .5 * (1 - (--t) * (t - 2)); }, // 4次方加速 easeInStrong: function (t){ return t * t * t * t; }, // 4次方法的减速 easeOutStrong: function (t){ return 1 - (--t) * t * t * t; }, // 先加速后减速,加速和减速的都比较剧烈 easeBothStrong: function (t){ return (t *= 2) < 1 ? .5 * t * t * t * t : .5 * (2 - (t -= 2) * t * t * t); }, // easeOutQuart: function (t){ return -(Math.pow((t - 1), 4) - 1) }, // 指数变化 加减速 easeInOutExpo: function (t){ if (t === 0) return 0; if (t === 1) return 1; if ((t /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (t - 1)); return 0.5 * (-Math.pow(2, -10 * --t) + 2); }, //指数式减速 easeOutExpo: function (t){ return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; }, // 先回弹,再加速 swingFrom: function (t){ return t * t * ((BACK_CONST + 1) * t - BACK_CONST); }, // 多走一段,再慢慢的回弹 swingTo: function (t){ return (t -= 1) * t * ((BACK_CONST + 1) * t + BACK_CONST) + 1; }, //弹跳 bounce: function (t){ var s = 7.5625, r; if (t < (1 / 2.75)){ r = s * t * t; }else if (t < (2 / 2.75)){ r = s * (t -= (1.5 / 2.75)) * t + .75; }else if (t < (2.5 / 2.75)){ r = s * (t -= (2.25 / 2.75)) * t + .9375; }else{ r = s * (t -= (2.625 / 2.75)) * t + .984375; } return r; } }; function MyAnimator(duration, ease, callBack){ this.duration = duration; this.ease = ease; this.callBack = callBack; } MyAnimator.prototype = { start: function (){ var startTime = new Date(); var that = this; requestAnimationFrame(function step(){ var p = Math.min(1, (new Date() - startTime) / that.duration) var e = that.ease(p); that.callBack(e); if (p < 1){ requestAnimationFrame(step) } }) } }
-
- css3_transfrom属性
转换, 变换
- 可以改变位置(平移),旋转, 扭曲, 缩放
- 它的属性值,是一些css函数
特点
-
位置还在原来的地方,仅仅是它的样式在移动,用它去做一些动画,效率会比从前更改left | top定位之后更高的多
-
变换的时候,总是相对于它没有添加这个属性的位置来变换
-
不管任何的变换,它都会有一个参考的变换点,默认都是元素的几何中心。可以通过transform-origin来更改参考点
p { width: 100px; height: 100px; background-color: gray; position: absolute; left: 50%; /*相对于父容器的宽度的50%*/ top: 50%; /*相对于父容器的宽度的50%*/ transform: translate(-50%, -50%); /*参照与自己的宽度50%*/ } div{ width: 100px; height: 100px; background-color: pink; margin: 20px; } .box1{ background-color: gray; transform-origin: 200px 0; transform: rotate(-10deg); /*让元素顺时针旋转 45°*/ }
-
使用自定义动画
<script> var box = document.querySelector("div"); var animator = new MyAnimator({ direction : "normal", durations: [1000, 2000, 1000, 2000], eases: [Easing.linear, Easing.bounce, Easing.easeBoth, Easing.bounce], callBacks: [function (e){ box.style.transform = "translate(" + 1000 * e + "px,0)" }, function (e){ box.style.transform = "translate(1000px," + 600 * e + "px)" }, function (e){ box.style.transform = "translate(" + 1000 * (1 - e) + "px,600px)" }, function (e){ box.style.transform = "translate(0px," + 600 * (1 - e) + "px)" }] }) animator.start("2"); /*执行动画序列*/ function MyAnimator(opts){ this.opts = opts; } MyAnimator.prototype = { start: function (count){ if (count == undefined || count == null || count <= 0) count = 1; var durations = this.opts.durations, eases = this.opts.eases, callBacks = this.opts.callBacks, direction = this.opts.direction; var startTime = new Date(), self = this, index = 0; // 表示正在执行的动画的索引 var i = 0; requestAnimationFrame(function step(){ var p = Math.min(1, (new Date() - startTime) / durations[index]); /*self.callBacks[index](self.eases[index](p));*/ var e = eases[index](p); if (i % 2 == 1 && direction == "reverse"){ e = 1 - e; } callBacks[index](e); if (p == 1){ // fun fun fun index++; if (index < callBacks.length){ startTime = new Date(); requestAnimationFrame(step); }else{ count--; i++; if (count > 0){ index = 0; // 如果完成了一次, 下一次继续从序列中第 0 个继续执行 startTime = new Date(); if (direction == "reverse"){ durations.reverse(); eases.reverse(); callBacks.reverse(); } requestAnimationFrame(step) } } }else{ requestAnimationFrame(step); } }) } }
网友评论