简介
在我们日常开发中偶尔会碰到获取元素样式、设置某元素样式、计算元素位置、计算滚动距离等需求。但是js中关于元素位置、样式、大小的api种类繁多,稍不留神就会搞不清楚。今天笔者就带你彻底弄清楚,让你在这类问题上不再迷茫。
本文分元素样式的获取和设置、元素位置大小计算、屏幕和窗口位置大小计算三部分来讲解,读完本文你将会学会
- 元素样式的获取的各种方法以及区别,在哪种情况是使用哪种方式最合适。
- 元素大小位置计算,弄懂了
client、scroll、offset三类api的区别。 screen、window对象关于位置、大小api,以及各自的区别。
元素样式的获取和设置
el.style、getComputedStyle 用来获取和设置元素样式。el.className、el.classList 用来获取和设置元素类名。el.getBoundingClientRect用来获取元素的位置和大小。
el.style
通过获取元素的style属性来获取元素样式。
语法
<head>
<style>
.div1 {
color: red;
}
</style>
</head>
<div id="div1" class="div1" style="font-size: 18px">style测试</div>
const div1 = document.querySelector("#div1");
console.log(div1.style.fontSize); // 18px
console.log(div1.style.color); // 获取不到该样式
特点
- 这种方式获取的样式属性值是驼峰式。
- 这种方式只能获取到元素的内联样式。
- 我们可以通过该方法设置元素样式。
常用方法
cssText
我们还可以使用cssText来获取样式的字符串。
console.log(div1.style.cssText); // font-size: 18px;
setProperty
我们可以使用setProperty方法来设置元素样式。
注意我们设置元素样式的属性不是驼峰式写法。
div1.style.setProperty("font-weight", 600);
console.log(div1.style.fontWeight); // 600
// 当然这种方式也是可以的
div1.style.fontWeight = 600;
console.log(div1.style.fontWeight); // 600
getPropertyValue
我们可以使用getPropertyValue方法来获取元素样式。
注意我们获取元素样式的属性不是驼峰式写法。
div1.style.getPropertyValue("font-size"); // 18px
// 当然这种方式也是可以的
console.log(div1.style.fontSize)
removeProperty
我们可以使用removeProperty方法来移除元素某样式。
div1.style.removeProperty("font-weight");
// 当然这种方式也是可以的
div1.style.fontWeight = "";
getComputedStyle(ele)
该方法挂载在window对象下,我们使用的时候可以省略window。
语法
<head>
<style>
.div1 {
color: red;
}
</style>
</head>
<div id="div1" class="div1" style="font-size: 18px">style测试</div>
const div1 = document.querySelector("#div1");
console.log(getComputedStyle(div1).fontSize); // 18px
console.log(getComputedStyle(div1).color); // rgb(255, 0, 0)
特点
- 这种方式获取的样式属性值是驼峰式。
- 能获取元素渲染后的所有样式包括内联和不内联样式。
- 只能获取元素的样式不能设置元素的样式。
el.getBoundingClientRect()
该方法能获取元素的长度和宽度(width、height)。并且能获取元素相对于浏览器窗口的位置信息(left、right、top、bottom)。
语法
<head>
<style>
.div1 {
color: red;
}
</style>
</head>
<div id="div1" class="div1" style="font-size: 18px">style测试</div>
这里需要注意的是,距离计算只相对窗口顶部和左边计算。(bottom、right的计算需要注意)
const div1 = document.querySelector("#div1");
// bottom: 33 元素下边框距离视口顶部的距离
// height: 25 元素高度
// left: 8 元素左边框距离视口左部的距离
// right: 342 元素右边框距离视口左部的距离
// top: 8 元素上边框距离视口顶部的距离
// width: 334 元素的宽度
// x: 8 元素左上角相对于视口左侧的距离
// y: 8 元素左上角相对于视口顶部的距离
console.log(div1.getBoundingClientRect());
特点
- 该方法只能获取元素位置和大小信息,不能获取到其他样式信息。
- 该方法不能设置元素样式。
el.className、el.classList
除了前面介绍的获取样式,我们还可以获取到类名,然后通过添加类名的方式给元素添加新的样式。
语法
console.log(div1.classList.value); // div1
console.log(div1.className); // div1
div1.className += " div2"; // 添加新类名 div2
特点
el.className获取的是元素的类名字符串,我们可以使用该方法获取类名或者添加新的类名。el.classList.value获取的是类名字符串,如果单纯的想获取类名可以使用该方法。
总结
- 当我们需要设置某元素样式的时候我们可以使用
ele.style方法。 - 当我们需要获取元素渲染后的所有样式的时候我们可以使用
getComputedStyle(ele)方法。 - 当我们需要获取类名或者批量设置元素样式的时候可以使用
className方法。 - 当我们需要计算元素位置,或者计算元素是否在可视窗口内或者元素大小的时候我们可以使用
ele.getBoundingClientRect()方法。
有了上面获取元素样式的基础下面我们再来介绍一些元素位置、大小的api
元素位置、大小计算
关于元素位置大小计算主要有client、scroll、offset三类api。
client
client可以简单理解为元素可视大小。
clientWidth、clientHeight
clientWidth 为可视宽度,宽度包含内边距(padding)。不包含边框(border)、外边距(margin)、滚动条。
clientHeight 为可视高度,高度包含内边距(padding)。不包含边框(border)、外边距(margin)、滚动条。
clientTop、clientLeft
clientTop获取的是元素上边框的高度。
clientLeft获取的是元素左边框的宽度。
参看上面的例子
clientWidth为400px - 滚动条15px + 左右内边距20 = 405pxclientHeight为200px - 滚动条15px + 上下内边距20 = 205pxclientTop为上边框高度10pxclientLeft为左边框宽度10px
scroll
scroll可以简单理解为元素实际大小(可滚动大小)。
scrollWidth、scrollHeight
scrollWidth当元素没滚动条的时候和clientWidth一样,为可视宽度。当有滚动条的时候为可滚动的宽度。宽度包含内边距(padding)和滚动条。不包含边框(border)、外边距(margin)。
scrollHeight当元素没滚动条的时候和clientHeight一样,为可视高度。当有滚动条的时候为可滚动的高度。高度包含内边距(padding)和滚动条。不包含边框(border)、外边距(margin)。
scrollTop、scrollLeft
scrollTop获取的是容器元素在y轴上滚动的距离。
scrollLeft获取的是容器元素在x轴上滚动的距离。
参看上面的例子,我们在这里使用了box1.scrollBy(20, 10);模拟滚动。
scrollWidth为600px + 左右内边距20 = 620pxscrollHeight为500px + 上下内边距20 = 520pxclientTop为在y轴上滚动的距离10pxclientLeft为在x轴上滚动的近距离20px
offset
offset可以简单理解为元素占据大小(在文档中的占据空间大小)。
offsetWidth、offsetHeight
offsetWidth 宽度包含内边距(padding)、边框(border)、滚动条。不包含外边距(margin)。
offsetHeight 高度包含内边距(padding)、边框(border)、滚动条。不包含外边距(margin)。
offsetParent
offsetParent是一个只读属性,获得元素最近并采用定位的祖先元素或者最近的 table, td, th元素,再没找到就获取body元素,用于offsetLeft和offsetTop的计算。
offsetLeft、offseTop
offsetLeft相对offsetParent水平偏移距离。
offseTop相对offsetParent垂直偏移距离。
参看上面的例子
offsetWidth为400px - 滚动条15px + 滚动条15px + 左右内边距20 + 左右边框宽度20px = 440pxoffsetHeight为200px - 滚动条15px + 滚动条15px + 上下内边距20 + 上下边框宽度20px = 240pxoffsetParent因为外面没包裹其他元素,所以直接返回body元素。offsetTop因为margin为20px所以相对于body垂直偏移距离为20pxoffsetLeft因为margin为20px所以相对于body水平偏移距离为20px
屏幕和窗口位置、大小计算
screen
屏幕相关属性的获取。
width、height
这里 screen.width、screen.height获取的是电脑屏幕的宽度和高度,跟我们浏览器大小是无关的。
availWidth、availHeight
这里 screen.availWidth、screen.availHeight获取的是电脑屏幕的实际宽度和实际高度,如果有任务栏是需要去掉的。跟我们浏览器大小是无关的。
window
浏览器窗口相关属性的获取。
outerWidth、outerHeight
outerWidth返回的是浏览器整个的宽度,如果浏览器最大化的话和screen.availWidth值相等。
outerHeight返回的是浏览器整个的高度,如果浏览器最大化的话和screen.availHeight值相等。
innerWidth、innerHeight
innerWidth返回的是浏览器文档可视的宽度,只包括滚动条,不包括顶部的tab、和书签栏。
innerHeight返回的是浏览器文档可视的高度,只包括滚动条,不包括顶部的tab、和书签栏。
screenX、screenLeft
window.screenX、window.screenLeft获取的是浏览器窗口左上角相对于屏幕左边框的距离。
ie不支持window.screenX火狐不支持window.screenLeft
screenY、screenTop
window.screenY、window.screenTop获取的是浏览器窗口左上角相对于屏幕上边框的距离。
ie不支持window.screenY火狐不支持window.screenTop
scrollX、scrollY
window.scrollX返回的是窗口在x轴上滚动的距离。
window.scrollY返回的是窗口在y轴上滚动的距离。
pageXOffset、pageYOffset
window.pageXOffset返回的是窗口在x轴上滚动的距离。
window.pageYOffset返回的是窗口在y轴上滚动的距离。
注意:
这里
scrollX、scrollY、pageXOffset、pageYOffset需要和上面的scrollTop、scrollLeft区分,这四个api只在window对象上有。
相对于
scrollX、scrollY,pageXOffset、pageYOffset兼容性更好,一般我们只用pageXOffset、pageYOffset就行了。但两者都不兼容IE9以下。
事件对象Event中的screenX、clientX、pageX、layerX、offsetX
事件对象中通常有screenX、clientX、pageX、layerX、offsetX这几个对象,他们都代表着什么意思,以及他们之间的差别我相信很多小伙伴还不是很清楚,所以今天笔者再来总结一下。
我们这里先准备父子两个元素,父元素有边框10px,内边距20px,宽高200px。子元素有边框20px,内边距30px,宽高100px。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>offsetX、clientX、screenX、pageX、layerX</title>
<style>
.div1 {
width: 200px;
height: 200px;
border: grey solid 10px;
padding: 20px;
background-color: aqua;
position: relative;
// margin-top: 200px; //演示浏览器滚动条时打开
}
.div2 {
width: 100px;
height: 100px;
padding: 30px;
border: forestgreen solid 20px;
background-color: blanchedalmond;
}
</style>
</head>
<body>
<div class="div1" onclick="handleClick(event)">
<div class="div2">点</div>
</div>
<script>
const handleClick = (e) => {
console.log(e);
console.log("screenX: ", e.screenX);
console.log("screenY: ", e.screenY);
console.log("clientX: ", e.clientX);
console.log("clientY: ", e.clientY);
console.log("pageX: ", e.pageX);
console.log("pageY: ", e.pageY);
console.log("offsetX: ", e.offsetX);
console.log("offsetY: ", e.offsetY);
console.log("layerX: ", e.layerX);
console.log("layerY: ", e.layerY);
};
</script>
</body>
</html>
父子盒子样式如下
下面正式进入正题
screenX、screenY
screenX、screenY是我们鼠标位置相对电脑屏幕左上角x轴和y轴的距离。
假设笔者鼠标点击的是点的位置,那么它的screenX、screenY就是笔者画红框的长度和宽度。它是根据屏幕计算的,跟浏览器大小无关。
clientX、clientY
clientX、clientY是我们鼠标位置相对浏览器可视窗口x轴和y轴的距离。
假设笔者鼠标点击的是点的位置,那么它的clientX、clientY就是笔者画红框的长度和宽度。它是根据浏览器计算的。
它是根据可视窗口计算的,也就是会除掉浏览器书签栏、导航栏的大小。
绿色框框是clientX、clientY,红色框框是screenX、screenY。
因为笔者演示的时候浏览器是全屏,所以screenX是等于clientX的,因为浏览器顶部有书签栏、导航栏所以screenY是大于clientY。
pageX、pageY
pageX、pageY是我们鼠标位置相对浏览器文档对象,x轴和y轴的距离。
怎么理解这句话呢?其实我们跟clientX、clientY对比就很容易理解了。
在没有出现滚动条的时候,其实可视窗口就等于文档对象的大小,所以pageX、pageY是和clientX、clientY相等的。
我们来先看一个没有出现滚动条的例子,
可以看到 pageX、pageY和 clientX、clientY 大小是一样的,都是红色框框的大小。
当页面出现滚动条的时候,两者才会有差异,因为一个是相对浏览器可视窗口,一个是相对document文档对象。
我们再来看一个有滚动条的例子,
可以看到,当y轴出现滚动条的时候,clientY和pageY的大小就有区别了。
clientY是相对可视窗口计算的,所以是绿色框框的大小,pageY是相对文档对象 document计算的,所以它在绿色框框的基础上加上滚动条滚动的距离。大概就是红色框框的大小。
看到这,小伙伴们应该明白了吧,一个是相对浏览器可视窗口,一个是相对文档对象 document(页面大小)计算。
offsetX、offsetY
offsetX、offsetY是相对元素自身padding-box左上角的位置计算的。
我们点击下点的位置,看看offsetX、offsetY是多少。
可以看到,大小就是自身内边距的大小,它是相对自身padding-box左上角计算的,是不包括边框的。
当我们点击绿色边框,可以看到它出现了负值。
这里一定要注意它是相对自身padding-box左上角计算的。
layerX、layerY
layerX、layerY是相对带定位的父元素border-box左上角的位置计算的。如果没有带定位的父元素那么就是相对文档对象计算。
我们点击下点的位置,看看layerX、layerY是多少。
可以看到,大小就是自身内边距30 + 自身边框20 + 父元素内边距20 + 父元素边框 10(大概是80),它是相对父元素border-box左上角的位置计算的。注意带上父元素边框的距离。
总结:
screenX、screenY很好理解,是相对屏幕计算。clientX、clientY和pageX、pageY我们对比就很容易理解,一个是相可视窗口左上角,一个是相对文档左上角。offsetX、offsetY和layerX、layerY我们也是通过对比理解,一个是相对自身padding-box左上角,一个是相对父元素padding-box左上角计算的。
后记
感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!