我试图让textarea看起来像一个密码字段。在webkit浏览器中,我找到了以下属性来实现它
-webkit-text-security : circle
但它在其他浏览器中不起作用。任何跨浏览器的替代方案......?
答案 0 :(得分:2)
您可以使用JS,定义变量并在其中存储textarea值,并用任何特殊字符替换textarea中的内容。您将在JS变量中拥有实际值,可用于提交表单或验证等。
为此,您可以为keydown
事件编写函数。
答案 1 :(得分:1)
答案 2 :(得分:0)
可以做到,但是实现并不简单。这个想法是使用一个不可见的password=true
输入元素作为textarea密码屏蔽版本的状态/代理,并使用JS在显示/隐藏时切换一个带有真实textarea的密码屏蔽(伪)文本区域。
注意事项:intgr对similar question州的评论,
不幸的是,这很快变得很难看。普通密码字段 还允许在中间进行修改,复制,剪切,拖放, 以及其他我无法想到的行为。模拟所有 这些忠实的即使可能,也不值得 麻烦。
我的实现通过使用密码屏蔽的(伪造)文本区域中的单击或箭头键以编程方式禁用文本导航,从而避免了这种复杂性。真实的textarea可以在其中导航和编辑,因此在UX方面损失很小。
在下面查看我的实现
// element handles
const inp = document.getElementById("input-el");
const fta = document.getElementById("fake-textarea-el");
const ftac = document.getElementById("fake-textarea-el-content");
const rta = document.getElementById("real-textarea-el");
const toggle = document.getElementById("pw-toggle");
// initial text element height
const initialHeightPx = fta.clientHeight + 'px';
// show/hide content flag
let hideContent = true;
// util for minimum textarea height workaround
function textWidth(text) {
const tag = document.createElement('div');
tag.classList.add('hidden');
tag.style.whiteSpace = 'nowrap';
tag.innerHTML = text;
document.body.appendChild(tag);
const result = tag.clientWidth;
document.body.removeChild(tag);
return result;
}
function setTextArea(content = '') {
// update all text elements
ftac.innerHTML = content.replace(/./g, '•');
inp.value = content;
rta.value = content;
// workaround to use CSS height for minimum
// textarea height
let newHeight = initialHeightPx;
if (textWidth(content) > rta.clientWidth) {
rta.style.height = 'auto';
newHeight = rta.scrollHeight + 'px';
}
rta.style.height = newHeight;
}
function handleInput(e) {
const {target: {value}} = e;
setTextArea(value);
}
inp.oninput = handleInput;
rta.oninput = handleInput;
fta.onfocus = e => {
inp.focus();
fta.classList.add('has-focus');
ftac.classList.remove('has-selectall');
}
inp.onblur = e => {
// deselect input contents
inp.selectionStart = inp.selectionEnd = -1;
fta.classList.remove('has-focus');
ftac.classList.remove('has-selectall');
}
inp.onkeydown = e => {
const {charCode, keyCode, target: {value}} = e;
const code = keyCode || charCode;
// prevent arrow keys
if (code >= 37 && code <= 40) {
e.preventDefault();
}
// handle ctrl/meta key combinations
if ((e.metaKey || e.ctrlKey)) {
switch (e.key) {
case 'a':
e.preventDefault();
inp.setSelectionRange(0, inp.value.length)
fta.classList.remove('has-focus');
ftac.classList.add('has-selectall');
break;
default:
}
} else if (ftac.classList.contains('has-selectall')) {
fta.classList.add('has-focus');
ftac.classList.remove('has-selectall');
}
}
// handle show/hide toggle
toggle.onclick = e => {
hideContent = !hideContent;
if (hideContent) {
rta.classList.add('hidden');
fta.classList.remove('hidden');
toggle.innerHTML = 'Show';
} else {
fta.classList.add('hidden');
rta.classList.remove('hidden');
toggle.innerHTML = 'Hide';
}
}
/* SETUP BEGIN */
* {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
main {
align-items: center;
display: flex;
height: 100vh;
justify-content: center;
}
button {
height: 24px;
margin: 18px;
width: 60px;
}
/* SETUP END */
#fake-textarea-el, #real-textarea-el {
border: none; /* remove user-agent textarea border */
box-shadow: 0 0 0 1px black;
box-sizing: border-box;
display: block;
height: 24px;
line-height: 18px;
margin: 0;
padding: 2px;
resize: none;
width: 150px;
word-wrap: break-word;
}
#fake-textarea-el {
height: auto;
min-height: 24px;
}
.hidden {
position: absolute;
bottom: 0px;
z-index: -1000;
opacity: 0;
pointer-events: none;
}
.has-selectall {
/* default selection bg on MacOS + Chrome */
background: #ACCEF7;
}
.cursor {
border-right: 1px solid transparent;
height: 1rem;
}
.has-focus .cursor {
animation: cursorBlink 1.14s forwards infinite;
}
@keyframes cursorBlink {
0% {
border-color: transparent;
}
50% {
border-color: transparent;
}
51% {
border-color: black;
}
100% {
border-color: black;
}
}
<main>
<input id="input-el" class="hidden" type="password" />
<div id="fake-textarea-el" contenteditable>
<span id="fake-textarea-el-content"></span><span class="cursor"></span>
</div>
<textarea id="real-textarea-el" class="hidden"></textarea>
<button id="pw-toggle">Show</button>
</main>