整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JavaScript 鼠标坐标和盒子位置

JavaScript 鼠标坐标和盒子位置

标位置

当我们给某一个盒子添加鼠标事件监听时(click、mouseover、mouseenter、mouseout等事件), 都一定会有以下四组值:

event.pageX event.pageY

event.screenX event.screenY

event.clientX event.clientY

event.offsetX event.offsetY

event.pageY 表示鼠标指针, 到页面顶端的距离。IE6、7、8不兼容

event.screenY 表示鼠标指针, 到屏幕顶端的距离

event.clientY 表示鼠标指针, 到视口顶端的距离(视口就是当前可视窗口)

event.offsetY 表示鼠标指针, 到盒子顶端的距离

规律:

1、当页面没有卷动的时候, pageY一定等价于clientY。或换句话说pageY等价于clientY+页面卷动的值scrollTop。

2、IE678不兼容pageX、pageY

offsetX/Y指的不是距离你监听的那个盒子左上角的距离, 而是指的你现在鼠标指针所在位置到此时最内层盒子左上角的距离。

getBoundingClientRect 用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。

event.getBoundingClientRect().left;

具体区别:

event.pageX event.pageY

event.screenX event.screenY

event.clientX event.clientY

event.offsetX event.offsetY

图解: https://www.cnblogs.com/Abner5/p/5855274.html?utm_source=itdadao&utm_medium=referral

event.getBoundingClientRect()

图解: https://www.cnblogs.com/Songyc/p/4458570.html

实例: 鼠标点击特效

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
/*cursor: none;*/
}
img{
width: 100px;
position: absolute;
left: 0;
top: 0;

}
</style>

</head>
<body>
<script type="text/javascript">
var body=document.getElementsByTagName("body")[0];
//如果想点击body那么body必须设置宽高
document.onclick=function(e){
var ev=e || window.event;//事件对象的兼容

var left=ev.clientX;
var top=ev.clientY;

var img=document.createElement("img");
img.setAttribute("src","img/eagle.png");
img.style.left=left + "px";
img.style.top=top + "px";

body.appendChild(img);

//因为拖拽图片图片有一种神奇的魔力 也就是我们所有的默认行为
if(ev.preventDefault){
ev.preventDefault();
}else{
ev.returnValue=false;
}
}
</script>
</body>
</html>

盒子位置

任何一个元素都有offsetParent属性和offsetLeft、offsetTop属性

对象.offsetParent获得定位祖先元素, 一层一层往上找, 如果不存在就是body和绝对定位类似

对象.offsetLeft获取到定位父元素距离左边的值, 一层一层往上找, 如果不存在就是body

对象.offsetTop获取到定位父元素距离上边的值, 一层一层往上找, 如果不存在就是body

offsetWidth 盒子的宽度

offsetHeight 盒子的高度

document.documentElement.clientWidth 文档的宽度

document.documentElement.clientHeight 文档的高度

//可视区域宽高

//console.log(document.body.clientWidth);//个别浏览器

//console.log(document.documentElement.clientWidth);//高版本

var w=document.documentElement.clientWidth || document.body.clientWidth;

var h=document.documentElement.clientHeight || document.body.clientHeight;

实例1:获取行内样式的宽度和高度

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 600px;
height: 300px;
background-color: red;
}
</style>

</head>
<body>
<div></div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
console.log(div.style.width);//操作的都是行内

//不兼容
//高版本
console.log(window.getComputedStyle(div).width)
//低版本
console.log(div.currentStyle.width)
</script>
</body>
</html>
实例2: 获取盒子的宽度和高度
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 600px;
height: 300px;
background-color: red;
}
</style>

</head>
<body>
<div></div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];

//盒子宽高 number类型
console.log(div.offsetWidth)
console.log(div.offsetHeight)

</script>
</body>
</html>

实例3: 获取盒子的位置

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 600px;
height: 300px;
background-color: red;
margin: 50px;
padding: 50px;
position: relative;
}
span{
width: 100px;
height: 100px;
display: block;
background-color: orange;
}
</style>

</head>
<body>
<div>
<span></span>
</div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
var span=document.getElementsByTagName("span")[0];

//盒子距离定位父元素(div)的位置
console.log(span.offsetLeft)
console.log(span.offsetTop)

</script>
</body>
</html>

实例4: 获取盒子的净位置

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 600px;
height: 300px;
background-color: red;
margin: 50px;
padding: 50px;
position: relative;
}
span{
width: 500px;
height: 88px;
display: block;
background-color: orange;
}
</style>

</head>
<body>
<div>
<span></span>
</div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
var span=document.getElementsByTagName("span")[0];

