亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一篇文章讓你徹底搞懂js中的位置計(jì)算

 更新時(shí)間:2021年09月13日 14:56:12   作者:19組清風(fēng)  
js中有各種與位置相關(guān)的屬性,每次看到的時(shí)候都各種懵逼,索性一次總結(jié)一下,這篇文章主要給大家介紹了關(guān)于js中位置計(jì)算的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

引言

文章中涉及到的api列表:

  1. scroll相關(guān)Api
  2. client相關(guān)Api
  3. offset相關(guān)Api
  4. Element.getBoundingClientRectAPi
  5. Window.getComputedStyleApi

我們會(huì)結(jié)合api定義,知名開源庫(kù)中的應(yīng)用場(chǎng)景來逐層分析這些api。足以應(yīng)對(duì)工作中關(guān)于元素位置計(jì)算的大部分場(chǎng)景。

注意在使用位置計(jì)算api時(shí)要格外的小心,不合理的使用他們可能會(huì)造成布局抖動(dòng)Layout Thrashing影響頁(yè)面渲染。

scroll

首先我們先來看看scroll相關(guān)的屬性和方法。

Element.scroll()

Element.scroll()方法是用于在給定的元素中滾動(dòng)到某個(gè)特定坐標(biāo)的Element 接口。

element.scroll(x-coord, y-coord)
element.scroll(options)
  • x-coord 是指在元素左上方區(qū)域橫軸方向上想要顯示的像素。
  • y-coord 是指在元素左上方區(qū)域縱軸方向上想要顯示的像素。

也就是element.scroll(x,y)會(huì)將元素滾動(dòng)條位置滾動(dòng)到對(duì)應(yīng)x,y的位置。

同時(shí)也支持element.scroll(options)方式調(diào)用,支持傳入額外的配置:

{
    left: number, 
    top: number,
    behavior: 'smooth' | 'auto' // 平滑滾動(dòng)還是默認(rèn)直接滾動(dòng)
}

Element.scrollHeight/scrollWidth

Element.scrollHeight 這個(gè)只讀屬性是一個(gè)元素內(nèi)容高度的度量,包括由于溢出導(dǎo)致的視圖中不可見內(nèi)容。

scrollHeight 的值等于該元素在不使用滾動(dòng)條的情況下為了適應(yīng)視口中所用內(nèi)容所需的最小高度。 沒有垂直滾動(dòng)條的情況下,scrollHeight值與元素視圖填充所有內(nèi)容所需要的最小值clientHeight相同。包括元素的padding,但不包括元素的border和margin。scrollHeight也包括 ::before 和 ::after這樣的偽元素。

換句話說Element.scrollHeight在元素不存在滾動(dòng)條的情況下是恒等于clientHeight的。
但是如果出現(xiàn)了滾動(dòng)條的話scrollHeight指的是包含元素不可以見內(nèi)容的高度,出現(xiàn)滾動(dòng)條的情況下是scrollHeight恒大于clientHeight。

  • Element.scrollWidth 這也是一個(gè)元素內(nèi)容寬度的只讀屬性,包含由于溢出導(dǎo)致視圖中不可以見的內(nèi)容。

原理上和scrollHeight是同理的,只不過這里是寬度而非高度。

簡(jiǎn)單來說一個(gè)元素如果不存在滾動(dòng)條,那么他們的scroll和client都是相等的值。如果存在了滾動(dòng)條,client只會(huì)計(jì)算出當(dāng)前元素展示出來的高度/寬度,而scroll不僅僅會(huì)計(jì)算當(dāng)前元素展示出的,還會(huì)包含當(dāng)前元素的滾動(dòng)條隱藏內(nèi)容的高度/寬度。

clientWidth/height + [滾動(dòng)條被隱藏內(nèi)容寬度/高度] = scrollWidth/Height

Element.scrollLeft/scrollTop

  • Element.scrollTop 屬性可以獲取或設(shè)置一個(gè)元素的內(nèi)容垂直滾動(dòng)的像素?cái)?shù).
  • Element.scrollLeft 屬性可以讀取或設(shè)置元素滾動(dòng)條到元素左邊的距離.

