
谷歌浏览器中代码运行效果图
写在前面,觉得文章还可以的朋友,可以点一手关注,在前端学习路上,我与你一路前行。
原生js效果实现小球碰壁反弹效果。在谷歌浏览器中运行的,曾经一位高级程序员说过,能用js实现的,终究还是用js实现。所以原生js技能对于前端工程师特别重要。
这个小demo的重点和难点就是鼠标事件函数,和offsetHeight与offsetTop的区别于用法。如果有朋友进行优化了,还请赐教,因为这个代码还存在一些不足。
offsetHeight:它返回的高度是内容高+padding+边框,但是注意哦,木有加margin哦,当然一般也木有啥需要把margin加进去.
1、offsetLeft
假设 obj 为某个 HTML 控件。
obj.offsetTop 指 obj 距离上方或上层控件的位置,整型,单位像素。
obj.offsetLeft 指 obj 距离左方或上层控件的位置,整型,单位像素。
obj.offsetWidth 指 obj 控件自身的宽度,整型,单位像素。
obj.offsetHeight 指 obj 控件自身的高度,整型,单位像素。
我们对前面提到的“上方或上层”与“左方或上层”控件作个说明。
<div id="tool"> <input type="button" value="提交"> <input type="button" value="重置"> </div>
“提交”按钮的 offsetTop 指“提交”按钮距“tool”层上边框的距离,因为距其上边最近的是 “tool” 层的上边框。
“重置”按钮的 offsetTop 指“重置”按钮距“tool”层上边框的距离,因为距其上边最近的是 “tool” 层的上边框。
“提交”按钮的 offsetLeft 指“提交”按钮距“tool”层左边框的距离,因为距其左边最近的是 “tool” 层的左边框。
“重置”按钮的 offsetLeft 指“重置”按钮距“提交”按钮右边框的距离,因为距其左边最近的是“提交”按钮的右边框。
以上属性在 FireFox ,google中也有效。
另 外:我们这里所说的是指 HTML 控件的属性值,并不是document.body,document.body 的值在不同浏览器中有不同解释(实际上大多数环境是由于对 document.body 解释不同造成的,并不是由于对 offset 解释不同造成的)。
offsetTop 与 style.top 的区别
我们知道 offsetTop 可以获得 HTML 元素距离上方或外层元素的位置,style.top 也是可以的,二者的区别是:
一、offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。
(深坑,这个demo的主要时间就卡在这了,注意着)
二、offsetTop 只读,而 style.top 可读写。
三、如果没有给 HTML 元素指定过 top 样式,则 style.top 返回的是空字符串。
offsetLeft 与 style.left、offsetWidth 与 style.width、offsetHeight 与 style.height 也是同样道理。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { margin: 0; padding: 0; } ol, ul, li { list-style: none; } .wrap { width: 400px; height: 400px; margin: 20px auto; background: #ddd; position: relative; overflow: hidden; } .sty { width: 50px; height: 50px; background: #f00; position: absolute; left: 112px; top: 10px; } .boardDiv { width: 100px; height: 20px; position: absolute; bottom: 100px; background: #f00; cursor: pointer; border-radius: 10px; } </style> </head> <body> <div class="wrap" id='wrapId'> <div class="sty" id='styId'></div> <div class='boardDiv' id='boardId'></div> </div> <script type='text/javascript'> var doc = document; var N = 0; function gId(n) { return doc.getElementById(n); }; var _L = 5; var _T = 5; // 运动的衰减 // _T = 0.77 * _T; setInterval(function() { var el = gId('styId').offsetLeft + _L; var et = gId('styId').offsetTop + _T; N = N + 1; console.log(et); //垂直方向 if (et >= gId('wrapId').offsetHeight - gId('styId').offsetHeight) { et = gId('wrapId').offsetHeight - gId('styId').offsetHeigBht; _T = -1 * _T; _T = 0.77 * _T; } else if (et <= 0) { et = 0; _T = -1 * _T; _T = 0.77 * _T; } //水平方向 if (el >= gId('wrapId').offsetWidth - gId('styId').offsetWidth) { el = gId('wrapId').offsetWidth - gId('styId').offsetWidth; _L = -1 * _L; _L = 0.77 * _L; } else if (el <= 0) { el = 0; _L = -1 * _L; _L = 0.77 * _L; } // 先判断y轴 if (et > gId('boardId').offsetTop - 50 && et < gId('boardId').offsetTop + 20) { // 再判断x轴 if (gId('styId').offsetLeft > gId('boardId').offsetLeft - 40 && gId('styId').offsetLeft < gId('boardId').offsetLeft + 140) { _T = -1 * _T; } } gId('wrapId').onmousemove = function(e) { var el = (e.pageX - gId('wrapId').offsetLeft - 50) + 'px'; gId('boardId').style.left = el; } // 这个给元素设置 gId('styId').style.top必须是数字加px gId('styId').style.top = et++ + 'px'; gId('styId').style.left = el++ + 'px'; //清除定时器 if (N > 1000) { clearInterval; } }, 50); </script> </body> </html>