繁体   English   中英

如何使 Textarea 像密码字段一样工作

[英]How to make a Textarea act like a password field

我试图让 textarea 看起来像一个密码字段。 在 webkit 浏览器中,我找到了以下属性来实现它

-webkit-text-security : circle    

但它在其他浏览器中不起作用。 任何跨浏览器的替代方案......?

您可以为此使用 JS,定义一个变量并将 textarea 值存储在其中,并用任何特殊字符替换 textarea 中的内容。 您将在 JS 变量中有实际值,可用于提交表单或验证等。

为此,您可以为keydown事件编写一个函数。

可以做到,但实现起来并不简单。 这个想法是使用一个不可见的password=true输入元素作为你的 textarea 的密码屏蔽版本的状态/代理,并使用 JS 在显示/隐藏时使用真正的 textarea 切换密码屏蔽(假)textarea。

需要注意的是: intgr类似问题的评论指出,

不幸的是,这很快就会变得丑陋。 普通的密码字段还允许在中间进行修改、复制-剪切-粘贴、拖放以及可能其他我想不到的行为。 忠实地模仿所有这些,即使可能,也可能不值得麻烦。

我的实现通过在密码屏蔽(假)文本区域中通过单击或箭头键以编程方式禁用文本导航来避免这种复杂性。 然而,真正的 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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM