手機開發webapp的同學一定遇到過這樣問題,如何為醜極了的手機元素應用自定義的樣式。首先,要弄清楚為什麼要定義手機原生控制元件的樣式,就需要看看手機的那些原生框樣式的醜陋摸樣:
android:
ios:
無奈的選擇
看完了這些醜陋的介面元素,我們就可以理解當我們把他們暴露在產品同學的眼中時,那種層層的殺氣了。可以看到,介面元素十分醜陋,產品兄弟是肯定不會接受的。但是,不得不說這些控制元件在觸發後的效果比pc機上的要炫酷。這其中以apple機的滾筒選擇最為出色.以下是它們觸發後呼叫原生控制元件的效果:
android:
ios:
不得不說這些樣式原生彈出樣式是符合我們設計的原則的,因為它即體現了UI介面的友好和體驗度,又不損耗任何web效能,關鍵是我們什麼都不需要做。產品BZJ君看到了,指明要在apple機下要滾筒的效果用來選擇日期或者下來單。如果我們不能解決掉介面文字框的樣式問題,那麼無論後面的效果多炫酷,始終使無法讓人接受的。也許你會想花時間寫類似的效果?我不否認你可以寫出來,但是需要多少時間的工作量呢?也很多人選擇了外掛的方式。通過jq外掛(如果你的專案中沒在使用jq,為了這個效果無奈下載jq和其外掛)來實現,其實是非常吃力不討好的事情。一個是外掛這種東西出了問題或者變換了需求後它會變得異常的不好擴充套件,第二個當然是考慮到資源載入,在手機端尤其需要考慮。因此,選擇外掛是下下策!
解決方法
問題來了,既想要彈出層的炫酷效果,又想自定義控制元件在介面顯示的樣式。怎麼辦呢?露珠曾經嘗試過最簡單的方法去重寫css去改變它們的樣式,但是即使在google若干小時,也沒有找到滿意的結果。露珠也嘗試過-webkit-appearance屬性,但它也顯得不盡如人意。況且我們還需要相容多機型(安卓,蘋果,wp?)。無論如何,走改變原始樣式的路是行不通的。露珠經過一番思考,找到了自認為非常好的解決方法,也是這篇博文的主題:既然控制元件在頁面的樣式不可以改變,那就隱藏它,但是!不是用display:none隱藏,也不是把width和height設定為0,我們希望的是看不到它們的原始樣式,而希望保留對它們的tap和focus事件。但是除了以上的方法,還有什麼能使它們看不見呢?聰明的你一定想到了,對,就是opacit:0, 通過將控制元件的不透明度設定為0,我們可以讓元素繼續讓它留在介面上,並且保持隨時響應focus事件的狀態。我們要做的,是為該控制元件設定為絕對定位,覆蓋在我們自定義樣式的一個element上。這樣,使用者看到的是底下的element,但當他的手去觸碰此element時,他實際觸碰的是完全透明確留在介面上的原生控制元件!如下圖所示:
這還是第一步,接下來我們需要為控制元件繫結響應事件,大多數情況下我們需要繫結的事件都是onchange,一旦選擇完成,就把值複製到自定義的element上去。這樣大功告成了!不管你是通過表單或者post提交,你取到的值依然是控制元件的值,自定義的element只負責顯示,不負責業務!
程式碼實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<html> <head> <style> body{ position: relative; } .front { position: absolute; opacity: 0; height: 30px; width: 180px; } .back { height: 30px; width: 386px; border: 1px dashed #19a39e; line-height: 30px; text-align: center; font-size: 11px; } </style> </head> <body> <input type="date" onchange="document.getElementsByClassName('back')[0].innerHTML = this.value;"> <div class="back">我是自定義element,我上面覆蓋著一層看不見的input</div> </body> </html> |
結束語
產品B君看到了醜陋的東西消失了,ios下的滾筒又炫酷滾起來了,肯定會拍拍你的肩膀說兄弟幹得不錯。這篇博文也不僅僅是關於解決控制元件樣式的問題,在其他類似的情況下,用遮罩層的方法掩蓋你無能為力的地方是值得借鑑的。其實在開發中類似的的小花招很多,只要找到了訣竅和方法,一行程式碼抵得上一萬行程式碼(借用劉震雲的小說名)。雖然是個很小的小花招,大篇幅的用一篇部落格來講解是過於誇張和繁瑣,不過前端開發事無鉅細,希望對遇到類似問題或者將來需要解決的同學有幫助。