日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

popup定位引擎popper.js介绍

發(fā)布時(shí)間:2024/6/21 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 popup定位引擎popper.js介绍 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

https://medium.com/@FezVrasta/popper-js-v1-5e8b3acd888c

https://survivejs.com/blog/popper-interview/

本文譯自popper.js作者的一篇博客

在過去,我為了在web app中更好地定位我的tooltips和popover,我會花幾個(gè)小時(shí)寫同樣的一段代碼,不斷進(jìn)行微調(diào)。每次我開始一個(gè)新的項(xiàng)目,總會根據(jù)不同的環(huán)境對定位有不同的需求。這種繁瑣直到我用emberjs開發(fā)一個(gè)大型應(yīng)用時(shí)達(dá)到極致,這個(gè)項(xiàng)目中由于比較爛的UX設(shè)計(jì)決定,幾乎她想在每個(gè)元素上都支持hover出現(xiàn)一個(gè)popover!

在這個(gè)大項(xiàng)目中,我們開始使用bootstrap3的tooltip,并不斷地通過hack代碼來實(shí)現(xiàn)新的功能。

在這個(gè)大項(xiàng)目中,一個(gè)重要的需求是:不允許將tooltip元素移動到body元素的直接兒子,因?yàn)槿绻@樣的話,我們的代碼就會broken.

幾乎經(jīng)過一年的項(xiàng)目開發(fā)并且維護(hù)我們的定制化實(shí)現(xiàn),我決定使用Tetcher,因?yàn)樗菜品浅?qiáng)大和穩(wěn)定。。不幸的是,玩了幾個(gè)小時(shí)后,發(fā)現(xiàn)他有一個(gè)重要的缺陷或者說限制:他會自動地修改dom節(jié)點(diǎn),將popper移動到body的兒子位置。他會增加一些classes并且增加一些inline style,而這你幾乎無法控制!

于是我又到github上花了很多時(shí)間去查找有沒有備選的方案,但是我最終一無所獲。難道是沒有人需要一個(gè)類似的library?或者還沒有人能夠比較好的抽象出來并實(shí)現(xiàn)一個(gè)可以單獨(dú)發(fā)布的lib?

我決定花一個(gè)周末的事件重寫我們自己項(xiàng)目中使用的定位engine,這就是popper.js的又來。

在v0.x時(shí)代,popper僅僅是一個(gè)js文件,謝了幾個(gè)函數(shù),聚焦在保持lib小巧輕量級。我希望popperjs能夠有很好的擴(kuò)展性,所以我決定使用middleware system.主要的想法是:計(jì)算元素的位置并且允許middleware來根據(jù)特定的需求來修改這個(gè)位置。

比如:一旦我們有了popper的position,并給了一些邊界約束,那么modifier就可以檢查popper是否會overflow并且自動反轉(zhuǎn)位置以確保popper不會被視窗cut off.

在工作了一段時(shí)間 后,我發(fā)現(xiàn)我們需要更好的代碼結(jié)構(gòu)以便更好地能夠維護(hù)使用他,這就是v1.0版本發(fā)布的初衷。

為了管理好代碼,我決定切換到es6模塊上來。我引入了rollup作為code bundler并使用babel作為transpiler,我也將自動化測試引擎從一個(gè)無頭的chrome setup切換到saucelabs cross-browser test suite上來。

在開發(fā)過程中,我決定各個(gè)功能模塊一級modifier/middleware都放到他們自己的文件中,這樣能在Libray中重用。

update流程:

我也重構(gòu)了整個(gè)update流程,也就是每次popper需要更新元素的位置時(shí)需要調(diào)用的代碼。

這個(gè)update process會在每一frame都被調(diào)用,也就是說大概60fps,這樣能夠保證位置修改的流暢連貫。為了實(shí)現(xiàn)這個(gè)連貫流暢的目標(biāo),整個(gè)update process的代碼必須簡練,并且盡可能地避免直接訪問dom.下面是其工作流程

React, Vuejs等第三方view library的集成

我必須考慮為了支持react或者vuejs需要做些什么,由于這些view library都會直接做dom操作,那么popperjs應(yīng)該做什么設(shè)計(jì)的思考呢?v1.0將所有的dom操作都集中到一個(gè)modifier中,applyStyle

這將允許使用vuejs,react的用戶簡單地disable掉applyStyle并且替換為vuejs,或者react兼容的函數(shù)。

Popper.js是如何工作的?

popper.js使用一個(gè)reference element(通常是一個(gè)button或者一個(gè)link)和一個(gè)popper element(任何你需要position的元素),popper.js找到這兩個(gè)元素的common offset parent,計(jì)算reference element相對于這個(gè)parent的位置,然后產(chǎn)生出一個(gè)坐標(biāo)集用于設(shè)置popper元素的position.就這么簡單。

最困難的地方在于必須考慮到一些邊界條件,比如跨瀏覽器的兼容性,box model的能力,必須考慮scrollable element等。簡單的用法:

new Popper(referenceElement, popperElement)

這段代碼將會把popperElement放置到referenceElement的下發(fā)。而且,通過這段代碼,你就可以訪問所有的內(nèi)置功能。

1. 如果referenceElement非常靠近了viewport的底部,那么popperElement將會被定位放置到referenceElement的上面,否則會出現(xiàn)popper部分不可見的問題;

2. 如果這兩個(gè)元素位于兩個(gè)不同的parents,那么popper.js也將會對這種情況考慮周全,也能很好的定位放置popper元素。

3. 它能夠有效地處理scrollable elements和頁面的resize場景.

Popper.js和其他類似的解決方案有什么不同呢?

主要的不同點(diǎn)在于該庫不需要直接操作dom。這有兩個(gè)好處:1.他不需要將popper節(jié)點(diǎn)移動到另外的context中,比如body的兒子,2.這樣很容易將popper.js集成到react,angular,vuejs等view library中。你可以像下面的代碼一樣輕松地將dom manipulation delegate給vuejs:

new Popper(referenceElement, popperElement, {
  modifiers: {
    applyStyle: { enabled: false },
    updateReactData: {
      order: 900,
      fn(data) {
        this.setState({ data });

        return data;
      }
    },
  },
});

上面的代碼中,我們關(guān)閉了內(nèi)置的applyStyle modifier,并且定義了我們客制化的modifier,該函數(shù)代理獲取計(jì)算出來的popper坐標(biāo)而將坐標(biāo)輸出到react組件中。

既然你具有了關(guān)于popper.js的所有knowledge,那么你就可以對popper element施加任何你想要的樣式。

你可能注意到我的定制modifier返回data對象。這個(gè)對象是必須的,因?yàn)槠渌膍odifier可能會在這個(gè)custom modifier之后執(zhí)行,它們也需要使用這個(gè)data對象。這種鏈條方式的調(diào)用使得popper.js非常易于擴(kuò)展。你可以注入任何定制化的函數(shù)在存續(xù)modifer之前或者之后運(yùn)行,或者關(guān)閉部分modifer,或者修正其他的modifer的行為,而這只需要通過修改這個(gè)data對象數(shù)據(jù)就可以了。

總結(jié)

以上是生活随笔為你收集整理的popup定位引擎popper.js介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。