jQuery - 元素的位置與大小

寬度、高度相關

width() 與 height()

在 jQuery,width()與 height()方法回傳元素的內容區域寬度與高度,不包括內距(padding)、邊框(border),它與 box-sizing 設定值的有關係。

css(‘width’) 與 width() 在 box-sizing:content-box,兩者取的值一樣(因為都是指內容區域的寬度),差別在於 css(‘width’)是有數字的字串 ‘px’,width() 只有數字。在設定為 box-sizing:border-box 時,css(‘width’)依舊是直接取得 css 設定的 width 值(會包含 border、padding),而 width() 則必須要扣除掉 padding、border,依舊指的是取得內容區域的寬度。

設定 width(value) 與 height(value) 時,可以是 數字px%auto。如果傳入的是數字(未設定單位),視為預設以 px 為單位的尺寸大小,如果傳入的是字串值,會被用作 CSS width 或 height 屬性的值,因此可以套用任何 CSS 允許的單位,但不能設定 Window 或 Document 物件的寬度或高度,它們是唯讀

$(selector).height()
$(selector).height(value)
$(selector).height(function(index, currentValue){…})

$('.box').width() // 取得寬度
$('.box').width(100) // 設置寬度,數值表示 px
$('.box').width('50%') // 設置寬度,可使用字串

// 以下兩者不是元素,不需要考慮 padding、border
$(window).height() // 取得視窗高度
$(document).height() // 取得文件高度

// 可以使用函式
$('.box').height(function (index, currentValue) {
if (index == 1) {
return Math.random() * 1000
}
})

innerWidth() 與 innerHeight()

在 box-sizing:content-box 設定下,innerWidth() 與 innerHeight() 回傳元素的寬度或高度(內容區域的寬、高)加上它內距(padding),但不包括邊框(border),但在 box-sizing:border-box 設定下,由於 padding 已經包含在 CSS 的 width、height,因此只會取得 width、height 值,它們不允許使用在 window、document。但可以用 width()、height 來獲取。

與 JavaScript 的 clientWidth、clientHeight 屬性一樣。

$(selector).innerHeight()
$(selector).innerHeight(value)
$(selector).innerHeight(function(index,oldValue){ … })

outerWidth() 與 outerHeight()

在 box-sizing:content-box 設定下,outerWidth() 與 outerHeight() 通常回傳元素的寬度或高度,加上內距(padding)、邊框(border),但在 box-sizing:border-box 設定下,由於 padding、border 已經包含在 CSS 的 width、height,因此只會取得 width、height 值,若傳入 true 值給上面任何一個方法,它們也會將該元素外距(margin)的大小計算在內。例如 outerWidth(true),預設是 false。

與 JavaScript 的 offsetWidth、offsetHeight 屬性一樣。

元素座標

offset()

返回元素視窗左上角至該元素邊框的座標偏移距離,它只以視窗計算至元素邊框的座標偏移距離,但如果有設定 margin,需與 top、bottom、left、right 加入計算,即便內部子元素用此方法,計算方式也是從視窗開始計算。offset() 可以加入物件參數回傳這個物件的 left 與 top 屬性(存有元素 X 與 Y 的座標數字)。如果使用 top、left 屬性,它會設定所指定的位置。

const pos = $('.box').offset() // 回傳一個紀錄 top、left 屬性的物件。
console.log(pos) // {top: 10, left: 10}

$(selector).offset()
$(selector).offset().top
$(selector).offset().left
$(selector).offset( {top:value,left:value} )
$(selector).offset( funnction(index, currentPosObject){ … } )

使用函式,返回要設置的坐標的函數。接收集合中元素的索引作為第一個參數,當前坐標作為第二個參數。該函數應該返回一個具有新的 top 和 left 屬性的對象。

注意,與 JavaScript 的 offsetTop、offsetLeft 屬性不同,即便它們名字很像,JavaScript 的 offsetTop、offsetLeft 與 jQuery 的 position() 一樣,與父元素位置有相對關係。 而且它們都是唯讀屬性,無法設置。

position()

position() 可以獲取定位的偏移量(與 JavaScript 的 offsetTop、offsetLeft 相同),其用法類似 offset(),但它只能作為 getter,無法設定值,從指定元素開始往上尋找,找到第一個 position 為 relative 或 absolute 為定位來做計算,如果都沒有找到,會以視窗左上角為偏移量(沒有設定 top、bottom、left、right 偏移量,照元素正常流向的推擠也算偏移),返回物件包含兩個屬性:top 和 left,此方法只能對可見元素有效。

.position()

$('.box').position().left
$('.box').position().top

offsetParent()

獲取被定位的最近祖先元素對象,每個元素都有個 offsetParent 屬性,用來指定元素的位置是相對於誰。已定位的元素永遠都是他們子裔元素的 offsetParent,jQuery 只會把已定位的元素當作 offsetParent,而 jQuery 物件的 offsetParent()方法則會把每個元素對應至最接近它的已定位祖(ancestor)元素,或最後是 body 元素。

捲軸偏移量

scrollTop() 與 scrollLeft()

可查詢元素在捲軸(scrollbar)的偏移量,或設定元素在捲軸的偏移量(px)。可用於 Window 物件,也可用於文件元素,而在 document 上呼叫時,它會設定內含該文件的 window 的捲動軸位置,與 window 相同,兩者都可以取得整個文件的捲動值。如果用在$(‘div’)等區塊元素,則可取得內嵌捲動框的捲動值。有別於其他 setters,你不能傳入一個函式給 scrollTop()或 scrollLeft()。scrollTop()為元素距離捲軸最上方起始點的垂直偏移量,scrollLeft()為元素距離捲軸最左側起始點的水平偏移量。如果滾動條位於最頂部,或者元素不可滾動,則此數字為 0。

scrollTop()是以 viewport 最頂端為一條基準線,捲軸往下拉動 100px,則表示內容往上移動 100px。相同的概念可以應用到 JavaScript 的 pageYOffset(scrollY)。

.scrollTop()
.scrollTop(value)

$(window).on('scroll', function () {
console.log($(window).scrollTop())
})

scrollTop() 與 scrollLeft() 是用 JavaScript 的 pageXOffset、pageYOffset 實作,pageXOffset、pageYOffst是 scrollX、scrollY 的別名,在跨瀏覽器兼容,應該使用pageXOffset、pageYOffst。

捲軸捲到某位置出現

// 移動到頁尾卷軸需要的距離 = 頁尾到頂部的距離 - 視窗的高度(一開始的高度卷軸不需要移動)
let endZone = $('#footer').offset().top - $window.height()
$(window).on('scroll', function () {
// 移動到頁尾卷軸需要的距離 小於 當前捲軸移動的距離
if (endZone < $window.scrollTop()) {
console.log(`endZone:${endZone}`)
$('#ad').animate({ right: '0' }, 250)
} else {
$('#ad').stop(true).animate({ right: '-360px' }, 250)
}
})