主頁 > 企業開發 > 記錄--不定高度展開收起影片 css/js 實作

記錄--不定高度展開收起影片 css/js 實作

2023-06-29 08:54:35 企業開發

這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

不定高度展開收起影片

最近在做需求的時候,遇見了元素高度展開收起的影片需求,一開始是想到了使用 transition: all .3s; 來做影片效果,在固定高度的情況下,transition 影片很好使,滿足了需求,但是如果要考慮之后可能還會有更改的情況下,如果每次都是用固定高度來做影片,會顯得很繁瑣,也很呆,就想到了使用 height: auto; 來做高度影片,但是,眾所周知,高度設定成 auto 時是不會觸發 transition 影片的

.container {
    height: 0;
    background-color: #ccc;
    overflow: hidden;
    transition: all .3s;
}
.container:hover {
    height: 1000px;
}

效果如圖,不能滿足影片的要求

1.gif

在一番查找實驗之后,目前發現了如下幾種方法:

1. max-height 最大高度

transition 影片可以回應 max-height

.container {
    max-height: 0;
    background-color: #ccc;
    overflow: hidden;
    transition: all .3s;
}
.container:hover {
    max-height: 1000px;
}

2.gif

但是使用 max-height 做影片有一個問題,如果設定的最大高度越大,但是實際高度確與最大高度相差甚遠,那么整體的影片速度就會非常快,影片的時間只會是 實際高度 / 最大高度 * 影片時間,因為展開影片原本預期高度是設定的最大高度,所以整體時間是以最大高度完全展開所用時間來進行的,但是當到達實際高度的時候影片就停止了,所以最終影片時間會與期望時間相差甚遠,

max-height 方法做影片也是一個好方法,如果能夠確定大致高度的話,使用此方法是最簡單也是最快的方法,但是如果不能確定大致高度或整體高度經常變化的話,可以考慮其他方法,

2. grid 影片

grid 網格布局,是一種較新的布局,號稱是最強大的布局方案,grid 布局不是本文的介紹重點,并且較為復雜,如果感興趣的話,可以參考相關文章,如:

  • 寫給自己看的display: grid布局教程
  • 最強大的 CSS 布局 —— Grid 布局

grid 布局中可以使用 fr 單位,fr 單位是支持過度影片的(0fr=>1fr),將 grid 布局下的子元素,初始設定為0fr,在 :hover 狀態下設定為 1fr,就能夠實作不定高度影片效果,但是如果子元素有內容,在設定 0fr 的時候,會被其內容撐開,所以要給子元素添加 min-height: 0;

.container {
    display: grid;
    grid-template-rows: 0fr;
    overflow: hidden;
    transition: all .3s;
}
.container:hover {
    grid-template-rows: 1fr;
}
.container .child {
    min-height: 0;
}

3.gif

如果想要實作帶有基礎高度的展開收起影片,我們可以設定 min-height: 100px;

.container .child {
    min-height: 100px;
}

4.gif

雖然此時實作了帶有基礎高度的影片效果,但是可以看到,如果我把 transition: all 3s; 的影片時間設定的較大,就可以看出來,雖然有基礎高度,但是整個影片的效果還是要實作 0fr1fr 的影片效果,基礎高度部分不會有影片效果,這也算是一個小的缺點,如果影片時間較短并且基礎高度也不大的話,可以這樣使用,并不會有太大的影響效果,

但是 grid 布局有可能有兼容性的問題,grid-template-rows 影片的支持可能有兼容性問題

 

3. js 控制影片

寫這篇文章的原因是因為在看專案代碼的時候看見了 $(.xx).slideDown() 方法實作了元素的下滑影片,覺得很不錯,想學習一下怎么實作的,實作效果如下:

5.gif

但是在看元素的時候卻只能看見下面的樣子,發現不是 css 實作的,是使用 js 不斷改變元素的高度來實作的:

6.gif

我又去看了一下 ant-designMenu 組件,通過觀察元素,發現其也是不斷改變高度來實作的(Ps: 我并沒有去看原始碼,如果有誤,多謝指正),

實作

首先要思考整個實作的思路

展開的時候,元素從無到有,我們應該首先獲取整個元素的實際高度使用 offsetHeight 來獲取,獲取到整體高度后就要計算每一次增加或者減少的高度,通過定時器不斷增加或減少元素的高度,直到到了最大高度或 0 后停止

展開

const element = document.getElementById('container');
let expandTimer = null;
let offsetHeight = 0;

// 獲取元素總高度
element.style.display = 'block';
let height = 0;
// 先將 display 設定為 block,獲取到的 offsetHeight 才是正確的高度,之后才能設定元素高度
offsetHeight = element.offsetHeight;
const stepHeight = offsetHeight / 30;
element.style.height = height + 'px';