需要額外注意的是: 注意如果這個(gè)元素的內(nèi)容排列方向(direction) 是rtl (right-to-left) ,那么滾動(dòng)條會(huì)位于最右側(cè)(內(nèi)容開始處),并且scrollLeft值為0。此時(shí),當(dāng)你從右到左拖動(dòng)滾動(dòng)條時(shí),scrollLeft會(huì)從0變?yōu)樨?fù)數(shù)。

scrollLeft/Top在日常工作中是比較頻繁使用關(guān)于操作滾動(dòng)條的相關(guān)api,他們是一個(gè)可以設(shè)置的值。根據(jù)不同的值對(duì)應(yīng)可以控制滾動(dòng)條的位置。

其實(shí)這兩個(gè)屬性和上方的Element.scroll()可以達(dá)到相同的效果。

在實(shí)際工作中如果對(duì)于滾動(dòng)操作有很頻繁的需求,個(gè)人建議去使用better-scroll,它是一個(gè)移動(dòng)/web端的通用js滾動(dòng)庫(kù),內(nèi)部是基于元素transform去操作的滾動(dòng)并不會(huì)觸發(fā)相關(guān)重塑/回流。

判斷當(dāng)前元素是否存在滾動(dòng)條

出現(xiàn)滾動(dòng)條便意味著元素空間將大于其內(nèi)容顯示區(qū)域,根據(jù)這個(gè)現(xiàn)象便可以得到判斷是否出現(xiàn)滾動(dòng)條的規(guī)則。

export const hasScrolled = (element, direction) => {
  if (!element || element.nodeType !== 1) return;
  if (direction === "vertical") {
    return element.scrollHeight > element.clientHeight;
  } else if (direction === "horizontal") {
    return element.scrollWidth > element.clientWidth;
  }
};

判斷用戶是否滾動(dòng)到底部

本質(zhì)上就是當(dāng)元素出現(xiàn)滾動(dòng)條時(shí),判斷當(dāng)前元素出現(xiàn)的高度 + 滾動(dòng)條高度 = 元素本身的高度(包含隱藏部分)。

element.scrollHeight - element.scrollTop === element.clientHeight

client

MouseEvent.clientX/Y

MounseEvent.clientX/Y同樣也是只讀屬性,它提供事件發(fā)生時(shí)的應(yīng)用客戶端區(qū)域的水平坐標(biāo)。

例如,不論頁(yè)面是否有垂直/水平滾動(dòng),當(dāng)你點(diǎn)擊客戶端區(qū)域的左上角時(shí),鼠標(biāo)事件的 clientX/Y 值都將為 0 。

其實(shí)MouseEvent.clientX/Y也就是相對(duì)于當(dāng)前視口(瀏覽器可視區(qū))進(jìn)行位置計(jì)算。

轉(zhuǎn)載一張非常直白的圖:

Element.clientHeight/clientWidth

Element.clientWidth/clinetHeight 屬性表示元素的內(nèi)部寬度,以像素計(jì)。該屬性包括內(nèi)邊距 padding,但不包括邊框 border、外邊距 margin 和垂直滾動(dòng)條(如果有的話)。

內(nèi)聯(lián)元素以及沒有 CSS 樣式的元素的 clientWidth 屬性值為 0。

在不出現(xiàn)滾動(dòng)條時(shí)候Element.clientWidth/Height === Element.scrollWidth/Height

Element.clientTop/clientLeft

Element.clientLeft表示一個(gè)元素的左邊框的寬度,以像素表示。如果元素的文本方向是從右向左(RTL, right-to-left),并且由于內(nèi)容溢出導(dǎo)致左邊出現(xiàn)了一個(gè)垂直滾動(dòng)條,則該屬性包括滾動(dòng)條的寬度。clientLeft 不包括左外邊距和左內(nèi)邊距。clientLeft 是只讀的。

同樣的Element.clientTop表示元素上邊框的寬度,也是一個(gè)只讀屬性。

