最近在作後臺有一個需求是點擊圖文生成一個二維碼,手機掃碼以後進入特定頁面進行操做,廢話很少說拿起鍵盤就是幹,不過不出所料果真在安卓下遇到了坑,使用
fixed
定位在底部的登陸按鈕在遇到輸入框獲取焦點展開鍵盤後發生了重疊,下面就是踩坑過來的總結。javascript
首先看一下兼容性 css
:focus-within
,能夠簡單理解成它是
focus
的升級版,最大的區別在於它能夠捕捉冒泡的
focus
,舉一個例子來理解。
<div class="item">
<label for="name">input獲取焦點我會加粗</label>
<input type="text" id="name" />
</div>
<style> .item:focus-within label { font-weight: 600; } </style>
複製代碼
在不使用:focus-within
的狀況下咱們要讓 label 樣式放生變化,常見的改變 input 和 label 的位置以後經過定位的方式讓其展現是正常的,以後經過 :focus + 兄弟選擇器
來實現,如今只要一行代碼就能夠實現了,是否是很感動呢。html
說了這麼多,咱們上面的例子怎麼用:focus-within
實現呢? 首先縷一下思路,最簡單的方法固然是全局使用:focus-within
以後更改登陸按鈕的來實現,不過這樣可能致使 a 連接獲取焦點也會生效。java
因此下面用一個標籤將元素包裹起來以後經過兄弟兄弟選擇器來實現node
<!-- React的jsx不過並不影響觀看 -->
<div className="App">
<div className="item focus">
<label htmlFor="name">用戶名</label>
<input type="text" id="name" />
</div>
<div className="item focus">
<label htmlFor="password">密碼</label>
<input type="password" id="password" />
</div>
<pre className="content">
<!-- 內容文章,先屏蔽掉 -->
</pre>
<div className="item change">
<button className="btn">登陸</button>
</div>
</div>
複製代碼
css,只放關鍵代碼app
.focus:focus-within ~ .change .btn {
position: static;
/* 方便看出效果 */
color: red;
}
複製代碼
撒花,這裏咱們實現了第一種方法,不過能夠看的出來對於頁面的佈局仍是有必定要求的,若是你肯定頁面沒有多餘的元素能夠直接使用.focus:focus-within
來操縱元素。佈局
這一種方法兼容性最好,常見的就是經過這種方法實現,經過監聽元素獲取焦點和失去焦點來處理登陸按鈕的 css 樣式,固然也能夠經過 resize 事件,具體看你的使用場景,這裏用focus
的方法實現。flex
注意,focus、blur
不會觸發冒泡事件,這裏改用focusin、focusout
來實現。ui
const btn = document.querySelector(".btn");
const app = document.querySelector(".app");
// 得到焦點
app.addEventListener("focusin", function(e) {
const target = e.target;
if (target.nodeName !== "INPUT") {
return;
}
btn.style.position = "static";
});
// 失去焦點
app.addEventListener("focusout", function(e) {
const target = e.target;
if (target.nodeName !== "INPUT") {
return;
}
btn.style.position = "fixed";
});
複製代碼
開拓思路不錯,不過實際項目中使用價值不高spa
這一種方法對頁面的高度有要求,不能超過一屏,超出以後按鈕確定會在下方展現,這種方法的實現思路是利用 flex 的彈性盒子,經過改變流向從上往下以後給內容區域設置flex:1
來保證自適應。 這裏給一個簡單的示例,
<div class="root">
<form class="form">
<label >用戶名:
<input type="text" />
</label>
<div class="box"></div>
</form>
<button class="btn">登陸</button>
</div>
<style> html, body { height: 100%; margin: 0; padding: 0; } .root { height: 100%; display: flex; flex-direction: column; } .form { flex: 1; } .btm { width: 100%; } .box { height: 80vh; background: #333; } </style>
複製代碼
稍微總結一下,若是對項目兼容性要求不高推薦使用:focus-within
實現,若是須要兼容或者須要定製更多細節那仍是老老實實的使用javascript
吧