//我们在懒加载的时候就用到过净位置
//http://jquery.cuishifeng.cn/offset.html

//净位置就是盒子到body的位置
//console.log(span.offsetTop)
console.log(span.offsetParent);//定位复原素(div)

//他返回一个信息集合
console.log(span.getBoundingClientRect());//这个东西就可以得到span的所有位置关系

//top和left值就是我们所需要的净位置
//我们知道我们无法直接获取该盒子到body的位置 但是我们我们可以获取该合资距离他有定位祖先元素的位置 那么这样我们就可以一层一层网上找
/*body
div(定位)
span

span.offsetTop ->sapn.offsetParent
div.offsetTop*/
</script>
</body>
</html>

实例5 编写净位置函数

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 600px;
height: 300px;
background-color: red;
margin: 50px;
padding: 50px;
/*position: relative;*/
}
span{
width: 500px;
height: 88px;
display: block;
background-color: orange;
}
</style>
</head>
<body>
<div>
<span></span>
</div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
var span=document.getElementsByTagName("span")[0];

//方法一: 编写自定义函数
console.log(pos(span)); //100

function pos(obj){
//用一个变量存储盒子到页面的初始值
var left=obj.offsetLeft;
//因为定位父盒子不确定 所以用一个变量临时存储 后面替换
var par=obj.offsetParent;
while(par){
left +=par.offsetLeft;
par=par.offsetParent;
}
return left;
}

//方法二: getBoundingClientRect里面包含了到页面的left top值
console.log(span.getBoundingClientRect().left) //100
</script>
</body>
</html>

拖拽三大事件

鼠标按下onmousedown

鼠标移动onmousemove

鼠标抬起onmouseup

实例: 鼠标拖拽

<!DOCTYPE html>
<html lang="zh">
<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 type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 200px;
height: 200px;
cursor: move;
background-color: orange;
/*元素如果可以拖拽他必定是定位元素*/
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div>
今天我们学习了拖拽 感觉老是讲的就是一坨翔
</div>

<p>onmouseup</p>
<script type="text/javascript">
//拖拽三大事件
//鼠标按下onmousedown
//鼠标移动onmousemove
//鼠标抬起onmouseup

//获取元素
var div=document.getElementsByTagName("div")[0];

div.onmousedown=function(e){
var ev=e || window.event;
//我按下时把鼠标到盒子的位置求出来
var startX=ev.offsetX;
var startY=ev.offsetY;
//div.onmousemove=function(e){//因为我们向左上角移动那么盒子就不跟着我跑了
document.onmousemove=function(e){
var ev=e || window.event;
//你移动鼠标那么盒子跟着你跑
console.log(ev.clientX,ev.offsetX)

console.log(ev.clientX - ev.offsetX)
console.log(ev.clientY - ev.offsetY)


//鼠标移动的位置就是鼠标到可视区的位置-一开始鼠标按下的位置
div.style.left=ev.clientX - startX + "px";
div.style.top=ev.clientY - startY + "px";


//div.style.left=ev.clientX + "px";
//div.style.top=ev.clientY + "px";
}
//我们习惯把抬起也放入按下里面
document.onmouseup=function(){
document.onmousemove=null;//我抬起鼠标之后不想让他再跟着我跑了
//所以就直接解除绑定
document.onmouseup=null;
}


//如果拖拽图片或者文字那么此时拖拽失效 所以我们需要清除默认行为
/*if(ev.preventDefault){
ev.preventDefault()
}else{
ev.returnValue=false;
}*/
return false;//如果使用它必须放到最后
}






//基本上很完美了
</script>
</body>
</html>
实例: 鼠标拖拽--防止拖出页面
<!DOCTYPE html>
<html lang="zh">
<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 type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 200px;
height: 200px;
cursor: move;
background-color: orange;
/*元素如果可以拖拽他必定是定位元素*/
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div>
今天我们学习了拖拽 感觉老是讲的就是一坨翔
</div>

<p>onmouseup</p>
<script type="text/javascript">
//拖拽三大事件
//鼠标按下onmousedown
//鼠标移动onmousemove
//鼠标抬起onmouseup

//获取元素
var div=document.getElementsByTagName("div")[0];