expandTimer = setInterval(() => {
    height += stepHeight;
    if (height >= offsetHeight) {
        clearInterval(expandTimer);
        element.style = null;
        return;
    }
    element.style.height = height + 'px';
}, 10);

收起

let collapseTimer = null;

offsetHeight = element.offsetHeight;
let height = offsetHeight;

const stepHeight = offsetHeight / 30;
element.style.height = height + 'px';

collapseTimer = setInterval(() => {
    height -= stepHeight;
    if (height <= 0) {
        clearInterval(collapseTimer);
        element.style = null;
        return;
    }
    element.style.height = height + 'px';
}, 10);

8.gif

現在能夠正確展開收起,但是我們在展開收起的時候也會有相反的操作,比如滑鼠進入元素展開離開收起,在展開的程序中滑鼠離開了,我們應該立刻就將元素收起,而不是等影片結束后在進行下一個影片,所以要將展開收起操作合并操作才可以

const element = document.getElementById('container');
let expandTimer = null;
let collapseTimer = null;
// 我認為在一次展開后,直到收起完成之前,這個元素的實際高度都不應該發生變化,但是可以在下一次展開時發生變化,所以在展開時會進行賦值,在收起完成時會將此值清空
let offsetHeight = 0;
let stepHeight = 0;

const handleClick = () => {
    // 如果當前 expandTimer 值存在,就標識當前是正在展開或已經展開,接下來要進行的是收起操作
    if (expandTimer) {
        clearInterval(expandTimer);
        expandTimer = null;
        // 收起時的初始高度是元素的當前實際高度,即使是元素在展開影片程序中,也要從當前元素高度進行收起影片
        let height = element.offsetHeight;

        collapseTimer = setInterval(() => {
            height -= stepHeight;
            if (height <= 0) {
                // 高度小于等于 0 代表影片完成,將資料進行重置
                clearInterval(collapseTimer);
                offsetHeight = 0;
                // 要將元素的高度置為 null,不然會影響下一次展開時獲取正確的高度
                element.style.height = null;
                // display 設為 null,要將元素隱藏
                element.style.display = 'none';
                return;
            }
            element.style.height = height + 'px';
        }, 10);
    } else {
        clearInterval(collapseTimer);
        collapseTimer = null;
        // 獲取元素總高度
        element.style.display = 'block';
        let height = 0;
        如果當前沒有 offsetHeight 就要重新獲取
        if (!offsetHeight) {
            offsetHeight = element.offsetHeight;
            // 每一次給元素添加或減少的高度,除以 30 是自己設定的,跟下面定時器的每次間隔時間一起控制整個高度影片的時長,也可以給函式添加第二個時間引數,可以自由控制影片時間
            stepHeight = offsetHeight / 30;
        } else {
            // 如果有 offsetHeight 就代表正在進行收起影片,應該從收起影片的當前高度進行展開影片
            height = element.offsetHeight;
        }
        
        element.style.height = height + 'px';

        expandTimer = setInterval(() => {
            height += stepHeight;
            if (height >= offsetHeight) {
                // 當前高度如果已經到了元素的實際高度,就要清除定時器
                clearInterval(expandTimer);
                // 將 expandTimer 設為 1 是因為當前是以 expandTimer 判斷是否正在或已經進行了展開影片,所以要在完成是設為 1,在收起影片的開始時會將值設為 null
                expandTimer = 1;
                element.style = null;
                return;
            }
            element.style.height = height + 'px';
        }, 10);
    }
};

最終實作效果

9.gif

4. 總結

上面的三種方式實作效果都是各有千秋 - max-height 方法實作是最簡單,也是效率最高的方式,但是也有影片時間不定的缺陷 - grid 方式實作比 max-height 稍微復雜一些,但是整體效果要比 max-height 更好,但是目前瀏覽器的支持方面可能有所不足,如果有低版本的兼容性要求的話,還是不能使用 - js 方式整體最復雜,但是卻沒有上面兩種方式的缺陷與問題,使用范圍也更廣泛,但是是 js 的實作方式,性能肯定是不如 css,雖然不如,但是由于整體操作也較為簡單,所以也不會有什么性能問題

幾種方法的取舍全看個人需求了,

如果有滑鼠進入展開,離開收起的操作,可以配合使用 onmouseover onmouseout 事件來監聽滑鼠的進入離開,

其他還有像是 transform: scale(0); 的實作也是可以,但是整體影片效果就是一個縮小的效果,而且元素還會有占位問題,如果沒什么要求也是可以使用的,

本文轉載于:

https://juejin.cn/post/7249536369474486329

如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/556251.html

標籤:其他