這兩個(gè)屬性日常使用會(huì)比較少,但是也應(yīng)該了解以避免搞混這些看似名稱都類似的屬性。

offset

MouseEvent.offsetX/offsetY

MouseEvent 接口的只讀屬性 offsetX/Y 規(guī)定了事件對(duì)象與目標(biāo)節(jié)點(diǎn)的內(nèi)填充邊(padding edge)在 X/Y 軸方向上的偏移量。

相信使用過offest的同學(xué)對(duì)這個(gè)屬性深有體會(huì),它是相對(duì)于父元素的左邊/上方的偏移量。

注意是觸發(fā)元素也就是 e.target,額外小心如果事件對(duì)象中存在從一個(gè)子元素當(dāng)移動(dòng)到子元素內(nèi)部時(shí),e.offsetX/Y 此時(shí)相對(duì)于子元素的左上角偏移量。

offsetWidth/offsetHeight

HTMLElement.offsetWidth/Height 是一個(gè)只讀屬性,返回一個(gè)元素的布局寬度/高度。

所謂的布局寬度也就是相對(duì)于我們上邊說到的clientHeight/Width,offsetHeight/Width,他們都是不包含border以及滾動(dòng)條的寬/高(如果存在的話)。

而offsetWidth/offsetHeight返回元素的布局寬度/高度,包含元素的邊框(border)、水平線/垂直線上的內(nèi)邊距(padding)、豎直/水平方向滾動(dòng)條(scrollbar)(如果存在的話)、以及CSS設(shè)置的寬度(width)的值。

offsetTop/left

HTMLElement.offsetLeft 是一個(gè)只讀屬性,返回當(dāng)前元素左上角相對(duì)于 HTMLElement.offsetParent 節(jié)點(diǎn)的左邊界偏移的像素值。

注意返回的是相對(duì)于 HTMLElement.offsetParent 節(jié)點(diǎn)左邊邊界的偏移量。

何為HTMLElement.offsetParent?

HTMLElement.offsetParent 是一個(gè)只讀屬性,返回一個(gè)指向最近的(指包含層級(jí)上的最近)包含該元素的定位元素或者最近的 table,td,th,body 元素。當(dāng)元素的 style.display 設(shè)置為 "none" 時(shí),offsetParent 返回 null。offsetParent 很有用,因?yàn)?offsetTop 和 offsetLeft 都是相對(duì)于其內(nèi)邊距邊界的。  -- MDN

講講人話,當(dāng)前元素的祖先組件節(jié)點(diǎn)如果不存在任何 table,td,th 以及 position 屬性為 relative,absolute 等為定位元素時(shí),offsetLeft/offsetTop 返回的是距離 body 左/上角的偏移量。

當(dāng)祖先元素中有定位元素(或者上述標(biāo)簽元素)時(shí),它就可以被稱為元素的offsetParent。元素的 offsetLeft/offsetTop 的值等于它的左邊框左側(cè)/頂邊框頂部到它的 offsetParent 元素左邊框的距離。

我們來看看這張圖:

計(jì)算元素距離 body 的偏移量

當(dāng)我們需要獲得元素距離 body 的距離時(shí),但是又無(wú)法確定父元素是否存在定位元素時(shí)(大多數(shù)時(shí)候在組件開發(fā)中,并不清楚父節(jié)點(diǎn)是否存在定位)。此時(shí)需要實(shí)現(xiàn)類似 jqery 的 offset()方法:獲得當(dāng)前元素對(duì)于 body 的偏移量。

  • 無(wú)法直接使用 offsetLeft/offsetTop 獲取,因?yàn)椴⒉淮_定父元素是否存在定位元素。
  • 使用遞歸解決,累加偏移量 offset,當(dāng)前 offsetParent 不為 body 時(shí)。
  • 繼續(xù)遞歸向上超著 offsetParent 累加 offset,直到遇到 body 元素停止。
const getOffsetSize = function(Node: any, offset?: any): any {
  if (!offset) {
    offset = {
      x: 0,
      y: 0
    };
  }
  if (Node === document.body) return offset;
  offset.x = offset.x + Node.offsetLeft;
  offset.y = offset.y + Node.offsetTop;
  return getOffsetSize(Node.offsetParent, offset);
};