div.onmousedown=function(e){
var ev=e || window.event;
//我按下时把鼠标到盒子(div)的位置求出来
var startX=ev.offsetX;
var startY=ev.offsetY;
//div.onmousemove=function(e){//因为我们向左上角移动那么盒子就不跟着我跑了
document.onmousemove=function(e){
var ev=e || window.event;
//你移动鼠标那么盒子跟着你跑
console.log(ev.clientX,ev.offsetX)

console.log(ev.clientX - ev.offsetX)
console.log(ev.clientY - ev.offsetY)

var lDis=ev.clientX - startX;
var rDis=ev.clientY - startY;

if(rDis < 0){
rDis=0;
}
if(lDis < 0){
lDis=0;
}

if(lDis > document.documentElement.clientWidth-div.offsetWidth){
lDis=document.documentElement.clientWidth-div.offsetWidth;
}

if(rDis > document.documentElement.clientHeight-div.offsetHeight){
rDis=document.documentElement.clientHeight-div.offsetHeight;
}

//鼠标移动的位置就是鼠标到可视区的位置-一开始鼠标按下的位置
div.style.left=lDis + "px";
div.style.top=rDis + "px";


//div.style.left=ev.clientX + "px";
//div.style.top=ev.clientY + "px";
}
//我们习惯把抬起也放入按下里面
document.onmouseup=function(){
document.onmousemove=null;//我抬起鼠标之后不想让他再跟着我跑了
//所以就直接解除绑定
document.onmouseup=null;
}


//如果拖拽图片或者文字那么此时拖拽失效 所以我们需要清除默认行为
/*if(ev.preventDefault){
ev.preventDefault()
}else{
ev.returnValue=false;
}*/
return false;//如果使用它必须放到最后
}

//基本上很完美了
</script>
</body>
</html>

特别注意:

因为图片、文字选中是也会被拖拽, 这是一种默认行为, 所以在鼠标按下时, 我们需要清除这种默认行为。

)CSS 标准盒子模型(Box Model)

在网页中所有HTML元素可以看作盒子,在CSS中,"box model"术语是用来设计和布局时使用的;CSS盒模型本质上是一个盒子,封装周围的HTML元素包括:外边距(margin)边框(border)内边距(padding)实际内容(content)四个属性,所以布局时每个元素所占的总宽高是这4个属性的总和;比如宽度:总元素的宽度=宽度+左填充+右填充+左边框+右边框+左边距+右边距

1.1Margin(外边距)清除边框外的区域,外边距是透明的

1.2Border(边框)围绕在内边距和内容外的边框

1.3Padding(内边距)清除内容周围的区域,内边距是透明的

1.4Content(内容)盒子里填充的内容比如文本,图像等

标准盒子模型

宽度为100px的div

根据盒子模型得出该元素的总宽度为:100+(20+20)+(15+15)+(15+15)(由里至外)因此如果想在此div中放置一个宽度为100px的元素,此元素的总宽度必须小于等于100px

2)DIV+CSS布局

Div+CSS布局就是将网页内容用<div>分割为块,之后使用css设置每个块的大小,位置等

DIV+CSS布局最重要的是灵活运用float(浮动)属性,其值:1)left 2)right 3)both

clear属性作用是清除浮动,其值为:1)left 2)right 3)both

d2向右浮动 float:right

因为div是块级元素,如果都没有脱离文档流div就会按照从上到下的顺序放置

d2设置为右浮动其他两个div位置的变化:

1)d1没有脱离文档流会占据一行,所以d2只能浮动到d1下面的右面如上图所示

2)d2脱离文档流,d3自动填充到d2的位置

d1,d2全部设置为右浮动

1)当d1,d2都设置为右浮动时:因为css中d1在d2上面先设置,因此d1在右侧,如果d2在d1上面先设置样式,则d2在右侧,d1在左侧,自己测试不再截图

2)当d1,d2都设置为右浮动时:d3就会跑到上图中d2的位置

3)如果3个div都设置左或右浮动,当3个width加一起<=100%就会在第一行显示(d1,d2,d3)

 <style type="text/css">
      #d1 {
      margin: 0px;
      background-color: red;
      padding: 0px;
      width: 50%;
      height: 100px;
      float:right; 
    }
    #d2 {
      margin: 0px;
      background-color: yellow;
      padding: 0px;
      width: 50%;
      height: 100px;
      float:right; 
    }
    #d3 {
      margin: 0px;
      background-color: green;
      padding: 0px;
      width: 50%;
      height: 100px;
    }
  </style>

d2清除左浮动,d3设置为右浮动

当d2清除了左浮动,d3设置为右浮动,就会如上图所示;如果d2清除的是右浮动,d2就会在d1上面,d3就会定位在d1下面的右面,自己测试不再截图

当d2清除了左浮动,如果想要d2紧挨着d1(与d1在一行上),可以通过position脱离文档流设置其上下左右属性使其定位在d1右侧,自己测试

