最近在作后台有一个需求是点击图文生成一个二维码,手机扫码以后进入特定页面进行操做,废话很少说拿起键盘就是干,不过不出所料果真在安卓下遇到了坑,使用
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
吧