成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

借助CSS來(lái)管理js事件

codercao / 1967人閱讀

摘要:是一門(mén)很神奇的語(yǔ)言,很多和它不相干的功能卻能起到很顯著的效果,有些在看起來(lái)實(shí)現(xiàn)都有一定的工作量,一句屬性就能輕而易舉的解決,下面來(lái)看幾個(gè)例子主要和事件相關(guān)。那么,如何借助來(lái)監(jiān)聽(tīng)這些呢可以從過(guò)渡和動(dòng)畫(huà)兩個(gè)思路來(lái)考慮。

CSS是一門(mén)很神奇的語(yǔ)言,很多和它不相干的功能卻能起到很顯著的效果,有些在js看起來(lái)實(shí)現(xiàn)都有一定的工作量,CSS一句屬性就能輕而易舉的解決,下面來(lái)看幾個(gè)例子(主要和js事件相關(guān))。

原鏈接

https://notes.codelabo.cn/art...

原issues

https://github.com/XboxYan/no...

很多都是開(kāi)腦洞想出來(lái)的,實(shí)現(xiàn)效果卻意外的驚人
事件禁用

在js中對(duì)事件禁用并不復(fù)雜,但是卻容易影響到業(yè)務(wù)邏輯

function buy(){
  if(XX){
    return false;
  }
  //其他業(yè)務(wù)代碼
}

當(dāng)然,元素也要設(shè)置相應(yīng)的樣式,讓它看起來(lái)不可點(diǎn)擊。

css對(duì)事件禁用就比較簡(jiǎn)單了,主要有兩種方式

1. disabled

原生表單元素是有默認(rèn)的禁用屬性的,比如

可以看出,禁用的默認(rèn)樣式為

button:disabled {
    color: graytext;
}

所以,在這里你可以隨意的修改禁用的樣式

button:disabled {
    color: red;
}
button[disabled] {/**屬性選擇器也行**/
    color: red;
}
button:hover { /**:hover支持**/
    color: red;
}
button:active,button:focus{/**不支持,其實(shí)也好理解,會(huì)觸發(fā)focus()事件,所以也禁用了**/
  color:red
}

一般情況下,使用這種方式是比較好的,天然的禁用屬性,兼容性也不錯(cuò)

2. pointer-events:none

這個(gè)屬性應(yīng)該也不陌生,最常見(jiàn)的用法就是禁用一個(gè)按鈕,而且不局限于表單元素,任意元素均可(比如很多人喜歡用的a標(biāo)簽)

button.disabled {
    pointer-events:none;
    user-select:none;/*去除選中效果*/
    color: graytext;
}

這個(gè)屬性用處很多,很多js絞盡腦汁想要過(guò)濾掉的方法,直接就用一行屬性解決,這里就不展開(kāi)了,網(wǎng)上教程很多。

查看這個(gè)demo

長(zhǎng)按事件

原生js中并沒(méi)有長(zhǎng)按事件,通常開(kāi)發(fā)者一般會(huì)順著思路,使用定時(shí)器來(lái)完成

下面是偽代碼

el.onmousedown = function(){
    this.timer && clearTimeout(this.timer);
    this.timer = settimeout(function(){
        //業(yè)務(wù)代碼
    },350)
}
el.onmouseup = function(){
    this.timer && clearTimeout(this.timer);
}

當(dāng)然,可以借助css來(lái)完成,而且效果更好,易于控制

這里為什么說(shuō)是“借助”呢,因?yàn)椴荒芡耆衏ss來(lái)完成,只是利用了某些特性

css3中新增了過(guò)渡和動(dòng)畫(huà)屬性,與之相對(duì)應(yīng)的也預(yù)設(shè)了這些動(dòng)畫(huà)的回調(diào)事件,如下

事件 說(shuō)明
transitionstart 在開(kāi)始過(guò)渡時(shí)觸發(fā)
transitionrun 在進(jìn)行過(guò)渡時(shí)觸發(fā)
transitioncancel 在取消過(guò)渡時(shí)觸發(fā)
transitionend 在完成過(guò)渡后觸發(fā)
animationstart 在 animation 開(kāi)始時(shí)觸發(fā)
animationiteration 在 animation 完成一個(gè)周期時(shí)觸發(fā)
animationend 在 animation 完成時(shí)觸發(fā)
animationcancel 在 animation 取消時(shí)觸發(fā)
有些事件存在兼容性問(wèn)題,有興趣的可以詳細(xì)研究

有了這些事件,要做一個(gè)長(zhǎng)按事件就很容易了,這里有兩種種思路,大家可以腦洞一下

假設(shè)需要延時(shí)1s;

過(guò)渡時(shí)間設(shè)置為1s,調(diào)用transitionend或者animationend

延時(shí)1s,調(diào)用transitionstart或者animationstart

這里以第一種情況transitionend(過(guò)渡比動(dòng)畫(huà)實(shí)現(xiàn)要容易多,代碼也少,優(yōu)先用過(guò)渡)來(lái)實(shí)現(xiàn)

button:hover:active{
  opacity:.99;/**隨便選取一個(gè)不影響頁(yè)面的可以過(guò)渡的樣式**/
  transition:opacity 1s;
}

相應(yīng)的,js需要監(jiān)聽(tīng)transitionend事件,不需要借助定時(shí)器(個(gè)人有點(diǎn)鄙視定時(shí)器的思想^)

el.addEventListener("transitionend",function(){
    //業(yè)務(wù)代碼
})

是不是精簡(jiǎn)很多呢,需要改長(zhǎng)按時(shí)間可以直接通過(guò)css來(lái)控制

這里封裝了一下自定義事件,可以更好的在項(xiàng)目中使用(雖然代碼本身就很少了)。

查看這個(gè)demo

單次點(diǎn)擊事件

jquery中有一個(gè)once(好像是這個(gè))方法,表示綁定一次性事件,點(diǎn)擊一次后就不再生效。

原生js實(shí)現(xiàn)這個(gè)也不復(fù)雜,通常做法就是定義一個(gè)標(biāo)識(shí),點(diǎn)擊后改變一下,下面是偽代碼

el.onclick = function(){
   if(!this.once){
       //業(yè)務(wù)代碼
       this.once = true;
   }
}

借助上面的思路,css也可以實(shí)現(xiàn)類(lèi)似的效果,深究了一番,總結(jié)以下兩個(gè)方法

1.animationend

animationend是動(dòng)畫(huà)結(jié)束后觸發(fā),顯然我們可以在這里做文章

比如我們可以在初始狀態(tài)給一個(gè)暫停狀態(tài)animation-play-state:paused,然后在點(diǎn)擊時(shí)運(yùn)動(dòng)animation-play-state:running,結(jié)束后一直保持在最后狀態(tài)animation-fill-mode: forwards

.button{
  animation: once .01s paused forwards;/**給一個(gè)足夠小的運(yùn)動(dòng)時(shí)間,確保能夠在`:active`時(shí)運(yùn)動(dòng)完成**/
}
.button:hover:active{
  animation-play-state:running;
}
@keyframes once {
  to{
    opacity:.8;
  }
}

js只需要對(duì)animationend進(jìn)行監(jiān)聽(tīng)

el.addEventListener("animationend",function(){
    //業(yè)務(wù)代碼
})

2.純css實(shí)現(xiàn)

不知道在上面的例子中有沒(méi)有發(fā)現(xiàn),在動(dòng)畫(huà)結(jié)束時(shí)把元素禁用會(huì)怎么樣?

@keyframes once {
  to{
    opacity:.8;
    pointer-events:none;
    user-select:none;
  }
}

這樣就可以在運(yùn)動(dòng)完直接禁用,好像很完美?

事實(shí)上,這里運(yùn)動(dòng)的時(shí)間很難把控,大家都知道,onclick其實(shí)是包含按下和抬起兩個(gè)過(guò)程的,如果抬起的太慢,那么此時(shí)元素已經(jīng)禁用了,觸發(fā)不了事件;如果抬起太快,如果快速點(diǎn)擊,由于還沒(méi)運(yùn)動(dòng)完成,會(huì)觸發(fā)多次事件。

解決方式也很簡(jiǎn)單,用onmousedown代替即可

查看這個(gè)demo

onresize事件

大家都知道window有個(gè)onresize事件,可以在窗口拉伸的時(shí)候觸發(fā),然后就能實(shí)時(shí)獲取窗體的尺寸等等屬性。

window.onresize = function(ev){
   //業(yè)務(wù)代碼
}

但是,普通的元素卻沒(méi)有這個(gè)監(jiān)聽(tīng),比如

