iv cssz-index層重疊順序
div層、span層等html標簽層重疊順序樣式z-index,平時CSS使用較少,但也會難免會碰到CSS z-index使用。
從基礎語法到應用案例教程講解學習z-index。
z-index 跟具體數字
div{
z-index:100
}
注意:z-index的數值不跟單位。
z-index的數字越高越靠前,并且值必須為整數和正數(正數的整數)。
z-index在使用絕對定位 position:absolute屬性條件下使用才能使用。通常CSS讓不同的對象盒子以不同順序重疊排列,CSS就是要z-index樣式屬性。
為了方便觀察,設置3個DIV盒子,分別設置不同css背景顏色,設置相同CSS高度、CSS寬度。分別設置背景顏色)為黑色、紅色、藍色。CSS width為300px,css height為100px。
css代碼(沒加z-index屬性)
<style>
.div css5 {
position: relative;
}
.div css5-1,
.div css5-2,
.div css5-3 {
width: 300px;
height: 100px;
position: absolute;
}
.divcss5-1 {
background: #000;/* 黑色*/
left: 10px;
top: 10px
}
.divcss5-2 {
background: #F00;/* 紅色*/
left: 20px;
top: 20px
}
.divcss5-3 {
background: #00F;/* 藍色*/
left: 30px;
top: 30px
}
</style>
CSS代碼(加上z-index屬性后) :
<style>
.div css5 {
position: relative;
}
.div css5-1,
.div css5-2,
.div css5-3 {
width: 200px;
height: 100px;
position: absolute;
}
.div css5-1 {
z-index: 10;
background: #000;/* 黑色*/
left: 10px;
top: 10px
}
.div css5-2 {
z-index: 20;
background: #F00;/* 紅色*/
left: 20px;
top: 20px
}
.div css5-3 {
z-index: 15;
background: #00F;/* 藍色*/
left: 30px;
top: 30px
}
</style>
html代碼
<div class="divcss5-1"></div>
<div class="divcss5-2"></div>
<div class="divcss5-3"></div>
沒加的效果:
加上z-index屬性效果:
三個盒子均都使用了絕對定位屬性position樣式,并且設置相同的高度和寬度樣式。為了便于觀察CSS使用left、right屬性并賦予不同值,讓其錯落有致。
為可以看見第一個盒子z-index:10,所以重疊在最下層,而第二個盒子z-index:20,值最大所以最上層重疊,第三個盒子設置z-index:15,居中。
本文基于CSS基礎,介紹了如何使用z-index重疊順序樣式,在實際DIV+CSS布局時候CSS需要絕對定位樣式,并且可以使用left、right進行定位,通過不同z-index值實現層重疊順序排列。代碼很簡單,希望能夠幫助你學習。
者: IT共享者 來源: IT共享之家
div cssz-index層重疊順序
div層、span層等html標簽層重疊順序樣式z-index,平時CSS使用較少,但也會難免會碰到CSS z-index使用。
從基礎語法到應用案例教程講解學習z-index。
一、z-index語法與結構
z-index 跟具體數字
div{
z-index:100
}
注意:z-index的數值不跟單位。
z-index的數字越高越靠前,并且值必須為整數和正數(正數的整數)。
二、z-index使用條件
z-index在使用絕對定位 position:absolute屬性條件下使用才能使用。通常CSS讓不同的對象盒子以不同順序重疊排列,CSS就是要z-index樣式屬性。
三、案例
1. z-index重疊順序案例
為了方便觀察,設置3個DIV盒子,分別設置不同css背景顏色,設置相同CSS高度、CSS寬度。分別設置背景顏色)為黑色、紅色、藍色。CSS width為300px,css height為100px。
css代碼(沒加z-index屬性)
<style>
.div css5 {
position: relative;
}
.div css5-1,
.div css5-2,
.div css5-3 {
width: 300px;
height: 100px;
position: absolute;
}
.divcss5-1 {
background: #000;/* 黑色*/
left: 10px;
top: 10px
}
.divcss5-2 {
background: #F00;/* 紅色*/
left: 20px;
top: 20px
}
.divcss5-3 {
background: #00F;/* 藍色*/
left: 30px;
top: 30px
}
</style>
CSS代碼(加上z-index屬性后) :
<style>
.div css5 {
position: relative;
}
.div css5-1,
.div css5-2,
.div css5-3 {
width: 200px;
height: 100px;
position: absolute;
}
.div css5-1 {
z-index: 10;
background: #000;/* 黑色*/
left: 10px;
top: 10px
}
.div css5-2 {
z-index: 20;
background: #F00;/* 紅色*/
left: 20px;
top: 20px
}
.div css5-3 {
z-index: 15;
background: #00F;/* 藍色*/
left: 30px;
top: 30px
}
</style>
html代碼
<div class="divcss5-1"></div>
<div class="divcss5-2"></div>
<div class="divcss5-3"></div>
沒加的效果:
加上z-index屬性效果:
2. 案例說明
三個盒子均都使用了絕對定位屬性position樣式,并且設置相同的高度和寬度樣式。為了便于觀察CSS使用left、right屬性并賦予不同值,讓其錯落有致。
為可以看見第一個盒子z-index:10,所以重疊在最下層,而第二個盒子z-index:20,值最大所以最上層重疊,第三個盒子設置z-index:15,居中。
四、總結
本文基于CSS基礎,介紹了如何使用z-index重疊順序樣式,在實際DIV+CSS布局時候CSS需要絕對定位樣式,并且可以使用left、right進行定位,通過不同z-index值實現層重疊順序排列。代碼很簡單,希望能夠幫助你學習。
內容是《Web前端開發之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學習。
文檔坐標和視口坐標:
元素的位置是以像素來度量的,向右代表x坐標的增加,向下代表y坐標的增加;但是,有兩個不同的點作為坐標系的原點:元素的x和y坐標可以相對于文檔的左上角或者相對于視口的左上角,也就是對于一個元素來說,會有兩種坐標:文檔坐標和視口坐標;視口坐標也被稱為窗口坐標;
在頂級窗口或標簽頁中,視口只是實際顯示文檔內容的瀏覽器的一部分,它不包括瀏覽器其他組件,如菜單、工具條等;
對于在框架中顯示的文檔,視口是定義了框架頁的<iframe>元素;
元素大小:
以下的屬性和方法不屬于DOM2級樣式規范,但卻與HTML元素的樣式息息相關;IE率先引用了一些屬性,目前,所有主流的瀏覽器都支持以下屬性;
1. 偏移量(offset dimension):
包括元素在屏幕上占用的所有可見的空間;元素的可見大小包括寬高,所有內邊距,滾動條和邊框的大小(不包括外邊距);
通過以下4個屬性可以取得元素的偏移量:
偏移量(offset dimension)
var mydiv = document.getElementById("mydiv");
console.log(mydiv.offsetWidth);
console.log(mydiv.offsetHeight);
console.log(mydiv.offsetLeft);
console.log(mydiv.offsetTop);
offsetLeft和offsetTop返回值與包含元素有關,對于有些元素,這些值是文檔坐標,但對于已定位元素的后代元素和一些其他元素(如表格單元格),這些屬性返回的坐標是相對于祖先元素而不是文檔;
offsetParent屬性:包含元素的引用,也就是相對的父元素;offsetParent不一定與parentNode的值相等;如:<td>元素的offsetParent是作為其祖先元素的<table>元素,因為<table>是在DOM層次中距<td>最近的一個具有大小的元素;
如果其offsetParent屬性為null,以上的屬性都是文檔坐標;
console.log(mydiv.offsetParent);
如果要想知道某個元素在頁面上的偏移量,將這個元素的offsetLeft和offsetTop與其offsetParent的相同屬性相加,如此循環直至根元素,就可以得到一個基本準確的值;
<style>
*{margin: 0; padding: 0;}
ul,li{list-style: none;}
#container{width: 500px; height:100px; position: absolute;left:50px;top:100px;border:10px solid;background-color: blue;}
#content{width: 400px; height:50px; position: relative; padding-left: 50px;background-color: red; }
#myul{width: 300px; position: relative; background-color: purple;}
#myli{width: 200px; margin-left:20px; background-color: pink;}
</style>
<body>
<div id="container">
<div id="content">
<ul id="myul">
<li id="myli">零點程序員</li>
</ul>
</div>
</div>
<script>
var myli = document.getElementById("myli");
console.log(myli.offsetWidth);
console.log(myli.offsetLeft);
console.log(myli.offsetParent);
var myul = document.getElementById("myul");
console.log(myul.offsetWidth);
console.log(myul.offsetLeft);
console.log(myul.offsetParent);
var content = document.getElementById("content");
console.log(content.offsetWidth);
console.log(content.offsetLeft);
console.log(content.offsetParent);
var container = document.getElementById("container");
console.log(container.offsetWidth);
console.log(container.offsetLeft);
console.log(container.offsetParent);
// 定義一個函數
function getElementPosition(element){
var x = 0, y = 0;
while(element != null){
x += element.offsetLeft;
y += element.offsetTop;
element = element.offsetParent;
}
return {x:x, y:y};
}
var content = document.getElementById("content");
console.log(getElementPosition(content).x);
console.log(getElementPosition(content).y);
var myli = document.getElementById("myli");
console.log(getElementPosition(myli).x);
console.log(getElementPosition(myli).y);
</script>
但實際上這個函數返回的值是不正確的,因為沒有包括邊框的寬度;
既然offsetWidth和offsetHeight是包括border的寬度的,所以有些地方也把它稱為物理寬度,它的值就是該元素實際的尺寸,因此,這并不一定等于元素的width和height,只有元素的CSS設置了box-sizing:border-box時才相等;
對于一個元素來說,它的實際的寬高也并不一定等于它的內容的寬和高,也就是在擁有滾動條的情況下,如:
<style>
#mydiv{width: 300px; height: 100px;border: 1px solid; overflow: scroll;}
</style>
<div id="mydiv">Lorem more...</div>
<script>
var mydiv = document.getElementById("mydiv");
console.log(mydiv.offsetWidth); // 302
console.log(mydiv.offsetHeight); // 102
console.log(mydiv.scrollWidth); // 283
console.log(mydiv.scrollHeight); // 483
</script>
另外,這兩個屬性值也不包含元素的:before或:after等偽類的寬和高;
<style>
#mydiv{width: 300px; height: 100px;border: 1px solid;}
#mydiv::after{content: "web前端開發"; display: block; margin-top:100px;}
</style>
<div id="mydiv"></div>
<script>
var mydiv = document.getElementById("mydiv");
console.log(mydiv.offsetWidth); // 302
console.log(mydiv.offsetHeight); // 102
</script>
如果該元素的display:none,各屬性返回0,offsetParent返回null;
如果該元素的position為static或fixed,其offsetParent為null,此時返回的各個屬性值就是文檔坐標;
對于行盒元素(如 span),offsetTop和offsetLeft描述的是第一個邊界框的位置,offsetWidth和 offsetHeight描述的是邊界框的尺寸;因此,使用offsetLeft、offsetTop、offsetWidth、offsetHeight來對應left、top、width和height 的一個盒子將不會是文本容器 span 的盒子邊界;如:
<div style="width: 300px; border:1px solid blue;">
<span style="background-color: purple;">span element</span>
<span id="long">Lorem ... text more...</span>
</div>
<div id="box" style="position: absolute; border: 1px solid red; z-index: 10"></div>
<script>
var box = document.getElementById("box");
var long = document.getElementById("long");
box.style.left = long.offsetLeft + "px";
box.style.top = long.offsetTop + "px";
box.style.width = long.offsetWidth + "px";
box.style.height = long.offsetHeight + "px";
</script>
所有這些偏移量屬性都是只讀的,且每次訪問它們都需要重新計算;因此,應該盡量避免重復訪問這些屬性;如果要使用,可以將它們保存在局部變量中,以提高性能;
myul.offsetLeft = 20;
console.log(myul.offsetLeft); // 50 靜默失敗
2.客戶區大小(client dimension):
指的是元素內容及其內邊距所占據的空間大小,相關屬性為:clientTop、clientLeft、clientWidth和clientHeight;
客戶區大小(client dimension)
客戶區大小就是元素內部的空間大小,其與offsetWidth和offsetHeight類似,只不過不包含邊框大小;也不包括滾動條占用的空間;
clientWidth = CSS width + CSS padding - 水平滾動條寬度 – CSS border(如果width不包括border的話);
clientHeight = CSS height + CSS padding - 水平滾動條高度 – CSS border(如果height不包括border的話);
var mydiv = document.getElementById("mydiv");
console.log(mydiv.clientWidth);
console.log(mydiv.clientHeight);
注意,它不是元素內容實際的尺寸,而是元素內部可見區域的大小;并且是不包括滾動條的,如:
<style>
#mydiv{width: 300px; height: 100px;padding: ;border: 1px solid; overflow: scroll;}
</style>
<div id="mydiv">Lorem more...</div>
<script>
var mydiv = document.getElementById("mydiv");
console.log(mydiv.offsetWidth); // 302
console.log(mydiv.offsetHeight); // 102
console.log(mydiv.clientWidth); // 300
console.log(mydiv.clientHeight); // 100
console.log(mydiv.scrollWidth); // 300
console.log(mydiv.scrollHeight); // 147
注意:對于行盒,如<i>、<code>或<span>等,包括塊盒被設置了display:block后,clientWidth和clientHeight總是返回0;
當元素的display:none時,返回的也是0;
var span = document.getElementsByTagName("span")[0];
console.log(span.clientWidth); // 0
console.log(span.clientHeight); // 0
最典型的應用就是之前講到的獲得瀏覽器視口大小,如:
function getViewPort(){
if(document.compatMode == "BackCompat"){
return{
width:document.body.clientWidth,
height:document.body.clientHeight
};
}else{
return {
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
};
}
}
有一個特例:在文檔的根元素上使用這些屬性時,它們的返回值和窗口的innerWidth和innerHeight屬性值相等;但如果有滾動條的話,innerWidth和innerHeight包括滾動條占用空間的值;
console.log(document.documentElement.clientWidth, document.documentElement.clientHeight);
console.log(window.innerWidth, window.innerHeight);
獲得瀏覽器視口大小:
function getViewportSize(w){
// 使用指定的窗口,如果不帶參數則使用當前窗口
w = w || window;
if(w.innerWidth != null) return {w: w.innerWidth, h: w.innerHeight};
var d = w.document;
if(document.compatMode == "CSS1Compat")
return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight};
// 怪異模式
return {w: d.body.clientWidth, h: d.body.clientHeight};
}
console.log(getViewportSize().h);
與偏移量相似,這兩個屬性該也為只讀,并且每次訪問都要重新計算;
clientTop屬性和clientLeft屬性:可以返回元素的上邊框和左邊框的大小,其值為一個整數,沒有單位,并且是只讀的;
var mydiv = document.getElementById("mydiv");
console.log(mydiv.clientTop); // 1
console.log(mydiv.clientLeft); // 1
其和getComputedStyle ()方法的borderTopWidth屬性存在一定的區別;
var mydiv = document.getElementById("mydiv");
console.log(mydiv.clientTop); // 12
console.log(getComputedStyle(mydiv,null).borderTopWidth); // 11.5px
可見,clientTop和clientLeft返回的是整數并且沒有單位,而borderTopWidth返回的是mydiv的上邊框的厚度,是精確的;兩者之間的關系是:
mydiv.clientTop = Math.round(parseFloat(getComputedStyle(mydiv,null).borderTopWidth));
但firefox是向下取整;
如果元素有滾動條,并且將這些滾動條放在左側或頂部,clientLeft和clientTop也就包含了滾動條的寬度;
對于行盒元素來說,clientLeft和clientTop值總是為0;當元素的display:none時,返回的也是0;
3.滾動大小(scroll dimension):
指的是包含滾動內容的元素大小;
有些元素(如<html>),即使沒有執行任何代碼也能自動地添加滾動條;但另外一些元素,則需要通過css的overflow屬性進行設置才能滾動;
滾動相關的屬性:
滾動大小(scroll dimension)
scrollWidth和scrollHeight主要用于確定元素內容的實際大小,它們是只讀的,不包括邊框和滾動條;
也就是說,返回的是元素的內容區域加上它的內邊距再加上任何溢出內容的尺寸;
<style>
#mydiv{width: 300px;height:100px; border: 1px solid; overflow: scroll;}
</style>
<div id="mydiv">Lorem more...</div>
<script>
var mydiv = document.getElementById("mydiv");
// 283 = 300 -17(滾動條的寬), 168 = 內容實際的高
console.log(mydiv.scrollWidth, mydiv.scrollHeight);
</script>
當內容正好和內容區域匹配而沒有溢出時,這些屬性與clientWidth與clientHeight是相等的;但當溢出時,它們就包含溢出的內容,返回值比clientWidth和clientHeight要大;
// 改變文字數量,觀察兩者的區別
console.log(mydiv.scrollWidth, mydiv.scrollHeight);
console.log(mydiv.clientWidth, mydiv.clientHeight);
通常認為<html>(混雜模式下為<body>)元素是在瀏覽器視口滾動的元素,因此帶有垂直滾動條的頁面總高度就是document.documentElement.scrollHeight;
對于不包含滾動條的頁面,scrollWidth、scrollHeight和clientWidth、clientHeight之間的關系基本是相等的;
console.log(document.documentElement.scrollWidth, document.documentElement.scrollHeight);
console.log(document.documentElement.clientWidth, document.documentElement.clientHeight);
scrollWidth和scrollHeight等于文檔內容區域的大小,而clientWidth和clientHeight等于視口大小;但低版本的瀏覽器有可能結果并不一致;
在確定文檔的總高度時,必須取得scrollWidth/clientWidth和scrollheight/clientHeight中的最大值,才能保證在跨瀏覽器的環境下得到精確的結果;
var docWidth = Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth);
var docHeight = Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight);
注:對于混雜混式下,需要使用document.body
scrollLeft和scrollTop屬性:
通過這兩個屬性可以取得元素當前滾動的狀態,也就是滾動位置;它們是可寫的,即能設置元素的滾動位置;
scrollLeft 屬性可以獲取或設置一個元素的內容水平滾動的像素數;scrollTop 屬性可以獲取或設置一個元素的內容垂直滾動的像素數;
在尚未滾動時,兩值均為0;如果垂直滾動,該值大于0,且表示元素上方不可見內容的像素高度,如果水平滾動,該值大于0,且表示元素左方不可見內容的像素寬;
console.log(document.documentElement.scrollLeft);
console.log(document.documentElement.scrollTop);
示例:滾動一個元素;
<style>
#mydiv{width: 300px; height:100px; border: 2px solid; overflow: scroll hidden; white-space: nowrap;}
</style>
<div id="mydiv">Lorem, more...</div>
<button id="btn">滾</button>
<script>
var mydiv = document.getElementById("mydiv");
var btn = document.getElementById("btn");
btn.onclick = function(e){
mydiv.scrollLeft += 20;
}
</script>
將元素的這兩個屬性設置為0,就可以重置元素的滾動位置;
function scrollToTop(element){
if(element.scrollTop != 0){
element.scrollTop = 0;
}
}
// 應用
var btn = document.getElementById("btn");
btn.onclick = function(){
scrollToTop(document.documentElement);
}
判定元素是否滾動到底:如果元素滾動到底,下面等式返回true,否則返回false,如:element.scrollHeight - element.scrollTop === element.clientHeight;
var mydiv = document.getElementById("mydiv");
var timer = setInterval(scrollDiv, 100);
function scrollDiv(){
if(mydiv.scrollHeight - mydiv.scrollTop === mydiv.clientHeight)
clearInterval(timer);
else
mydiv.scrollTop += 5;
console.log("scroll");
}
檢查容器能否滾動:
// 加個判斷,條件也可以是:
// window.getComputedStyle(mydiv).overflow === 'hidden'
var timer;
if(window.getComputedStyle(mydiv).overflowY === 'scroll'){
timer = setInterval(scrollDiv, 100);
}
scrollLeft和scrollTop可以被設置為任何整數值,但有以下特點:
var mydiv = document.getElementById("mydiv");
mydiv.scrollTop = 500; // 或設為負數
console.log(mydiv.scrollTop); // 0
這兩個屬性值有可能是小數(比如縮放了頁面的顯示大小),所以在取值時最好取整,例如:Math.ceil()或Math.floor;
function getElementPos(element){
var y = 0, x = 0;
var current = element;
for(var e = element; e != null; e = e.offsetParent){
// 但是自己的邊框不能加進去
if(current == e){
x += e.offsetLeft;
y += e.offsetTop;
}else{
x += e.offsetLeft + e.clientLeft;
y += e.offsetTop + e.clientTop;
}
}
// 再次循環所有的祖先元素,減去滾動的偏移量,并轉換為視口坐標
for(var e=element.parentNode; e != null && e.nodeType == 1; e = e.parentNode){
y -= e.scrollTop;
x -= e.scrollLeft;
}
return {x:x, y:y};
}
var mydiv = document.getElementById("mydiv");
console.log(getElementPos(mydiv).x);
console.log(getElementPos(mydiv).y);
console.log(mydiv.offsetParent);
console.log(mydiv.getBoundingClientRect());
示例:返回到頂部:
var gotop = document.getElementById("gotop");
var timer;
gotop.onclick = function(){
timer = setInterval(goTop, 1);
}
function goTop(){
if(document.documentElement.scrollTop == 0)
clearInterval(timer);
else{
// document.documentElement.scrollTop-= 10;
document.documentElement.scrollTop-= document.documentElement.scrollTop / 100;
}
}
// 或者使用遞歸
gotop.onclick = goTop;
function goTop(){
console.log("a:" + document.documentElement.scrollTop);
if(document.documentElement.scrollTop == 0)
return;
document.documentElement.scrollTop -= 10;
setTimeout(goTop,1);
}
示例:判定用戶是否閱讀過文本,如:
<style>
.registration{
width: 600px; height: 200px; padding: 10px;
border: 2px solid purple; border-radius: 5px;
overflow-y: scroll;
}
</style>
<h1>同意協議</h1>
<div class="registration">
<p>Lorem more...</p>
</div>
<p>
<input type="checkbox" name="accept" id="agree" />
<label for="agree">我同意</label>
<input type="submit" id="nextstep" value="下一步" />
</p>
<script>
window.onload = function(){
var registration = document.querySelector(".registration");
var agree = document.getElementById("agree");
agree.disabled = true;
var nextstep = document.getElementById("nextstep");
nextstep.disabled = true;
var readed = false;
var noticeBox = document.createElement("h2");
noticeBox.id = "notice";
noticeBox.innerText = "請閱讀以下內容"
registration.parentNode.insertBefore(noticeBox, registration);
registration.onscroll = function(e){
if(readed) return;
readed = this.scrollHeight - this.scrollTop === this.clientHeight;
agree.disabled = nextstep.disabled = !readed;
noticeBox.innerText = readed ? "歡迎參加" : "請繼續閱讀";
}
}
</script>
示例:滾動文本,如:
<style>
*{margin: 0; padding: 0;}
#scrollBox{padding:10px;margin:100px auto;width: 300px; height: 150px; background: lightgray;overflow: hidden;}
</style>
<div id="scrollBox">
<ul id="con1">
<li>HTML</li>
<li>CSS</li>
<li>Javascript</li>
<li>更多的li</li>
<li>更多的li</li>
<li>更多的li</li>
<li>更多的li</li>
<li>更多的li</li>
</ul>
<ul id="con2"></ul>
</div>
<script>
var scrollBox = document.getElementById("scrollBox");
var con1 = document.getElementById("con1");
var con2 = document.getElementById("con2");
con2.innerHTML = con1.innerHTML;
function scrollUp(){
if(scrollBox.scrollTop >= con1.offsetHeight)
scrollBox.scrollTop = 0;
else
scrollBox.scrollTop++;
}
var timer = setInterval(scrollUp, 50);
scrollBox.onmouseover = function(){
clearInterval(timer);
};
scrollBox.onmouseout = function(){
timer = setInterval(scrollUp, 50);
}
</script>
圖示匯總各個屬性:
元素坐標、幾何尺寸
windows對象的pageXOffset、pageYOffset和scrollX、scrollY:
pageXOffset 和 pageYOffset 屬性返回文檔在窗口左上角水平和垂直方向滾動的像素;這一對屬性等于scrollX和scrollY屬性,前者是后者的別稱;但IE不支持后者;這些屬性是只讀的;
window.scrollBy(100,200);
console.log(window.pageXOffset);
console.log(window.pageYOffset);
console.log(window.scrollX);
console.log(window.scrollY);
console.log(window.pageXOffset == window.scrollX); // true
與scrollLeft和scrollTop關系:返回值是一樣的;
window.scroll(100,300);
console.log(window.pageXOffset);
console.log(window.pageYOffset);
console.log(document.documentElement.scrollLeft);
console.log(document.documentElement.scrollTop);
為了跨瀏覽器兼容性,一般使用window.pageXOffset代替window.scrollX;另外,舊版本的 IE(<9)兩個屬性都不支持,必須通過其他的非標準屬性來解決此問題;
window.scrollBy(100,200);
var x = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
var y = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
console.log(x,y);
// 或者
var isCSS1Compat = document.compatMode === "CSS1Compat";
var x = window.pageXOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft;
var y = window.pageXOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
console.log(x,y);
封裝一個函數:
// 以一個對象的x和y屬性的方式返回滾動條的偏移量
function getScrollOffset(w){
// 使用指定的窗口,如果不帶參數則使用當前窗口
w = w || window;
if(w.pageXOffset != null) return {x: w.pageXOffset, y: w.pageYOffset};
var d = w.document;
if(document.compatMode == "CSS1Compat")
return {x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop};
// 針對怪異模式
return {x: d.body.scrollLeft, y: d.body.scrollTop};
}
console.log(getScrollOffset().x);
console.log(getScrollOffset().y);
4. 確定元素大小:
瀏覽器為每個元素都提供了一個Element.getBoundingClientRect()([?ba?nd??] 邊界)方法;該方法是在IE5引入的;該方法不需要參數,返回一個矩形對象,類型為DOMRect,包含6個屬性:x、y、left、top、right、bottom、width和height;這些屬性給出了元素在頁面中相對于視口的位置和寬高;其中,x和left相同,y與top相同;right和bottom屬性表示元素的右下角的x和y坐標;
<div id="mydiv" style="width: 200px;height:100px;background-color:red; ">id is mydiv</div>
<div style="width: 2000px; background-color: purple;">div</div>
<script>
var mydiv = document.getElementById("mydiv");
var rect = mydiv.getBoundingClientRect();
console.log(rect);
rect = document.documentElement.getBoundingClientRect();
console.log(rect);
</script>
IE并沒有實現x和y;
DOMRect 中的 top, left, right, bottom 屬性是使用對象的其他屬性的值來計算獲得的;
在IE及老款的Edge中,該方法返回的并不是DOMRect類型,而是ClientRect類型;
console.log(ClientRect);
console.log(ClientRect.prototype); // [object ClientRectPrototype]
getBoundingClientRect()返回的數據是包括元素的border及padding;
<div id="mydiv" style="width: 200px;height:100px;background-color:red; border:20px solid black;">name is mydiv</div>
// …
var rect = mydiv.getBoundingClientRect();
console.log(rect);
這是標準盒子,如果是怪異盒子,比如在CSS中設置box-sizing:border-box,那么返回的數據中的寬和高就等于元素的width和height;
如果要轉化為文檔坐標,需要加上滾動的偏移量;
window.scrollBy(50,100);
var mydiv = document.getElementById("mydiv");
var rect = mydiv.getBoundingClientRect();
var x = rect.left + document.documentElement.scrollLeft;
var y = rect.top + document.documentElement.scrollTop;
// 或者使用上面定義的getScrollOffset()函數
var offsets = getScrollOffset();
var x = rect.left + offsets.x;
var y = rect.top + offsets.y;
console.log(x,y);
在布局中,文檔中的元素分為塊盒和行盒,塊盒總是為矩形,但行盒可能跨了多行,因此可能由多個矩形組成,可以把它稱為邊界矩形;
var span = document.getElementById("mydiv").getElementsByTagName("span")[0];
var rect = span.getBoundingClientRect();
console.log(rect);
在IE8及以下瀏覽器中,該方法返回的對象中并不包括width和height屬性;可以使用一個簡便的方式計算元素的width和height屬性:
var mydiv = document.getElementById("mydiv");
var rect = mydiv.getBoundingClientRect();
var w = rect.width || (rect.right - rect.left);
var h = rect.height || (rect.bottom - rect.top);
console.log(w,h);
示例:元素在頁面上的相對文檔的偏移量,如:
function getOffset(ele){
if (!ele || ele.nodeType != 1)
return;
var rect = ele.getBoundingClientRect(),
doc = ele.ownerDocument.documentElement;
return {
top: rect.top + window.pageYOffset - doc.clientTop,
left: rect.left + window.pageXOffset - doc.clientLeft
};
}
getClientRects()方法:
該方法返回一個指向客戶端中每一個盒子的邊界矩形的矩形集合;該矩形集合是一個只讀的類數組對象DOMRectList,可以稱為矩形列表對象,它的每個元素都是DOMRect對象;
var span = document.getElementsByTagName("span")[0];
var rects = span.getClientRects();
console.log(rects);
for(var i=0,len=rects.length; i<len; i++){
console.log(rects[i]);
}
當然,該方法也可以應用在塊盒中,此時它只返回包含一個元素的集合對象;
var mydiv = document.getElementById("mydiv");
console.log(mydiv.getClientRects()[0]);
在IE中返回的是ClientRectList類型,其中保存的是ClientRect類型的對象;
對于HTML area元素、自身不做任何渲染的SVG元素、display:none元素和不直接渲染出來的任何元素,都將會返回一個空列表;
小示例:
<style>
div{display: inline-block; width: 150px;}
div p,ol,table{border: 1px solid blue;}
span, li, th, td{border: 1px solid green;}
</style>
<div>
<strong>原始</strong>
<p><span>Web前端開發課程,包括HTML、CSS、Javascript等內容</span></p>
</div>
<div>
<strong>p的rect</strong>
<p class="rect"><span>Web前端開發課程,包括HTML、CSS、Javascript等內容</span></p>
</div>
<div>
<strong>span的rect</strong>
<p class="rect"><span>Web前端開發課程,包括HTML、CSS、Javascript等內容</span></p>
</div>
<hr />
<div>
<strong>原始</strong>
<ol>
<li>HTML</li>
<li>CSS</li>
</ol>
</div>
<div>
<strong>ol的rect</strong>
<ol class="rect">
<li>HTML</li>
<li>CSS</li>
</ol>
</div>
<div>
<strong>li的rect</strong>
<ol>
<li class="rect">HTML</li>
<li class="rect">CSS</li>
</ol>
</div>
<hr/>
<div>
<table>
<caption>原始</caption>
<thead><tr><th>thead</th></tr></thead>
<tbody><tr><td>tbody</td></tr></tbody>
</table>
</div>
<div>
<table class="rect">
<caption>table的rect</caption>
<thead><tr><th>thead</th></tr></thead>
<tbody><tr><td>tbody</td></tr></tbody>
</table>
</div>
<div>
<table>
<caption>td的rect</caption>
<thead><tr><th class="rect">thead</th></tr></thead>
<tbody><tr><td class="rect">tbody</td></tr></tbody>
</table>
</div>
<script>
function addClientRect(elt){
// 為了使邊框寬度與矩形寬度一致,這里給每個客戶矩形上方絕對定位一個 div。
// 注意:如果用戶改變大小或者縮放,繪圖將會重繪。
var rects = elt.getClientRects();
for(var i=0, len=rects.length; i<len; i++){
var rect = rects[i];
// console.log(rect);
var overlayDiv = document.createElement("div");
overlayDiv.className = "overlay";
overlayDiv.style.position = "absolute";
overlayDiv.style.border = "1px solid red";
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
overlayDiv.style.margin = overlayDiv.style.padding = "0";
overlayDiv.style.top = (rect.top + scrollTop) + "px";
overlayDiv.style.left = (rect.left + scrollLeft) + "px";
// 希望rect.width作為邊框寬度,所以內容寬度減少2px
overlayDiv.style.width = (rect.width - 2) + "px";
overlayDiv.style.height = (rect.height - 2) + "px";
document.body.appendChild(overlayDiv);
}
}
var elts = document.querySelectorAll(".rect");
for(var i=0,len=elts.length; i<len; i++)
addClientRect(elts[i]);
</script>
對于NodeList等對象,它們是實時的,但getBoundingClientRect()和getClientRects()所返回的矩形對象或矩形列表對象并不是實時的,它們只是調用方法時文檔視覺狀態的靜態快照,在用戶滾動或改變瀏覽器窗口大小時不會更新它們;
document.elementFromPoint()方法:如果想在指定位置上判定有什么元素,可以使用該方法;參數需要傳遞x和y坐標,不需要單位px,該坐標是視口坐標,該方法返回在指定位置的一個元素;
如果在指定位置有多個元素,它返回的是里面和最上面的(即CSS的z-index屬性),如果指定的點在視口以外,該方法返回null;
典型的案例是將鼠標指針的坐標傳遞給它來判斷鼠標在哪個元素上,但是,在鼠標事件中的target屬性也包含了這些坐標信息,所以,elementFromPoint()方法并不常用;
var div = document.createElement("div");
div.id="divone";
div.setAttribute("style","width:200px;height:100px;position:absolute;left:50px;top:200px;border:solid 5px;");
document.documentElement.appendChild(div);
var innerDiv = document.createElement("div");
innerDiv.setAttribute("style","background-color:purple; width:100px; height:50px;");
div.appendChild(innerDiv);
var elt = document.elementFromPoint(100,200);
console.log(elt);
console.log(div.getBoundingClientRect());
// 鼠標事件中的坐標
var mydiv = document.getElementById("mydiv");
document.addEventListener("click",function(e){
console.log(e.target);
console.log(e.clientX, e.clientY);
},false);
document.elementsFromPoint()方法:該方法返還在特定坐標點下的HTML元素數組;IE與老版的Edge并不支持;
var elts = document.elementsFromPoint(100,250);
console.log(elts);
滾動:
Window.scroll()、Window.scrollBy()、Window.scrollTo()及Element.scroll()、Element.scrollBy()、Element.scrollTo();
scroll(x, y)或scrollTo(x, y)方法:
var btn = document.querySelector(".btn");
btn.onclick = function(){
var documentHeight = document.documentElement.offsetHeight;
var viewportHeight = window.innerHeight;
// 滾動到最后一屏
window.scrollTo(0, documentHeight - viewportHeight);
}
scrollBy(x, y)方法:
其與以上兩個方法類似,但是它的參數是相對的,并在當前滾動的偏移量上增加
window.scrollBy(5,5);
示例,閱讀文章時自動滾屏,如:
<style>
.autoscrollbtn{width: 50px; height: 50px; background-color: purple;
position: fixed; top:100px; right: 100px; color:#FFF}
</style>
<div>lorem</div>
<div class="autoscrollbtn">滾</div>
<script>
// 3874 4531
var btn = document.querySelector(".autoscrollbtn");
var timer;
var viewportHeight = window.innerHeight;
var stop = false;
btn.addEventListener("click",function(e){
if(!stop){
e.target.innerText = "停";
timer = setInterval(function(){
if((viewportHeight + document.documentElement.scrollTop) >=
document.documentElement.offsetHeight)
clearInterval(timer);
scrollBy(0,2);
},200);
}else{
e.target.innerText = "滾";
clearInterval(timer);
}
stop = !stop;
});
</script>
以上方法,參數除了x和y坐標外,還可以是一個ScrollToOptions對象;
CSSOM View 規范的ScrollToOptions對象,用于指定一個元素應該滾動到哪里,以及滾動是否應該平滑;與我們之前講的scrollIntoView()方法的參數類似,但類型不一樣,其為ScrollIntoViewOptions,屬性為block及inline等;而ScrollToOptions對象擁有的是top、left和behavior屬性,其中behavior屬性值可能為:auto及smooth;該參數IE和Edge不支持;
如果不使用ScrollToOptions對象參數,也可以使用CSS指定,如:
html,body{
scroll-behavior:smooth;
}
但IE和Edge依然不支持;
var btn = document.getElementById("btn");
btn.addEventListener("click",function(e){
window.scroll(mydiv.offsetLeft,mydiv.offsetTop);
// 或,但IE與Edge不支持
window.scroll({left:mydiv.offsetLeft, top:mydiv.offsetTop, behavior:"smooth"});
},false);
Element.scroll()、Element.scrollBy()、Element.scrollTo();
這些方法是用于在給定的元素中滾動到某個特定坐標,其用法與window上的三個方法一致,但IE與Edge均不支持Element的方法;
<div id="mydiv" style="background-color: purple; width: 300px; height: 400px; overflow-y: scroll;">Lorem</div>
<script>
var mydiv = document.getElementById("mydiv");
mydiv.scroll(0,300);
</script>
Web前端開發之Javascript
*請認真填寫需求信息,我們會在24小時內與您取得聯系。