注意:這里不可以使用 parentNode 上文已經(jīng)講過 offsetLeft/top 針對(duì)的是 HTMLElement.offsetParent 的偏移量而非 parentNode 的偏移量。

Element.getBoundingClientRect

用法講解

Element.getBoundingClientRect() 方法返回元素的大小及其相對(duì)于視口的位置。

element.getBoundingClientRect()返回的相對(duì)于視口左上角的位置。

element.getBoundingClientRect()返回的 height 和 width 是針對(duì)元素可見區(qū)域的寬和高(具體尺寸根據(jù) box-sizing 決定),并不包含滾動(dòng)條被隱藏的內(nèi)容。

TIP: 如果是標(biāo)準(zhǔn)盒子模型,元素的尺寸等于 width/height + padding + border-width 的總和。如果 box-sizing: border-box,元素的的尺寸等于 width/height。

rectObject = object.getBoundingClientRect();

返回值是一個(gè) DOMRect 對(duì)象,這個(gè)對(duì)象是由該元素的 getClientRects() 方法返回的一組矩形的集合,就是該元素的 CSS 邊框大小。返回的結(jié)果是包含完整元素的最小矩形,并且擁有 left, top, right, bottom, x, y, width, 和 height 這幾個(gè)以像素為單位的只讀屬性用于描述整個(gè)邊框。除了 width 和 height 以外的屬性是相對(duì)于視圖窗口的左上角來計(jì)算的。

width和height是計(jì)算元素的大小,其他屬性都是相對(duì)于視口左上角來說的。

當(dāng)計(jì)算邊界矩形時(shí),會(huì)考慮視口區(qū)域(或其他可滾動(dòng)元素)內(nèi)的滾動(dòng)操作,也就是說,當(dāng)滾動(dòng)位置發(fā)生了改變,top 和 left 屬性值就會(huì)隨之立即發(fā)生變化(因此,它們的值是相對(duì)于視口的,而不是絕對(duì)的) 。如果你需要獲得相對(duì)于整個(gè)網(wǎng)頁(yè)左上角定位的屬性值,那么只要給 top、left 屬性值加上當(dāng)前的滾動(dòng)位置(通過 window.scrollX 和 window.scrollY),這樣就可以獲取與當(dāng)前的滾動(dòng)位置無(wú)關(guān)的值。

計(jì)算元素是否出現(xiàn)在視口內(nèi)

利用的還是元素距離視口的位置小于視口的大小。

注意即便變成了負(fù)值,那么也表示元素曾經(jīng)出現(xiàn)過在屏幕中只是現(xiàn)在不顯示了而已。(就比如滑動(dòng)過)

vue-lazy圖片懶加載庫(kù)源碼就是這么判斷的。

 isInView (): boolean {
    const rect = this.el.getBoundingClientRect()
    return rect.top < window.innerHeight && rect.left < window.innerWidth
  }

如果rect.top < window.innerHeight表示當(dāng)前元素已經(jīng)已經(jīng)出現(xiàn)在(過)頁(yè)面中,left同理。

window.getComputedStyle

用法講解

Window.getComputedStyle()方法返回一個(gè)對(duì)象,該對(duì)象在應(yīng)用活動(dòng)樣式表并解析這些值可能包含的任何基本計(jì)算后報(bào)告元素的所有CSS屬性的值。 私有的CSS屬性值可以通過對(duì)象提供的API或通過簡(jiǎn)單地使用CSS屬性名稱進(jìn)行索引來訪問。

let style = window.getComputedStyle(element, [pseudoElt]);

element

  •  用于獲取計(jì)算樣式的Element。

pseudoElt 可選

  • 指定一個(gè)要匹配的偽元素的字符串。必須對(duì)普通元素省略(或null)。

返回的style是一個(gè)實(shí)時(shí)的 CSSStyleDeclaration 對(duì)象,當(dāng)元素的樣式更改時(shí),它會(huì)自動(dòng)更新本身。

