-
最近需要把時間軸修改成自己想要的樣子,需要在時間軸的當前時間條上設置一個氣泡,但是沒有這個api,於是想到一個辦法,通過監聽 時間條dom元素,獲取時間條的位置,然后創建一個元素當做氣泡,這個氣泡的位置會隨着時間條的位置變化而變化;
1、需要用到MutationObserver 來監聽時間條dom元素,
2、用DOM.getBoundingClientRect()方法監聽dom相對於窗口的位置;
3、根據時間條的位置,給創建的氣泡元素設置位置,從而達到給時間條加氣泡的效果;
4、為了簡化一些,我用了一個div當做時間條,設置一個定時器讓它持續移動。可以模擬出來拖動時間條的場景。
上代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>observer</title> <style> .wrap{ width:400px; height:400px; position: relative; margin-left:200px; } .box{ width: 300px; height:300px; position: absolute; top:0; left:0; background:cadetblue; clip-path: polygon(15px 0, calc(100% - 15px) 0, 100% 15px, 100% calc(100% - 15px), calc(100% - 15px) 100%, 15px 100%, 0 calc(100% - 15px), 0 15px) } .pop{ position: fixed; border:1px solid black; border-radius:4px; padding: 4px; box-shadow: 0px 0px 4px 2px black inset; user-select: none; } </style> </head> <body> <div class="wrap"> <div class="box"></div> </div> <script> let box = document.querySelector(".box"); let add = 1; setInterval(() => { let left = parseInt(getComputedStyle(box).left); console.log(left); if(left > 300 ){ add = -1; } if (left < 0){ add = 1; } box.style.left = `${left + add}px` }, 1000); // 觀察者的選項(要觀察哪些突變) var config = { attributes: true, childList: false, subtree: false };// 只監聽屬性發生變化 // 當觀察到突變時執行的回調函數 var callback = function(mutationsList) { console.log(mutationsList, 'mutationsList'); mutationsList.forEach(function(item,index){ if (item.type == 'childList') { console.log('有節點發生改變'); } else if (item.type == 'attributes') { let targetleft = item.target.getBoundingClientRect().left; console.log(targetleft,'targetleft'); let date = new Date(); changePop(item.target, ` <div>${date.getYear()}年${date.getMonth() + 1}月${date.getDay()}</div> <span>${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}</span> `) } else if (item.type == 'subtree') { console.log('subtree有變化'); } }); }; // 創建一個鏈接到回調函數的觀察者實例 var observer = new MutationObserver(callback); // 開始觀察已配置突變的目標節點 observer.observe(box, config); // 停止觀察 //observer.disconnect(); function changePop(parent,innerHTML){ let pop = null; if(!document.querySelector('.pop')){ pop = document.createElement('div'); pop.classList.add('pop') document.body.appendChild(pop); } else { pop = document.querySelector('.pop'); } let position = parent.getBoundingClientRect(); pop.style.left = `${position.left}px`; pop.style.top = `${position.bottom}px`; pop.innerHTML = innerHTML; } </script> </body> </html>
效果:氣泡位置會跟着時間條的位置變化而變化
下面簡單說一下ResizeObserver API的使用,這個方法是監聽元素的大小改變,不用通過window.resize來監聽窗口改變來達到目的,有些時候只監聽window.resize也是達不到目的的,因為我們可能用js來改變某一個元素的寬高,所以用ResizeObserver方法來監聽會更加方便,不過這個API目前是實驗階段,在chrome瀏覽器已經支持
文檔地址:https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver
<textarea id="main"></textarea> <script> // javascript let mainEl = document.querySelector('#main') const resizeObserver = new ResizeObserver(entries => { console.log(entries, 'entries'); for (let entry of entries) { console.log(entry.contentRect, 'contentRect'); entry.target.style.borderRadius = Math.max(0, 250 - entry.contentRect.width) + 'px'; } }); resizeObserver.observe(mainEl); // 取消某個元素監聽 //resizeObserver.unobserve(mainEl) // 取消全部元素監聽 //resizeObserver.disconnect()
拖動富文本框,監聽到實時的大小。
-