(还记得是过年休息前一周!运营们突然想做活动了,和老板们一拍即合出了一个方案,身为公司唯一前端义不容辞,加班加点 3 天搞定了。最近时间还算充沛,来总结一下这看似简单实施起来坑不断,兼容性问题不断的鬼东西!!!–本篇只是冰山一角,未来这段时间的这套总结,一定会对一群人有帮助,如果你碰巧看到了,觉得还不错,就关注俺吧,xixi ~)
本文原需求:1、一个宽两列的输入框,竖向输入文字;2、当文字数量小小于等于 6 时,文字居中一列显示并且字号大,当文字数量大于 6 时,呈两列显示且字号小;3、移动双端兼容;4、还有一些日常的输入展示相关的用户体验(正则控制,此部分略过)
第一反应就是用 div 模拟 input 吧
来吧,模拟一下
<div class="inputArea">
<input type="text" v-model="items" ref="type" class="input" />
<div class="ready" v-show="this.showReady">输入文本</div>
<div class="textArea1" v-show="this.showWhich">{{ items }}</div>
<div class="textArea2" v-show="!this.showWhich">{{ items }}</div>
</div>
data() {
return {
items: "",
showWhich: true,
showReady: true,
};
},
.inputArea {
width: 80px;
height: 300px;
// border: solid 1px green;
position: relative;
}
.ready {
writing-mode: tb-lr;
-webkit-writing-mode: vertical-lr;
table-layout: vertical-ideographic;
width: 40px;
height: 300px;
line-height: 40px;
/* border: solid 1px black; */
overflow: hidden;
position: absolute;
top: 0;
left: 20px;
opacity: 0.5;
font-size: 40px;
color: #ff8cfe;
letter-spacing: 0;
line-height: 40px;
}
.input {
width: 300px;
height: 80px;
background: transparent;
color: rgba(0, 0, 0, 0.1);
border: 1px solid pink;
font-size: 20px;
z-index: 2;
position: absolute;
top: -80px;
left: 0;
transform-origin: 0 bottom;
transform: rotateZ(90deg);
// /* Safari */
-webkit-transform: rotateZ(90deg);
// /* Firefox */
-moz-transform: rotateZ(90deg);
// /* Internet Explorer */
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}
.textArea1 {
writing-mode: tb-lr;
-webkit-writing-mode: vertical-lr;
table-layout: vertical-ideographic;
width: 40px;
height: 300px;
line-height: 40px;
// border: solid 1px black;
overflow: hidden;
position: absolute;
top: 0;
left: 20px;
}
.textArea2 {
writing-mode: tb-lr;
-webkit-writing-mode: vertical-lr;
table-layout: vertical-ideographic;
width: 80px;
height: 300px;
line-height: 40px;
border: solid 1px red;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
}
这里是安卓和 ios 各 3 张的效果图:
eg1
eg2
eg3
eg4
eg5
eg6
是不是以为自己搞定了?NO!在测试过后你会发现,由于每次 focus 聚焦依赖的是 input,造成的问题就是用户实际添加或删除文字的位置会和所预想的不一致!所以想到了两种解决方案:1、主动介入帮助光标定位。2、不依赖 input,直接对 div 进行编辑。
介入帮助光标定位稍后再说,先说竖向输入并展示的方案二,直接对 div 进行操作
备案对 div 做编辑和展示的限制
没错,这里用到了上面说的div如何竖向展示文字:
<div
class="test"
contenteditable="true"
placeholder="输入文本"
@keyup="checkLimitLength($event)"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"
>
</div>
checkLimitLength(e) {
let vals = e.target.innerHTML;
let val = vals.replace(/[^\u4E00-\u9FA5]/g, "");
let valArr = val.split("");
console.log(vals, val, valArr.length);
if (valArr.length > 12) {
e.target.blur();
e.target.innerHTML = val.substr(0, 13);
}
},
.test {
width: 80px;
height: 300px;
line-height: 40px;
writing-mode: tb-lr;
-webkit-writing-mode: vertical-lr;
table-layout: vertical-ideographic;
overflow: hidden;
border: royalblue solid 1px;
}
.test:empty:before {
content: attr(placeholder);
color: #bbb;
}
.test:focus:before {
content: none;
}
这里只是原理展示,其实div+可编辑不可控性太强了,比如甚至图片都能直接放进去,以我们的ui要求,交互要求来看用这种方案无疑是给自己找罪受。当然如果你只是简单的没有其他要求的为了实现竖向而实现,也是可以用的!
而且,凭借着回忆好像这种contenteditable可编辑div也会有光标问题,当时是怎么聚焦光标都会在第一个字上面!可真是太头疼了,巧了,第一种方案咱们不也有一种主动介入光标聚焦的想法么,就来实现一下只要聚焦就把光标设置在最后吧.
(写这篇的时候我又试了这个可编辑div,没有出现光标跑头上的情况了,我也不知道是因为写得简单demo还是因为什么别的,没有这种现象是好事,但我还是不建议用div,因为div太自由了!)
可编辑div光标永远在第一个字头上解决-定位到最后
声明,这次写demo发现这个问题没有了,而且对focus的操作也失效了,但还是贴出来吧,等谁遇到的时候再试试吧。
<div
class="test"
id="myinput"
ref="myinput"
contenteditable="true"
placeholder="输入文本"
@input="checkLimitLength($event)"
@click="openInput()"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"
>
</div>
moveCursorToEnd(id) {
setTimeout(() => {
var el = document.getElementById(id);
el.focus();
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}, 0);
},
openInput() {
this.$nextTick((x) => {
this.$refs.myinput.focus();
this.moveCursorToEnd("myinput");
});
},
终于,可以竖着实时为大家进行操作了,但是,设备问题出来咯~,
部分安卓机型的键盘在拉起后,会把H5页面挤压变形!
更多神坑,更多精彩,关注后续~