div.onresize = function(ev){
   //不生效...
}

為什么需要這個(gè)功能呢?

大家可能知道有這樣一個(gè)屬性,可以原生拉伸元素,改變尺寸

.box{
    overflow: hidden;/**需要配合overflow才能生效**/
    resize: both;
}

只需一個(gè)屬性,就可以實(shí)現(xiàn)元素的拉伸(雖然稍有瑕疵),不需要大量的js來(lái)計(jì)算。

視覺(jué)展示還好,但是如果需要實(shí)時(shí)知道元素的尺寸怎么辦呢,js通常有兩種思路

1. onmousemove事件

拉伸的時(shí)候很自然的想到是有鼠標(biāo)按住然后拖拽完成,所以可以給元素添加onmouse-*一系列事件,同時(shí)要注意鼠標(biāo)抬起要取消監(jiān)聽(tīng)

//大概是這樣的邏輯
div.onmousedown = function(){
    div.onmousemove = fn;//監(jiān)聽(tīng)
    div.onmouseup = function(){
        div.onmousemove = null;
    }
}

2. 定時(shí)器

借助setInterval或者requestAnimFrame來(lái)實(shí)現(xiàn)監(jiān)聽(tīng),同樣是需要注意取消監(jiān)聽(tīng)的時(shí)機(jī)

//大概是這樣的邏輯
div.onmousedown = function(){
    this.timer && clearInterval(this.timer)
    this.timer = setInterval(fn,300);//監(jiān)聽(tīng)
    div.onmouseup = function(){
        this.timer && clearInterval(this.timer)
    }
}

很顯然,上面的方法都不是特別的舒適,很多情況下都會(huì)出現(xiàn)監(jiān)聽(tīng)取消的問(wèn)題,導(dǎo)致不停的觸發(fā),影響體驗(yàn)。

這時(shí)候,又輪到css出場(chǎng)了,很多時(shí)候js覺(jué)得實(shí)現(xiàn)起來(lái)不順暢的時(shí)候都可以用css的思維來(lái)重新認(rèn)識(shí)。

那么,如何借助css來(lái)監(jiān)聽(tīng)這些呢?

可以從過(guò)渡和動(dòng)畫(huà)兩個(gè)思路來(lái)考慮。

1. CSS過(guò)渡

首先,我們可以知道的是,在通過(guò)resize: both進(jìn)行元素拉伸的時(shí)候,改變的是widthheight,這一點(diǎn)可以從開(kāi)發(fā)者工具直接看到

我們需要通過(guò)transitionrun或者transitionend來(lái)監(jiān)聽(tīng)widthheight,所以需要給這兩個(gè)屬性加上過(guò)渡

.box{
   transition:width .3s,ehight .3s;//分別給width和height設(shè)置過(guò)渡,其他屬性不需要
}

這樣就可以拿到監(jiān)聽(tīng)了,不過(guò)這種方式有一個(gè)弊端,由于過(guò)渡需要時(shí)間,所以有一種不跟隨,卡頓的感覺(jué)。

所以我們來(lái)看第二種方式

2. animationiteration

css動(dòng)畫(huà)可以設(shè)置播放次數(shù),如果設(shè)置成animation-iteration-count: infinite就表示無(wú)限輪播,配合animationiteration回調(diào),不就可以實(shí)現(xiàn)監(jiān)聽(tīng)了么

.box:active{
    animation: resize .3s infinite forwards;
}

@keyframes resize{
    to {
       opacity: .99;/**用一個(gè)無(wú)關(guān)緊要的屬性來(lái)觸發(fā)動(dòng)畫(huà)**/
    }
}

js很簡(jiǎn)單,一個(gè)監(jiān)聽(tīng)就能解決問(wèn)題,也不需要什么取消監(jiān)聽(tīng)什么,這些都已經(jīng)在css完成了

el.addEventListener("animationiteration",function(){
    //業(yè)務(wù)代碼
})

這里是每個(gè)動(dòng)畫(huà)完成一次就回調(diào)一次,所以我們可以通過(guò)設(shè)置動(dòng)畫(huà)時(shí)長(zhǎng)來(lái)控制監(jiān)聽(tīng)的頻率,比如上面是.3s的觸發(fā)頻率。

下面寫(xiě)了一個(gè)demo,可以實(shí)現(xiàn)自定義onresize事件

查看這個(gè)demo

小節(jié)

