事件的原由是朋友給我發的一個微信javascript
當時就奇怪字體跟數據綁定有啥關係,處於好奇我讓他寫個 demo 給我看看 ,而後他發來一個代碼文件css
代碼精簡以下:html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Demo</title>
<style> body { font-size: 40px; } .time1 { display: inline-block; background: linear-gradient(to right, #a6ffcb, #1fa2ff); -webkit-background-clip: text; color: transparent; } </style>
</head>
<body>
<div id="app">
<div class="time1">{{ time }}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
<script> new Vue({ el: "#app", data: { time: new Date().toLocaleString() }, methods: { updateTime() { this.time = new Date().toLocaleString(); } }, mounted() { setInterval(this.updateTime, 1000); } }); </script>
asdasd
</body>
</html>
複製代碼
發如今瀏覽器下時間並不會改變 ,當我在控制檯把顏色註釋掉後,發現數據是改變的,這就奇怪了呀! 這裏我就試了下 另外一種漸變樣式寫法java
這種我不細說了 也很好理解 能夠看上面代碼實現方式web
<style> .time2 { position: relative; color: #a6ffcb; } .time2:before { content: attr(time); position: absolute; z-index: 10; color: #1fa2ff; -webkit-mask: linear-gradient(to left, #1fa2ff, transparent); } </style>
<div class="time2" time="time">我是漸變文字</div>
複製代碼
選擇器:before
向選定的元素前插入內容,使用 content
屬性來指定要插入的內容。mask
屬性讓元素的某一部分顯示或隱藏npm
content 取值 attr 就是用來獲取屬性值的,content:attr(屬性名)瀏覽器
content: attr(time)
; 能獲取到元素的 time
屬性,這裏的這個 time
屬性是本身自定義的一個屬性,隨便寫微信
<h1 date="我是漸變文字">我是漸變文字</h1>
複製代碼
而後content
屬性 這樣寫,content: attr(date)
; 一樣是能夠起做用的。app
mask 屬性 容許使用者經過部分或者徹底隱藏一個元素的可見區域。這種效果能夠經過遮罩或者裁切特定區域的圖片。
咱們試試另外一種狀況會不會出現不渲染狀況
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Demo</title>
<style> body { font-size: 40px; } .time1 { display: inline-block; } .time1 { background: linear-gradient(to right, #a6ffcb, #1fa2ff); -webkit-background-clip: text; color: transparent; } .time2 { position: relative; color: #a6ffcb; } .time2:before { content: attr(time); position: absolute; z-index: 10; color: #1fa2ff; -webkit-mask: linear-gradient(to left, #1fa2ff, transparent); } </style>
</head>
<body>
<div id="app">
<div class="time1">{{ time }}</div>
<div class="time2" :time="time">{{ time }}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
<script> new Vue({ el: "#app", data: { time: new Date().toLocaleString() }, methods: { updateTime() { this.time = new Date().toLocaleString(); } }, mounted() { setInterval(this.updateTime, 1000); } }); </script>
</body>
</html>
複製代碼
看下效果
我當時的表情
我想到了是否是瀏覽器重排和重繪的問題
咱們瞭解下重排和重繪
瀏覽器編譯頁面分爲 5 步
當 DOM 變化影響了元素的幾何屬性(寬、高改變等等),瀏覽器此時須要從新計算元素幾何屬性,而且頁面中其餘元素的幾何屬性可能會受影響,這樣渲染樹就發生了改變,也就是從新構造 RenderTree 渲染樹,這個過程叫作重排(reflow)
若是 DOM 變化僅僅影響的了背景色等等非幾何屬性,此時就發生了重繪(repaint)而不是重排,由於佈局沒有發生改變
頁面佈局和元素幾何屬性的改變就會致使重排
下列狀況會發生重排:
這邊時間文字改變了,但文字大小沒變,我感受按道理應該沒有觸發重排從而使背景色沒有改變 ,那我試試改變文字大長度試試
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Demo</title>
<style> body { font-size: 40px; } .time1 { display: inline-block; } .time1 { background: linear-gradient(to right, #a6ffcb, #1fa2ff); -webkit-background-clip: text; color: transparent; } .time2 { position: relative; color: #a6ffcb; } .time2:before { content: attr(time); position: absolute; z-index: 10; color: #1fa2ff; -webkit-mask: linear-gradient(to left, #1fa2ff, transparent); } </style>
</head>
<body>
<div id="app">
<div class="time1">{{ time }}</div>
<div class="time2" :time="time">{{ time }}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
<script> new Vue({ el: "#app", data: { time: new Date().toLocaleString(), arr: [ "奧術大師大所大所", "噶事發傻手法十分", "按時間大勝靠德德", "奧斯卡拉家帶口拉絲機迪卡龍" ] }, methods: { updateTime() { // this.time = new Date().toLocaleString(); this.time = this.arr[Math.floor(Math.random() * this.arr.length)]; } }, mounted() { setInterval(this.updateTime, 1000); } }); </script>
</body>
</html>
複製代碼
效果以下
發現確實,文字長度沒變,第一個不會從新渲染,長度一旦發生改變,第一個纔會改變渲染,而第二個一直在渲染
問題好像忽然找到緣由了,但我又無心發現新的問題
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Demo</title>
<style> body { font-size: 40px; } .time1 { display: inline-block; } .time1, .time3 { background: linear-gradient(to right, #a6ffcb, #1fa2ff); -webkit-background-clip: text; color: transparent; } .time2 { position: relative; color: #a6ffcb; } .time2:before { content: attr(time); position: absolute; z-index: 10; color: #1fa2ff; -webkit-mask: linear-gradient(to left, #1fa2ff, transparent); } </style>
</head>
<body>
<div id="app">
<div class="time1">{{ time }}</div>
<div class="time2" :time="time">{{ time }}</div>
<div>
<span class="time3">{{ time }}</span>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
<script> new Vue({ el: "#app", data: { msg: "Hello", time: new Date().toLocaleString() }, methods: { updateTime() { this.time = new Date().toLocaleString(); } }, mounted() { setInterval(this.updateTime, 1000); } }); </script>
</body>
</html>
複製代碼
當我改變 dom 結構發現又好了
效果以下
好了 我完全呆了
最後我也沒搞明白,但願知道的大佬幫忙解答。
不過爲了保險起見之後相似這種仍是用第二種漸變樣式吧!