摘要:是一門很神奇的語言,很多和它不相干的功能卻能起到很顯著的效果,有些在看起來實現都有一定的工作量,一句屬性就能輕而易舉的解決,下面來看幾個例子主要和事件相關。那么,如何借助來監(jiān)聽這些呢可以從過渡和動畫兩個思路來考慮。
CSS是一門很神奇的語言,很多和它不相干的功能卻能起到很顯著的效果,有些在js看起來實現都有一定的工作量,CSS一句屬性就能輕而易舉的解決,下面來看幾個例子(主要和js事件相關)。
原鏈接
https://notes.codelabo.cn/art...
原issues
https://github.com/XboxYan/no...
很多都是開腦洞想出來的,實現效果卻意外的驚人事件禁用
在js中對事件禁用并不復雜,但是卻容易影響到業(yè)務邏輯
function buy(){ if(XX){ return false; } //其他業(yè)務代碼 }
當然,元素也要設置相應的樣式,讓它看起來不可點擊。
css對事件禁用就比較簡單了,主要有兩種方式
1. disabled
原生表單元素是有默認的禁用屬性的,比如
可以看出,禁用的默認樣式為
button:disabled { color: graytext; }
所以,在這里你可以隨意的修改禁用的樣式
button:disabled { color: red; } button[disabled] {/**屬性選擇器也行**/ color: red; } button:hover { /**:hover支持**/ color: red; } button:active,button:focus{/**不支持,其實也好理解,會觸發(fā)focus()事件,所以也禁用了**/ color:red }
一般情況下,使用這種方式是比較好的,天然的禁用屬性,兼容性也不錯
2. pointer-events:none
這個屬性應該也不陌生,最常見的用法就是禁用一個按鈕,而且不局限于表單元素,任意元素均可(比如很多人喜歡用的a標簽)
button.disabled { pointer-events:none; user-select:none;/*去除選中效果*/ color: graytext; }
這個屬性用處很多,很多js絞盡腦汁想要過濾掉的方法,直接就用一行屬性解決,這里就不展開了,網上教程很多。
查看這個demo
長按事件原生js中并沒有長按事件,通常開發(fā)者一般會順著思路,使用定時器來完成
下面是偽代碼
el.onmousedown = function(){ this.timer && clearTimeout(this.timer); this.timer = settimeout(function(){ //業(yè)務代碼 },350) } el.onmouseup = function(){ this.timer && clearTimeout(this.timer); }
當然,可以借助css來完成,而且效果更好,易于控制
這里為什么說是“借助”呢,因為不能完全有css來完成,只是利用了某些特性
css3中新增了過渡和動畫屬性,與之相對應的也預設了這些動畫的回調事件,如下
事件 | 說明 |
---|---|
transitionstart | 在開始過渡時觸發(fā) |
transitionrun | 在進行過渡時觸發(fā) |
transitioncancel | 在取消過渡時觸發(fā) |
transitionend | 在完成過渡后觸發(fā) |
animationstart | 在 animation 開始時觸發(fā) |
animationiteration | 在 animation 完成一個周期時觸發(fā) |
animationend | 在 animation 完成時觸發(fā) |
animationcancel | 在 animation 取消時觸發(fā) |
有些事件存在兼容性問題,有興趣的可以詳細研究
有了這些事件,要做一個長按事件就很容易了,這里有兩種種思路,大家可以腦洞一下
假設需要延時1s;
過渡時間設置為1s,調用transitionend或者animationend
延時1s,調用transitionstart或者animationstart
這里以第一種情況transitionend(過渡比動畫實現要容易多,代碼也少,優(yōu)先用過渡)來實現
button:hover:active{ opacity:.99;/**隨便選取一個不影響頁面的可以過渡的樣式**/ transition:opacity 1s; }
相應的,js需要監(jiān)聽transitionend事件,不需要借助定時器(個人有點鄙視定時器的思想^)
el.addEventListener("transitionend",function(){ //業(yè)務代碼 })
是不是精簡很多呢,需要改長按時間可以直接通過css來控制
這里封裝了一下自定義事件,可以更好的在項目中使用(雖然代碼本身就很少了)。
查看這個demo
單次點擊事件在jquery中有一個once(好像是這個)方法,表示綁定一次性事件,點擊一次后就不再生效。
原生js實現這個也不復雜,通常做法就是定義一個標識,點擊后改變一下,下面是偽代碼
el.onclick = function(){ if(!this.once){ //業(yè)務代碼 this.once = true; } }
借助上面的思路,css也可以實現類似的效果,深究了一番,總結以下兩個方法
1.animationend
animationend是動畫結束后觸發(fā),顯然我們可以在這里做文章
比如我們可以在初始狀態(tài)給一個暫停狀態(tài)animation-play-state:paused,然后在點擊時運動animation-play-state:running,結束后一直保持在最后狀態(tài)animation-fill-mode: forwards
.button{ animation: once .01s paused forwards;/**給一個足夠小的運動時間,確保能夠在`:active`時運動完成**/ } .button:hover:active{ animation-play-state:running; } @keyframes once { to{ opacity:.8; } }
js只需要對animationend進行監(jiān)聽
el.addEventListener("animationend",function(){ //業(yè)務代碼 })
2.純css實現
不知道在上面的例子中有沒有發(fā)現,在動畫結束時把元素禁用會怎么樣?
@keyframes once { to{ opacity:.8; pointer-events:none; user-select:none; } }
這樣就可以在運動完直接禁用,好像很完美?
事實上,這里運動的時間很難把控,大家都知道,onclick其實是包含按下和抬起兩個過程的,如果抬起的太慢,那么此時元素已經禁用了,觸發(fā)不了事件;如果抬起太快,如果快速點擊,由于還沒運動完成,會觸發(fā)多次事件。
解決方式也很簡單,用onmousedown代替即可
查看這個demo
onresize事件大家都知道window有個onresize事件,可以在窗口拉伸的時候觸發(fā),然后就能實時獲取窗體的尺寸等等屬性。
window.onresize = function(ev){ //業(yè)務代碼 }
但是,普通的元素卻沒有這個監(jiān)聽,比如
div.onresize = function(ev){ //不生效... }
為什么需要這個功能呢?
大家可能知道有這樣一個屬性,可以原生拉伸元素,改變尺寸
.box{ overflow: hidden;/**需要配合overflow才能生效**/ resize: both; }
只需一個屬性,就可以實現元素的拉伸(雖然稍有瑕疵),不需要大量的js來計算。
視覺展示還好,但是如果需要實時知道元素的尺寸怎么辦呢,js通常有兩種思路
1. onmousemove事件
拉伸的時候很自然的想到是有鼠標按住然后拖拽完成,所以可以給元素添加onmouse-*一系列事件,同時要注意鼠標抬起要取消監(jiān)聽
//大概是這樣的邏輯 div.onmousedown = function(){ div.onmousemove = fn;//監(jiān)聽 div.onmouseup = function(){ div.onmousemove = null; } }
2. 定時器
借助setInterval或者requestAnimFrame來實現監(jiān)聽,同樣是需要注意取消監(jiān)聽的時機
//大概是這樣的邏輯 div.onmousedown = function(){ this.timer && clearInterval(this.timer) this.timer = setInterval(fn,300);//監(jiān)聽 div.onmouseup = function(){ this.timer && clearInterval(this.timer) } }
很顯然,上面的方法都不是特別的舒適,很多情況下都會出現監(jiān)聽取消的問題,導致不停的觸發(fā),影響體驗。
這時候,又輪到css出場了,很多時候js覺得實現起來不順暢的時候都可以用css的思維來重新認識。
那么,如何借助css來監(jiān)聽這些呢?
可以從過渡和動畫兩個思路來考慮。
1. CSS過渡
首先,我們可以知道的是,在通過resize: both進行元素拉伸的時候,改變的是width和height,這一點可以從開發(fā)者工具直接看到
我們需要通過transitionrun或者transitionend來監(jiān)聽width和height,所以需要給這兩個屬性加上過渡
.box{ transition:width .3s,ehight .3s;//分別給width和height設置過渡,其他屬性不需要 }
這樣就可以拿到監(jiān)聽了,不過這種方式有一個弊端,由于過渡需要時間,所以有一種不跟隨,卡頓的感覺。
所以我們來看第二種方式
2. animationiteration
css動畫可以設置播放次數,如果設置成animation-iteration-count: infinite就表示無限輪播,配合animationiteration回調,不就可以實現監(jiān)聽了么
.box:active{ animation: resize .3s infinite forwards; } @keyframes resize{ to { opacity: .99;/**用一個無關緊要的屬性來觸發(fā)動畫**/ } }
js很簡單,一個監(jiān)聽就能解決問題,也不需要什么取消監(jiān)聽什么,這些都已經在css完成了
el.addEventListener("animationiteration",function(){ //業(yè)務代碼 })
這里是每個動畫完成一次就回調一次,所以我們可以通過設置動畫時長來控制監(jiān)聽的頻率,比如上面是.3s的觸發(fā)頻率。
下面寫了一個demo,可以實現自定義onresize事件
查看這個demo
小節(jié)以上通過借助css,實現了許多js都很棘手的問題,可能還會有更多的應用場景,歡迎小伙伴留言討論~
如果有新的想法,會第一時間更新在 https://github.com/XboxYan/no... ,多多關注
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/104275.html
摘要:預讀取預讀取是一項使瀏覽器主動去執(zhí)行域名解析的功能。在某些圖片較多的頁面中,在發(fā)起圖片加載請求之前預先把域名解析好將會有至少的圖片加載速度提升。但由于域名解析本身也是耗時的,所以也不是越多越好,最大支持路并發(fā),所以一般設置個域名較為合適。 文章本來是給公司內部分享用的,現在發(fā)表出來,歡迎大家提出寶貴建議。 背景目的 讓官網首頁加載速度更快,對用戶的操作響應得更及時,給用戶提供更為友好...
摘要:傳統(tǒng)的網頁編程采用的三劍客來實現,在微信小程序中同樣有三劍客。觀察者模式不難實現,重點是如何在微信小程序中搭配其特有的生命周期來使用。交互事件傳統(tǒng)的事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。 本文由作者鄒永勝授權網易云社區(qū)發(fā)布。 簡介為了更好的展示我們即時通訊SDK強悍的能力,網易云信IM SDK微信小程序DEMO的開發(fā)就提上了日程。用產品的話說就是: 云信 IM 小程序 S...
摘要:非常的龐大,而且它是完全為設計而生的動效庫。它運行于純粹的之上,是目前最強健的動畫資源庫之一??赡苁莿?chuàng)建滾動特效最好用的工具,它支持大量的瀏覽器,只要它們支持和特性??梢酝ㄟ^安裝吊炸天了,接近現實生活中的物理運動碰撞慣性動畫庫。 收集日期為2019-02-28,★代表當時的該項目在github的star數量 Animate.css 56401 ★ 一個跨瀏覽器的動效基礎庫,是許多基礎動...
閱讀 1335·2021-09-01 10:30
閱讀 2263·2021-07-23 10:38
閱讀 969·2019-08-29 15:06
閱讀 3215·2019-08-29 13:53
閱讀 3327·2019-08-26 11:54
閱讀 1901·2019-08-26 11:38
閱讀 2436·2019-08-26 10:29
閱讀 3191·2019-08-23 18:15