簡體   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