JS三大系列
- 三大家族(offset/scroll/client)
- 事件对象 (event)
(事件被触动时,鼠标和键盘的状态)
(通过属性控制)
offset家族
目的: js中有一套方便的获取元素尺寸的办法就是offset家族;
offsetWidth、offsetHeight
得到对象的宽度和高度(自己的,与他人无关)
offsetWidth = width + border + padding
div { width:220px; border-left:2px solid red; padding:10px;}
div.offsetWidth = 220 + 2 + 20
为什么不用 div.style.width
,因为div.style.width
只能得到行内式中设置的宽高的数值
offsetLeft、offsetTop
返回距离上级盒子(最近的带有定位)左边的位置
- 如果父级都没有定位则以body 为准
这里的父级指的是所有上级节点, 不仅仅指的是父亲, 还可以是 爷爷 曾爷爷 曾曾爷爷。。。。 - offsetLeft 从父亲的padding 开始算 父亲的border 不算
**总结一下: ** 就是子盒子到定位的父盒子边框到边框的距离
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css">
.gradeFater{
width: 300px;
height: 300px;
background-color: #ccc;
}
.fater{
/*position: relative;*/
width: 200px;
height: 200px;
background-color: yellow;
padding: 10px;
border: 1px solid #cccccc;
}
.son{
width: 100px;
height: 100px;
background-color: pink;
}
</style>
<script type="text/javascript">
window.onload = function () {
var son = document.getElementById("son");
//没有定位时,打印8,相对于body
//当在gradeFater上添加position: relative;打印11
//当在fater上添加position: relative;打印10
console.log(son.offsetTop);
}
</script>
</head>
<body>
<div class="gradeFater">
<div class="fater">
<div class="son" id="son"></div>
</div>
</div>
</body>
</html>
例:筋斗云
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>筋斗云</title>
<style type="text/css">
body{
background-color: #000;
}
body,ul,li{
margin: 0;
padding: 0;
}
ul,li{
list-style: none;
}
a{
text-decoration: none;
color: #333;
}
.nav{
width: 880px;
height: 42px;
margin: 100px auto;
border-radius: 5px;
background: url("images/rss.png") no-repeat right center #fff;
position: relative;
}
.cloud{
position: absolute;
width: 83px;
height: 42px;
background: url("images/cloud.gif") no-repeat left;
left: 0;
top: 0;
}
.nav ul{
position: absolute;
left: 0;
top: 0;
}
.nav ul li{
float: left;
width: 83px;
height: 42px;
line-height: 42px;
/*background-color: #fff;*/
/*margin-left: 8px;*/
text-align: center;
}
.nav a{
font-size: 14px;
color: #000;
}
</style>
<script type="text/javascript">
window.onload = function () {
var nav = document.getElementById("nav");
var cloud = nav.children[0];
var lis = nav.children[1].children;
var leader = 0,target = 0;
var current = 0;
for(var i=0 ; i<lis.length ; i++){
var li = lis[i];
li.index = i;
li.onmouseover = function () {
//老做法,但是当li的宽度改变就出问题了,所以使用offSetLeft
// target = this.index*83;
target = this.offsetLeft;
}
li.onmouseout = function () {
target = current;
}
li.onclick = function () {
current = this.offsetLeft;
}
}
function AnimationPlay(){
leader = leader + (target - leader)/20;
cloud.style.left = leader+"px";
}
setInterval(AnimationPlay,10);
}
</script>
</head>
<body>
<div class="nav" id="nav">
<div class="cloud">
</div>
<ul>
<li><a href="#">首页新闻</a></li>
<li><a href="#">师资力量</a></li>
<li><a href="#">活动策划</a></li>
<li><a href="#">企业文化</a></li>
<li><a href="#">招聘信息</a></li>
<li><a href="#">公司简介</a></li>
<li><a href="#">上海校区</a></li>
</ul>
</div>
</body>
</html
offsetParent
返回改对象的父级 (带有定位)
- 如果当前元素的父级元素没有进行CSS定位 (
position为absolute或relative,fixed
),offsetParent
为body
。 - 如果当前元素的父级元素中有CSS定位(
position为absolute或relative,fixed
),offsetParent
取最近的那个父级元素。 -
与parentNode的区别:
parentNode
是返回直接父亲元素,offsetParent
是返回有定位的父级元素
offsetTop、style.top 的区别
一、最大区别在于 offsetTop 可以返回没有定位的盒子距离顶部的位置。 而 style.top
不可以
只有定位的盒子,才有 style.left
、style.top
、style.right
、style.bottom
二、offsetTop
返回的是数字,而 style.top
返回的是字符串,除了数字外还带有单位:px
。
三、offsetTop
只读,而 style.top
可读写。
四、如果没有给 HTML 元素指定过 top 样式,则style.top
返回的是空字符串。style.top
只能返回行内样式设置的top距离
五、最重要的区别, style.top
只能返回行内样式设置的top距离,offsetLeft
随便
事件对象
我们学过一些事件 : onmouseover onmouseout onclick .....
、btn.onclick = function(event) { 语句 }
event 单词翻译过来 事件 的意思 。event
就是事件的对象,指向的是事件是 onclick
在触发DOM上的某个事件时,会产生一个事件对象event
,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event
对象,但支持的方式不同。比如鼠标操作时候,会添加鼠标位置的相关信息到事件对象中。
普通浏览器支持 event
, IE 6、7、8 支持 window.event
,所以我们 采取兼容性的写法 :
var event = event || window.event;
event 常见属性
|属性| 作用|
|::|::|
|data| 返回拖拽对象的URL字符串(dragDrop)|
|width| 该窗口或框架的高度|
|height| 该窗口或框架的高度|
|pageX| 光标相对于该网页的水平位置(IE6、7、8无)|
|pageY| 光标相对于该网页的垂直位置(IE6、7、8无)|
|screenX| 光标相对于该屏幕的水平位置|
|screenY| 光标相对于该屏幕的垂直位置|
|target| 该事件被传送到的对象|
|type| 事件的类型|
|clientX| 光标相对于该网页的水平位置 (当前可见区域)|
|clientY| 光标相对于该网页的水平位置|
pageX 、clientX 、screenX 区别
-
screenX
是以我们的电脑屏幕 为基准点 测量 -
pageX
是以我们的文档(类似绝对定位) 的基准点 对齐,IE6、7、8 不认识 -
clientX
以可视区域为基准点 ,类似于固定定位 - 当出现垂直滚动条,滚动条不在最上边时,
pageY
和clientY
值是不一样的
例:点击跟随鼠标
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#image{
width: 80px;
position: absolute;
left: 0;
top: 0;
}
</style>
<script type="text/javascript">
window.onload = function () {
var img = document.getElementById("image");
var leaderX=0,leaderY=0,targetX=0,targetY=0;
document.onclick = function (event) {
var event = event||window.event;
targetX=event.clientX-img.offsetWidth/2;
targetY=event.clientY-img.offsetHeight/2;
}
setInterval(function () {
leaderX = leaderX+(targetX-leaderX)/10;
leaderY = leaderY+(targetY-leaderY)/10;
img.style.left = leaderX+"px";
img.style.top = leaderY+"px";
},20);
}
</script>
</head>
<body>
![](images/img.jpg)
</body>
</html>
盒子内的坐标
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css">
div{
width: 500px;
height: 500px;
background-color: pink;
margin-left: 100px;
margin-top: 56px;
}
</style>
<script type="text/javascript">
window.onload = function () {
var div = document.getElementsByTagName("div")[0];
div.onmousemove = function (event) {
var event = event||window.event;
var x = event.clientX - this.offsetLeft;
var y = event.clientY - this.offsetTop;
this.innerHTML = x+"px"+"<br>"+y+"px";
// console.dir(event.screenY);
}
}
</script>
</head>
<body>
<div class="box">
</div>
</body>
</html>
例:淘宝商品图片放大的效果
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>taobao放大镜</title>
<style type="text/css">
.box{
position: relative;
width: 350px;
height: 350px;
/*padding: 10px;*/
border: 1px solid #ccc;
/*margin: 100px auto;*/
}
img{
display: block;
}
.big{
position: absolute;
width: 450px;
height: 450px;
top: 0;
left: 355px;
border: 1px solid #ccc;
overflow: hidden;
display: none;
}
.mask{
position: absolute;
width: 188px;
height: 188px;
/*background-color: rgba(255,255,255,.2);*/
left: 0;
top: 0;
background: url("images/mask.png");
display: none;
cursor: move;
}
.big img{
position: absolute;
left: 0;
top: 0;
}
</style>
<script type="text/javascript">
window.onload = function () {
var tb = document.getElementById("taobao");
var small = tb.children[0];
var big = tb.children[1];
var mask = small.children[1];
var bigImg = big.children[0];
small.onmouseover = function () {
big.style.display = "block";
mask.style.display = "block";
}
small.onmouseout = function () {
big.style.display = "none";
mask.style.display = "none";
}
small.onmousemove = function (event) {
var event = event||window.event;
var x = event.clientX - this.offsetParent.offsetLeft - mask.offsetWidth/2;
var y = event.clientY - this.offsetParent.offsetTop - mask.offsetHeight/2;
//边界检测
x = x<=0?0:x;
y = y<=0?0:y;
var maxWidth = small.offsetWidth-mask.offsetWidth;
var maxHeight = small.offsetHeight-mask.offsetHeight;//2是2个px的边框
x = x>=maxWidth?maxWidth:x;
y = y>=maxHeight?maxHeight:y;
mask.style.left = x+"px";
mask.style.top = y+"px";
//计算大盒子与小盒子的比率scale
//在小盒子中每移动1px,那么在大盒子中移动scale*1px;
//大图的宽高为800
var scale = 800/small.offsetWidth;
bigImg.style.left = -x*scale+"px";
bigImg.style.top = -y*scale+"px";
}
}
</script>
</head>
<body>
<div class="box" id="taobao">
<div class="small">
![](images/001.jpg)
<div class="mask"></div>
</div>
<div class="big">
![](images/0001.jpg)
</div>
</div>
</body>
</html>
常用事件
onmouseover onmouseout onclick
-
onmousemove
当鼠标移动的时候就是说,鼠标移动一像素就会执行的事件
div.onmousemove = function() { 语句 }
当鼠标再div 身上移动的时候,就会执行。
div.onmouseover
和div.onmousemove
区别
他们相同点都是经过 div 才会触发
div.onmouseover
只触发一次
div.onmousemove
每移动一像素,就会触发一次onmouseup
当鼠标弹起onmousedown
当鼠标按下
拖动
- 拖动原理 == 鼠标按下 接着 移动鼠标 。
bar.onmousedown = function(){
document.onmousemove = function(){
}
}
- 当我们按下鼠标的时候,就要记录当前 鼠标 的位置 - 大盒子的位置
算出 bar 当前 在 大盒子内的距离 。
例:可拖拽的进度条
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.scroll{
width: 400px;
height: 8px;
background-color: #ccc;
margin: 100px auto;
position: relative;
}
.bar{
width: 10px;
height: 20px;
background-color: #369;
position: absolute;
left: 0;
top: -6px;
cursor: pointer;
}
.mask{
width: 10px;
height: 8px;
background-color: #369;
}
</style>
<script type="text/javascript">
window.onload = function () {
var scroll = document.getElementById("scroll");
var bar = scroll.children[0];
var mask = scroll.children[1];
var msg = document.getElementById("msg");
var that = null;
bar.onmousedown = function (event) {
var event = event||window.event;
that = this;
var leftVal = event.clientX-this.offsetLeft;
document.onmousemove = function (event) {
var event = event||window.event;
var lVal = event.clientX - leftVal;
if(lVal<0){
lVal = 0;
}else if(lVal>=scroll.offsetWidth-10){
lVal = scroll.offsetWidth-10;
}
that.style.left = lVal+"px";
mask.style.width = lVal+"px";
msg.innerHTML = "当前进度:"+parseInt(lVal/(scroll.offsetWidth-10)*100)+"%";
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
}
}
document.onmouseup = function () {
document.onmousemove = null;
}
}
</script>
</head>
<body>
<div class="scroll" id="scroll">
<div class="bar"></div>
<div class="mask"></div>
</div>
<span id="msg"></span>
</body>
</html>
防止选择拖动
我们知道 按下鼠标然后拖拽可以选择文字的。
清除选中的内容 ,
正常浏览器:window.getSelection().removeAllRanges()
;
IE6、7、8:document.selection.empty();
兼容所有浏览器的写法:
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
例:可拖拽的弹出框
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding:0;
height: 42px;
}
a{
text-decoration: none;
}
.nav{
background-color: #036663;
}
.nav a{
margin-left: 24px;
line-height: 42px;
color: #fff;
}
.d-box{
width: 400px;
height: 300px;
border: 5px solid #eeeeee;
box-shadow: 2px 2px 2px 2px #999;
position: absolute;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -150px;
display: none;
}
.b-title{
width: 100%;
height: 25px;
background-color: #7c9299;
color: #fff;
line-height: 25px;
cursor: move;
}
.b-title a{
float: right;
color: #ffffff;
}
</style>
<script type="text/javascript">
window.onload = function () {
function $(id){return document.getElementById(id);}
var con_box = $("con-alert");
var close = con_box.getElementsByTagName("a")[0];
$("m-alert").onclick = function () {
con_box.style.display = "block";
}
close.onclick = function () {
con_box.style.display = "none";
}
function startDrag(current,move){
current.onmousedown = function (event) {
var event = event||window.event;
var x = event.clientX - move.offsetLeft - move.offsetWidth/2;
var y = event.clientY - move.offsetTop - move.offsetHeight/2;
document.onmousemove = function (event) {
var event = event||window.event;
var left = event.clientX - x;
var top = event.clientY - y;
move.style.left = left+"px";
move.style.top = top+"px";
window.getSelection?window.getSelection().removeAllRanges():document.selection.empty();
}
}
document.onmouseup = function () {
document.onmousemove = null;
}
}
startDrag(con_box.children[0],con_box);
}
</script>
</head>
<body>
<div class="nav">
<a href="javascript:;" id="m-alert">注册信息</a>
</div>
<div class="d-box" id="con-alert">
<div class="b-title">注册信息 (可以拖拽)
<a href="javascript:;">【关闭】</a>
</div>
<div class="d-con">
</div>
</div>
</body>
</html>
例:歌词控件,自定义滚动条
滚动条的高度: 容器的高度 / 内容的高度 * 容器的高度
滚动的比率:(内容盒子高度 - 大盒子高度) / (大盒子高度 - 滚动条的高度)
内容的盒子定位top值:(内容盒子高度 - 大盒子高度) / (大盒子高度 - 滚动条的高度) * 滚动条移动的数值
完整代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.box{
width: 250px;
height: 500px;
margin: 100px auto;
background-color: #eee;
position: relative;
overflow: hidden;
}
.content{
padding: 5px 20px 5px 5px;
/*background-color: pink;*/
text-align: center;
position: absolute;
left: 0;
top: 0;
}
.scroll{
width: 20px;
height: 100%;
position: absolute;
background-color: #ccc;
top: 0;
right: 0;
}
.bar{
width: 100%;
height: 10%;
background-color: #999;
border-radius: 10px;
position: absolute;
left: 0;
top: 0;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 计算滚动条的长度
// 内容越多,滚动条越短
function $(id){return document.getElementById(id);}
var box = $("box");
var content = box.children[0];
var scroll = $("scroll");
var bar = scroll.children[0];
var h = box.offsetHeight*box.offsetHeight/content.offsetHeight;
bar.style.height = h+"px";
bar.onmousedown = function (event) {
var event = event||window.event;
var t = event.clientY - this.offsetTop;
document.onmousemove = function (event) {
var event = event||window.event;
var y = event.clientY - t;
//上下边界检测
y = y<0?0:y;
var maxH = scroll.offsetHeight - bar.offsetHeight;
y = y>maxH?maxH:y;
bar.style.top = y+"px";
window.getSelection?window.getSelection().removeAllRanges():document.selection.empty();
//内容的位移比率
var scale = (content.offsetHeight - box.offsetHeight)/maxH;
var content_top = scale*y;
content.style.top = -content_top+"px";
}
}
document.onmouseup = function () {
document.onmousemove = null;
}
}
</script>
</head>
<body>
<div class="box" id="box">
<div class="content" id="content">
看透爱情看透你 (粤语版)<br>
作曲:陈炜<br>
填词:杨语莲<br>
演唱:杨语莲<br>
歌词千寻:www.lrcgc.com<br>
从未奢望真心可永久<br>
只得放任无言退后<br>
谁说分手仍然是朋友<br>
迷茫梦境苦痛你知否<br>
可叹心死倾出我所有<br>
强装镇定默默眼泪流<br>
流水记忆早已经远走<br>
断肠消瘦问这生何求<br>
无情的世界无情的走<br>
无聊爱情早已经看透<br>
寻寻觅觅又添许多愁<br>
怀着千般失落茫然中跌坐<br>
无情的世界无情的酒<br>
饮下这杯爱情无言的诅咒<br>
忘掉了你忘记曾一起<br>
看透爱情也看透了你<br>
可叹心死倾出我所有<br>
强装镇定默默眼泪流<br>
流水记忆早已经远走<br>
断肠消瘦问这生何求<br>
无情的世界无情的走<br>
无聊爱情早已经看透<br>
寻寻觅觅又添许多愁<br>
怀着千般失落茫然中跌坐<br>
无情的世界无情的酒<br>
饮下这杯爱情无言的诅咒<br>
忘掉了你忘记曾一起<br>
看透爱情也看透了你<br>
无情的世界无情的走<br>
无聊爱情早已经看透<br>
寻寻觅觅又添许多愁<br>
怀着千般失落茫然中跌坐<br>
无情的世界无情的酒<br>
饮下这杯爱情无言的诅咒<br>
忘掉了你忘记曾一起<br>
看透爱情也看透了你<br>
<br><br>
奔跑吧兄弟<br>
作词:谭春梅/张佳彤<br>
作曲:张佳彤<br>
演唱:谭春梅<br>
监制混缩:李程<br>
发行:天歌数字音乐传媒<br>
当我孤独寂寞的时候<br>
是你让我快乐无忧<br>
当我徘徊无助的时候<br>
是你伸出温暖的双手<br>
当我病痛降临的时侯<br>
是你日夜在为我操劳<br>
当我痛苦难过的时候<br>
是你为我种下幸福之花<br>
奔跑奔跑吧兄弟<br>
我会一直在你的左右<br>
奔跑奔跑吧兄弟<br>
握紧你的拳头一直往前走<br>
奔跑奔跑吧兄弟<br>
我们有福同享有难一起扛<br>
奔跑奔跑吧兄弟<br>
你永远是我们心中的骄傲<br>
奔跑奔跑吧兄弟<br>
幸福之花将开满你我心头<br>
奔跑奔跑吧兄弟<br>
为了我们同一个梦想而努力奋斗<br>
当我孤独寂寞的时候<br>
是你让我快乐无忧<br>
当我徘徊无助的时候<br>
是你伸出温暖的双手<br>
当我病痛降临的时候<br>
是你日夜在为我操劳<br>
当我痛苦难过的时候<br>
是你为我种下幸福之花<br>
奔跑奔跑吧兄弟<br>
我会一直在你的左右<br>
奔跑奔跑吧兄弟<br>
握紧你的拳头一直往前走<br>
奔跑奔跑吧兄弟<br>
我们有福同享有难一起扛<br>
奔跑奔跑吧兄弟<br>
你永远是我们心中的骄傲<br>
奔跑奔跑吧兄弟<br>
幸福之花将开满你我心头<br>
奔跑奔跑吧兄弟<br>
为了我们同一个梦想而努力奋斗<br>
奔跑奔跑吧兄弟<br>
我会一直在你的左右<br>
奔跑奔跑吧兄弟<br>
握紧你的拳头一直往前走<br>
奔跑奔跑吧兄弟<br>
我们有福同享有难一起扛<br>
奔跑奔跑吧兄弟<br>
你永远是我们心中的骄傲<br>
奔跑奔跑吧兄弟<br>
幸福之花将开满你我心头<br>
奔跑奔跑吧兄弟<br>
为了我们同一个梦想而努力奋斗<br>
为了我们同一个梦想而努力奋斗
</div>
<div class="scroll" id="scroll">
<div class="bar"></div>
</div>
</div>
</body>
</html>