<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>div+CSS布局</title>
  <style type="text/css">
      #d1 {
      margin: 0px;
      background-color: red;
      padding: 0px;
      width: 30%;
      height: 100px;
      float:left; 
    }
    #d2 {
      margin: 0px;
      background-color: yellow;
      padding: 0px;
      width: 40%;
      height: 100px;
      clear: left;     
    }
    #d3 {
      margin: 0px;
      background-color: green;
      padding: 0px;
      width: 30%;
      height: 100px; 
      float: right; 
    }
  </style>
</head>
<body>
    <div id="d1"><span style="font-size: 50px;">d1</span></div>
    <div id="d2"><span style="font-size: 50px;">d2</span></div>
    <div id="d3"><span style="font-size: 50px;">d3</span></div>
  </body>
</html>

DIV+CSS布局综合运用position+上下左右属性与float属性为网页进行布局

注意:浏览器的兼容性问题,特别是使用IE内核的浏览器对W3C的规范不怎么遵守


个网页前端是由HTML DOM与嵌套组合形成视图结加上 CSS 样式的修饰形成视图,由JavaScript 接受用户的交互请求,以事件机制来响应用户交互操作而形成的。CSS是前台页面形式最重要的部分,它负责控制DOM元素的页面布局和颜色、大小的属性。

在CSS中有一著名的盒子模型理论,可以用它来控制DOM的位置。基于div+css技术的“盒子模型”的出现大大代替了传统的table表格嵌套。

虽然其十分好用,但是对于很多新手来说,却很难搞清楚它几个属性和内容之间的联系个区别。

盒子模型概念

所有页面的元素都可以看做一个盒子,占据着一定的页面空间。一般来说这些被占据的空间往往会比单纯的内容要大。因此,可以通过盒子的边框和距离等参数来控制内容的位置。

Div+CSS 盒子模型

说明:

1、Margin:中文叫外边距,主要作用是控制边框外(Border以外)的区域,外边距是透明的

2、Border:中文叫边框,是围绕在内边距(Padding)和内容外的边框。注意,它不是透明的

3、Padding:中文叫内边距,控制内容周围的区域,内边距是透明的

4、Content:内容,盒子的内容,显示文本和图像。

5、在Css文件中设置的Div的Css.width和Css. height就是内容的宽和高。

6、盒子实际尺寸有可能大于内容尺寸:

盒子模型的总宽度等于content(宽)+padding(左右)+border(左右)+margin(左右);

盒子模型的总高度等于content(高)+padding(上下)+border(上下)+margin(上下);

实例演示--原始样式

接下来通过实例演示的方式来一一讲解Margin、Border、Padding的作用和区别。

页面如图所示:


原始样式

代码:

HTML:
<body>
    <div class="TsetUpper"></div>
    <div class="TsetMiddle"></div>
    <div class="TsetDown"></div>
</body>
CSS:
.TsetUpper{
	width: 400px;
	height: 200px;
	background-color: black;
	position: relative;
	margin: auto;
	text-align: center;
}
.TsetMiddle{
	width: 600px;
	height: 200px;
	background-color: red;
	position: relative;
	margin: auto;
}
.TsetDown{
	width: 400px;
	height: 200px;
	background-color: black;
	position: relative;
	margin: auto;
	text-align: center;
}

Border

元素边框:我们可以在CSS边框属性中设置元素边框的样式和颜色。

按如下代码设置Div(TsetMiddle)的Border(边框):

border-style:solid;
border-width: 10px;
border-color: aqua;

刷新页面如下图:此时TsetMiddle这个盒子的总宽度已经变成200+30+30了,而且可以设置其底色和线条样式。

Border

Margin

margin 控制周围的元素区域。margin 没有背景颜色,是完全透明的。通过margin可以控制元素与四周元素的空隙距离;

按如下代码设置Div(TsetMiddle)的margin(外边距):

margin: 30px auto;

刷新页面如下图:此时TsetMiddle这个盒子的总宽度已经变成200+30(Border)+30(Margin)+30(Border)+30(Margin)了。

Margin

Padding

Padding:当元素的 padding(填充)内边距被清除时,所释放的区域将会受到元素背景颜色的填充。

按如下代码设置Div(TsetMiddle)的margin(外边距):

padding: 30px;

刷新页面如下图:此时TsetMiddle这个盒子的总宽度已经变成200+30(Padding)+30(Border)+30(Margin)+30(Padding)+30(Border)+30(Margin)了。

Padding

总结

1、各属性的值可以用px为单位,也可以用em,百分比等。

2、可以利用盒子的各种属性,调整其内容在父容器中的位置。