現在才發現的小技巧。
簡述
以往要做 File 元件時我都是用 absolute
+ opaicty
的障眼法來把原生元件覆蓋在客制元件上,就能享有原生自動跳出 dialog 的功能。
這邊的 HTML 和 CSS 大概會這樣設計:
1 2 3 4 5 6
| <div class="custom-upload-wrapper"> <div class="custom-upload-element"> <span>Filename goes here...</span> <input class="custom-upload-native" type="file" /> </div> </div>
|
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 28 29
| .custom-upload-wrapper { margin: 20px auto; max-width: 300px; .custom-upload-element { position: relative; display: block; border: 1px solid #033076; border-radius: 4px; padding: 9px 10px; font-size: 14px; color: #021f54; transition: all 0.3s; &:hover { box-shadow: 0 0 0 2px rgba(2, 31, 84, 0.2); } } .custom-upload-native { position: absolute; top: 0; left: 0; width: 100%; height: 100%; cursor: pointer; opacity: 0; z-index: 999; text-indent: -999px; } }
|
不過其實除了這種作法之外,有一個更簡單的技巧是透過 <label>
來處理,這個技巧是把 input file 包在 <label>
裡面,並且設為 display: none
:
1 2 3 4
| <label class="custom-upload-wrapper"> <span class="custom-upload-element">Filename goes here...</span> <input class="custom-upload-native" type="file" /> </label>
|
你會發現神奇的事情發生了,照理說你應該是沒辦法點擊到 input 的,不過因為 label
的特性就是會把事件反應到對應的 input 元件上,所以即便設為 display: none
也一樣能觸發 dialog 的功能!
所以 CSS 可以簡化許多:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| .custom-upload-wrapper { display: block; margin: 20px auto; max-width: 300px; .custom-upload-element { display: block; border: 1px solid #033076; border-radius: 4px; padding: 9px 10px; font-size: 14px; color: #021f54; transition: all 0.3s; cursor: pointer; &:hover { box-shadow: 0 0 0 2px rgba(2, 31, 84, 0.2); } } .custom-upload-native { display: none; } }
|
現在事情好辦了,你完全不需要對原生元件做額外處理,只要專注在你的客制元件上就行了。
這邊的實際範例可以到 Codepen 上參考。