以上通過(guò)借助css,實(shí)現(xiàn)了許多js都很棘手的問(wèn)題,可能還會(huì)有更多的應(yīng)用場(chǎng)景,歡迎小伙伴留言討論~

如果有新的想法,會(huì)第一時(shí)間更新在 https://github.com/XboxYan/no... ,多多關(guān)注

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104275.html

相關(guān)文章

  • 頁(yè)面優(yōu)化的一些建議

    摘要:預(yù)讀取預(yù)讀取是一項(xiàng)使瀏覽器主動(dòng)去執(zhí)行域名解析的功能。在某些圖片較多的頁(yè)面中,在發(fā)起圖片加載請(qǐng)求之前預(yù)先把域名解析好將會(huì)有至少的圖片加載速度提升。但由于域名解析本身也是耗時(shí)的,所以也不是越多越好,最大支持路并發(fā),所以一般設(shè)置個(gè)域名較為合適。 文章本來(lái)是給公司內(nèi)部分享用的,現(xiàn)在發(fā)表出來(lái),歡迎大家提出寶貴建議。 背景目的 讓官網(wǎng)首頁(yè)加載速度更快,對(duì)用戶(hù)的操作響應(yīng)得更及時(shí),給用戶(hù)提供更為友好...

    tommego 評(píng)論0 收藏0
  • 微信小程序開(kāi)發(fā)中的二三事之網(wǎng)易云信IMSDK DEMO

    摘要:傳統(tǒng)的網(wǎng)頁(yè)編程采用的三劍客來(lái)實(shí)現(xiàn),在微信小程序中同樣有三劍客。觀(guān)察者模式不難實(shí)現(xiàn),重點(diǎn)是如何在微信小程序中搭配其特有的生命周期來(lái)使用。交互事件傳統(tǒng)的事件傳遞類(lèi)型有冒泡型與捕獲型,微信小程序中自然也有。 本文由作者鄒永勝授權(quán)網(wǎng)易云社區(qū)發(fā)布。 簡(jiǎn)介為了更好的展示我們即時(shí)通訊SDK強(qiáng)悍的能力,網(wǎng)易云信IM SDK微信小程序DEMO的開(kāi)發(fā)就提上了日程。用產(chǎn)品的話(huà)說(shuō)就是: 云信 IM 小程序 S...

    weij 評(píng)論0 收藏0
  • 可能是最全的前端動(dòng)效庫(kù)匯總

    摘要:非常的龐大,而且它是完全為設(shè)計(jì)而生的動(dòng)效庫(kù)。它運(yùn)行于純粹的之上,是目前最強(qiáng)健的動(dòng)畫(huà)資源庫(kù)之一。可能是創(chuàng)建滾動(dòng)特效最好用的工具,它支持大量的瀏覽器,只要它們支持和特性??梢酝ㄟ^(guò)安裝吊炸天了,接近現(xiàn)實(shí)生活中的物理運(yùn)動(dòng)碰撞慣性動(dòng)畫(huà)庫(kù)。 收集日期為2019-02-28,★代表當(dāng)時(shí)的該項(xiàng)目在github的star數(shù)量 Animate.css 56401 ★ 一個(gè)跨瀏覽器的動(dòng)效基礎(chǔ)庫(kù),是許多基礎(chǔ)動(dòng)...

    afishhhhh 評(píng)論0 收藏0
  • 移動(dòng)端滾動(dòng)研究

    摘要:還會(huì)有一個(gè)性能上的問(wèn)題就是當(dāng)頁(yè)面的列表過(guò)長(zhǎng),元素過(guò)多時(shí),在模擬滾動(dòng),下拉刷新這段時(shí)間內(nèi),頁(yè)面也會(huì)有卡頓現(xiàn)象,這里采取了一個(gè)優(yōu)化策略即列表較長(zhǎng)時(shí)數(shù)量較多時(shí),在觸發(fā)下拉刷新的時(shí)機(jī)時(shí)將頁(yè)面視窗之外的元素隱藏或者存放在里面。 移動(dòng)web滾動(dòng)問(wèn)題 在移動(dòng)端如果使用局部滾動(dòng),意思就是我們的滾動(dòng)在一個(gè)固定寬高的div內(nèi)觸發(fā),將該div設(shè)置成overflow:scroll/auto;來(lái)形成div內(nèi)部的...

    ghnor 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<