上一篇:前端打包部署后介面BASE_URL不對問題解決辦法

下一篇:返回列表

標籤雲
其他(161822) Python(38259) JavaScript(25516) Java(18273) C(15238) 區塊鏈(8273) C#(7972) AI(7469) 爪哇(7425) MySQL(7271) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4607) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2438) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1985) HtmlCss(1976) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 記錄--不定高度展開收起影片 css/js 實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 不定高度展開收起影片 最近在做需求的時候,遇見了元素高度展開收起的影片需求,一開始是想到了使用 transition: all .3s; 來做影片效果,在固定高度的情況下,transition 影片很好使,滿足了需求,但是如果要考慮之后可 ......

    uj5u.com 2023-06-29 08:54:35 more
  • 前端打包部署后介面BASE_URL不對問題解決辦法

    在前端打包部署時,為了免去不同環境打包的麻煩,專案用的流水線觸發方式。在這里不細說,重點說說下面情況。 當專案提交打包部署后,訪問壓測環境或者生產環境的地址來使用專案時,發現介面報錯404。 在NETWORK里發現介面的BASEURL和當前環境需要呼叫的后端baseurl不同。 主要問題在于配置問題 ......

    uj5u.com 2023-06-29 08:54:22 more
  • this指向性問題

    this的查找規則會逐層往上查找,最終位全域window 優先級問題:顯式系結(顯式系結與new系結沒有可比性)new系結>隱式系結>默認系結 在編程中,this 是一個關鍵字,代表當前物件或者函式的執行環境。this 的指向性問題是指在不同的情況下,this 指向的物件不同,從而影響代碼的行為。 ......

    uj5u.com 2023-06-29 08:54:12 more
  • this指向性問題

    this的查找規則會逐層往上查找,最終位全域window 優先級問題:顯式系結(顯式系結與new系結沒有可比性)new系結>隱式系結>默認系結 在編程中,this 是一個關鍵字,代表當前物件或者函式的執行環境。this 的指向性問題是指在不同的情況下,this 指向的物件不同,從而影響代碼的行為。 ......

    uj5u.com 2023-06-29 08:48:10 more
  • Vue2.0針對設備調節顯示內容方法

    一晚上完成0.2.2、0.3.0、0.3.1三個版本的更新,很高興,總結一下 專案地址: [穆音博客](https://blog.muvocal.com) 文章首發地址:[Vue針對設備調節顯示](https://blog.muvocal.com/blog/11) ## Vue中進行優化的方式 總體 ......

    uj5u.com 2023-06-28 10:04:15 more
  • React ISR 如何實作 - 最后的 Demo

    之前寫了兩個 `demo` 講解了如何實作 `SSR` 和 `SSG`,今天再寫個 `demo` 說在 `ISR` 如何實作。 ## 什么是 ISR `ISR` 即 `Incremental Static Regeneration` 增量靜態再生,是指在 `SSG` 的前提下,可以在收到請求時判定頁 ......

    uj5u.com 2023-06-28 10:04:10 more
  • 618技術揭秘:探究競速榜頁面核心前端技術

    本文將探究京東競速榜H5頁面的核心前端技術,包括影片、樣式配置化、皮膚切換、海報技術、除錯技巧等方面,希望能夠為廣大前端開發者提供一些有用的參考和思路。 ......

    uj5u.com 2023-06-28 10:04:04 more
  • 前端檔案上傳的幾種互動造輪子

    前端檔案上傳本來是一個常規互動操作,沒什么特殊性可言,但是最近在做檔案上傳,需要實作截圖粘貼上傳,去找了下有沒有什么好用的組件,網上提供的方法有,但是沒找完整的組件來支持cv上傳,經過了解發現可以用剪貼板功能讓自己的cv實作檔案上傳,于是自己就整合了目前幾種檔案上傳的互動方式,碼了一個支持cv的vu... ......

    uj5u.com 2023-06-28 10:03:59 more
  • 記錄--Threejs-著色器實作一個水波紋

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 hree.js 是一個基于 WebGL 的 JavaScript 3D 庫,用于創建和渲染 3D 圖形場景。 一、 影像渲染程序 1、webGL webGL: WebGL 是一種基于 JavaScript API 的圖形庫,它允許在瀏覽器 ......

    uj5u.com 2023-06-28 09:58:41 more
  • CSS實作根據子元素數量應用不同樣式

    theme: condensed-night-purple highlight: atelier-cave-light 在前端的頁面布局中經常會出現在子元素個數使用不同的樣式的需求,比如文章串列,在較少內容下單串列現,而在元素內容較多時使用雙串列現。再比如在頁面排版上,可以根據元素內容的多少來修改內 ......

    uj5u.com 2023-06-28 09:57:34 more