Electron點(diǎn)擊穿透不規(guī)則窗體的透明區(qū)域的實(shí)現(xiàn)
實(shí)現(xiàn)一個(gè)不規(guī)則窗體
這里我們實(shí)現(xiàn)一個(gè)圓形窗體,實(shí)現(xiàn)其他形狀的窗體與這個(gè)方法類(lèi)似。
首先,把窗口的高度(height)和寬度(width)值修改為相同的值,使窗口成為一個(gè)正方形。
其次,把窗口的透明屬性(transparent)設(shè)置為true,這樣設(shè)置之后窗口還是正方形的,但只要我們控制好內(nèi)容區(qū)域的Dom元素的形狀,就可以讓窗口看起來(lái)像一個(gè)不規(guī)則形狀一樣。
不規(guī)則窗口往往需要自定義邊框和標(biāo)題欄,所以frame也設(shè)置為false。
另外,透明的窗口不可調(diào)整大小。所以將resizable屬性設(shè)置為false。
窗口顯示后,為了防止雙擊窗口可拖拽區(qū)觸發(fā)最大化事件,我們把maximizable屬性也設(shè)置為false。
最終創(chuàng)建窗口的代碼如下:
win = new BrowserWindow({ width: 380, height: 380, transparent: true, frame: false, resizable: false, maximizable: false, //... })
接下來(lái)再修改樣式,使內(nèi)容區(qū)域的Dom元素呈現(xiàn)一個(gè)圓形:
html,body { margin: 0px; padding: 0px; pointer-events: none; } #app { box-sizing: border-box; width: 380px; height: 380px; border-radius: 190px; border: 1px solid green; background: #fff; overflow: hidden; pointer-events: auto; }
上面樣式代碼中通過(guò)border-radius樣式把#app元素設(shè)置成了圓形。border-radius負(fù)責(zé)定義一個(gè)元素的圓角樣式,如果圓角足夠大,整個(gè)DIV就變成了一個(gè)圓形。
pointer-events樣式,在后面會(huì)有講解。
最終實(shí)現(xiàn)的窗口界面如圖5-7:
如果你略微了解CSS,你會(huì)知道除了圓形,你還可以通過(guò)CSS樣式控制這個(gè)窗口成為任意其他形狀。
點(diǎn)擊穿透透明區(qū)域
上面這個(gè)應(yīng)用會(huì)有一點(diǎn)小問(wèn)題,雖然窗口看起來(lái)是圓形的,但它其實(shí)還是一個(gè)正方形窗口,只不過(guò)正方形四個(gè)角是透明的,所以看起來(lái)像一個(gè)圓形的窗口。
當(dāng)我點(diǎn)擊下圖中的①區(qū)域內(nèi)的文本文件時(shí),鼠標(biāo)的點(diǎn)擊事件還是發(fā)生在本窗口內(nèi),而不會(huì)點(diǎn)擊到那個(gè)文件上。
作為開(kāi)發(fā)者,我們知曉其中的道理,但作為用戶(hù)來(lái)說(shuō),這就顯得很詭異。為了達(dá)到更好的用戶(hù)體驗(yàn),我們需要讓鼠標(biāo)在這4個(gè)區(qū)域發(fā)生點(diǎn)擊動(dòng)作時(shí),點(diǎn)擊動(dòng)作可以穿透本窗口,落在窗口后面的內(nèi)容上。
Electron官方文檔明確說(shuō)“不能點(diǎn)擊穿透透明區(qū)域”,這并沒(méi)有難倒我們,有一個(gè)小trick來(lái)解決這個(gè)問(wèn)題。
首先,需要用到窗口對(duì)象的setIgnoreMouseEvents方法,該方法可以使窗口忽略窗口內(nèi)的所有鼠標(biāo)事件,并且在此窗口中發(fā)生的所有鼠標(biāo)事件都將被傳遞到此窗口背后的內(nèi)容。
如果調(diào)用該方法時(shí)傳遞了forward參數(shù),如:
setIgnoreMouseEvents(true, { forward: true }),
則只有點(diǎn)擊事件會(huì)穿透窗口,鼠標(biāo)移動(dòng)事件仍會(huì)觸發(fā)。
基于此,我們?cè)陧?yè)面中執(zhí)行如下代碼:
const remote = require("electron").remote; let win = remote.getCurrentWindow(); window.addEventListener("mousemove", event => { let flag = event.target === document.documentElement; if (flag){ win.setIgnoreMouseEvents(true, { forward: true }); } else { win.setIgnoreMouseEvents(false); } }); win.setIgnoreMouseEvents(true, { forward: true });
注意,這是實(shí)驗(yàn)代碼,所以用了remote模塊,關(guān)于remote模塊的一些問(wèn)題,我在“Electron團(tuán)隊(duì)為什么要干掉remote模塊“有詳細(xì)描述。
上面的代碼中,設(shè)置窗口對(duì)象監(jiān)聽(tīng)mousemove事件,當(dāng)鼠標(biāo)移入窗口圓形內(nèi)容區(qū)的時(shí)候,不允許鼠標(biāo)事件穿透。當(dāng)鼠標(biāo)移入透明區(qū)時(shí),允許鼠標(biāo)事件穿透。
接著我們?yōu)閔tml,body元素增加樣式:pointer-events: none,為#app元素增加樣式pointer-events: auto。
設(shè)定pointer-events: none后,其所標(biāo)志的元素就永遠(yuǎn)不會(huì)成為鼠標(biāo)事件的target了。
為子元素#app設(shè)置了pointer-events: auto,說(shuō)明子元素#app還是可以成為鼠標(biāo)事件的target的。
也就是說(shuō)除了圓形區(qū)域內(nèi)可以接收鼠標(biāo)事件外,其他部分將不再接收鼠標(biāo)事件。
當(dāng)鼠標(biāo)在圓形區(qū)域外移動(dòng)時(shí),窗口對(duì)象的mousemove事件觸發(fā),event.target為document.documentElement對(duì)象(這個(gè)事件并不是在html或body元素上觸發(fā)的,而是在窗口對(duì)象上觸發(fā)的,document.documentElement就是DOM樹(shù)中的根元素,也就是html節(jié)點(diǎn)所代表的元素)。
至此,上文代碼中的判斷成立,當(dāng)鼠標(biāo)在前文所述四個(gè)區(qū)域移動(dòng)時(shí),鼠標(biāo)事件允許穿透。鼠標(biāo)在圓形區(qū)域移動(dòng)時(shí),鼠標(biāo)事件不允許穿透。
至此,上文所述判斷成立,運(yùn)行程序,鼠標(biāo)在正方形四角區(qū)域內(nèi)點(diǎn)擊,鼠標(biāo)事件具備了穿透效果。
到此這篇關(guān)于Electron點(diǎn)擊穿透不規(guī)則窗體的透明區(qū)域的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Electron點(diǎn)擊穿透內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript入門(mén)系列之知識(shí)點(diǎn)總結(jié)
JavaScript 是屬于網(wǎng)絡(luò)的腳本語(yǔ)言。本文是小編日常收集整理些javascript入門(mén)基礎(chǔ)知識(shí),對(duì)js新手朋友非常有幫助,對(duì)js入門(mén)知識(shí)點(diǎn)感興趣的朋友一起學(xué)習(xí)吧2016-03-03Actionscript與javascript交互實(shí)例程序(修改)
這篇文章主要介紹了Actionscript與javascript交互實(shí)例程序(修改)的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09JavaScript實(shí)現(xiàn)PC端四格密碼輸入框功能
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)PC端四格密碼輸入框功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02微信小程序的數(shù)據(jù)存儲(chǔ)與Django等服務(wù)發(fā)送請(qǐng)求?講解
這篇文章主要為大家介紹了微信小程序的數(shù)據(jù)存儲(chǔ)與Django等服務(wù)發(fā)送請(qǐng)求講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04JavaScript用JSONP跨域請(qǐng)求數(shù)據(jù)實(shí)例詳解
Javascript跨域訪問(wèn)是web開(kāi)發(fā)者經(jīng)常遇到的問(wèn)題,什么是跨域,就是一個(gè)域上加載的腳本獲取或操作另一個(gè)域上的文檔屬性。下面這篇文章主要介紹了JavaScript用JSONP跨域請(qǐng)求數(shù)據(jù)的方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01