總結(jié)

到此這篇關(guān)于js中位置計(jì)算的文章就介紹到這了,更多相關(guān)js中的位置計(jì)算內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • html+javascript+bootstrap實(shí)現(xiàn)層級(jí)多選框全層全選和多選功能

    html+javascript+bootstrap實(shí)現(xiàn)層級(jí)多選框全層全選和多選功能

    想做一個(gè)先按層級(jí)排序并可以多選的功能,首先傾向于用多層標(biāo)簽式的,直接選定加在文本域里,接下來通過本文給大家介紹html+javascript+bootstrap實(shí)現(xiàn)層級(jí)多選框全層全選和多選功能,需要的朋友參考下
    2017-03-03
  • 微信小程序如何同時(shí)獲取用戶信息和用戶手機(jī)號(hào)

    微信小程序如何同時(shí)獲取用戶信息和用戶手機(jī)號(hào)

    小程序登錄是現(xiàn)在小程序里面很普遍的一個(gè)功能,因?yàn)楣俜教峁┑姆椒?可以一鍵獲取到用戶信息,一鍵拿到手機(jī)號(hào),這篇文章主要給大家介紹了關(guān)于微信小程序如何同時(shí)獲取用戶信息和用戶手機(jī)號(hào)的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • 原生javascript實(shí)現(xiàn)無(wú)間縫滾動(dòng)示例

    原生javascript實(shí)現(xiàn)無(wú)間縫滾動(dòng)示例

    原生javascript無(wú)間縫滾動(dòng)目前支持的是豎向與橫向滾動(dòng),下面有個(gè)不錯(cuò)的示例,大家可以參考下
    2014-01-01
  • 一文總結(jié)JS中邏輯運(yùn)算符的特點(diǎn)

    一文總結(jié)JS中邏輯運(yùn)算符的特點(diǎn)

    在JavaScript的眾多運(yùn)算符里,提供了三個(gè)邏輯運(yùn)算符&&、||和!,下面這篇文章主要給大家介紹了關(guān)于JS中邏輯運(yùn)算符的特點(diǎn),文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Bootstrap fileinput組件封裝及使用詳解

    Bootstrap fileinput組件封裝及使用詳解

    這篇文章主要介紹了Bootstrap fileinput組件封裝及使用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • JS中的回調(diào)函數(shù)實(shí)例淺析

    JS中的回調(diào)函數(shù)實(shí)例淺析

    這篇文章主要介紹了JS中的回調(diào)函數(shù),結(jié)合實(shí)例形式簡(jiǎn)單分析了javascript回調(diào)函數(shù)的感念、功能、使用方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2018-03-03
  • javascript圖片延遲加載實(shí)現(xiàn)方法及思路

    javascript圖片延遲加載實(shí)現(xiàn)方法及思路

    這篇文章主要介紹了javascript圖片延遲加載實(shí)現(xiàn)方法及思路,有時(shí)我們需要用懶加載,也就是延遲加載圖片的方式,來提高網(wǎng)站的親和力,需要的朋友可以參考下
    2015-12-12
  • 利用uniapp+vue3+js適配微信隱私協(xié)議開發(fā)指南

    利用uniapp+vue3+js適配微信隱私協(xié)議開發(fā)指南

    這篇文章主要給大家介紹了關(guān)于利用uniapp+vue3+js適配微信隱私協(xié)議開發(fā)指南的相關(guān)資料,適配最新微信小程序隱私協(xié)議開發(fā)指南,兼容uniapp版本,需要的朋友可以參考下
    2023-12-12
  • js正則表達(dá)式中exec用法實(shí)例

    js正則表達(dá)式中exec用法實(shí)例

    這篇文章主要介紹了js正則表達(dá)式中exec用法,實(shí)例分析了javascript中使用exec執(zhí)行正則表達(dá)式的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • js實(shí)現(xiàn)微信聊天界面

    js實(shí)現(xiàn)微信聊天界面

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)微信聊天界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08

最新評(píng)論