【问题标题】:Is it possible to prevent moving the cursor to the start of an input field when type changes?类型更改时是否可以防止将光标移动到输入字段的开头?
【发布时间】:2021-12-30 18:29:24
【问题描述】:

我目前正在创建一个密码字段,其中包含在 React/Ionic 中隐藏或显示密码的选项。

  • 当您更改输入的类型时,我想继续关注密码字段。 (就像PayPay Login page 一样)我正在使用event.preventDefault()mousedown-Event 上进行操作。

const input = document.querySelector('input')

function toggleVisibility() {
  if (input.type === "text")
    input.type = "password"
  else
    input.type = "text"
}

function keepFocus(event) {
  event.preventDefault()
}
<input placeholder="Password" type="text">
<button onmousedown="keepFocus(event)" onclick="toggleVisibility()">Show Password</button>

问题

  • 当我更改输入字段的类型时,光标翻转回输入字段的开头。我想将光标保持在以前的位置。 (再次喜欢PayPal

【问题讨论】:

    标签: javascript html css reactjs forms


    【解决方案1】:

    如果您查看链接到的 PayPal 自己的代码,您会发现只需在单个事件侦听器中调用 input.focus()

          function hidePassword(e) {
              if (baseType === 'tel') {
                  $(field).addClass('tel-password');
              } else {
                  field.setAttribute('type', 'password');
              }
              $(btnShow).removeClass('hide');
              $(btnHide).addClass('hide');
              field.focus();
              e.stopPropagation();
    
              login.logger.log({
                  evt: 'is_pwd_sh',
                  data: 'N',
                  instrument: true
              });
              login.logger.pushLogs();
          }
    

    这可以简化为下面的示例,并进行一些更改:

    • 默认type="" 应始终为password。用户期望密码输入不会突然显示密码 - 他们正在向所有可以看到他们屏幕的人输入密码(尤其是在屏幕共享或投影到电视或进行演示等时) .
    • 我已将querySelector 调用更改为在&lt;button data-for="" /&gt; 中嵌入目标&lt;input type="password" /&gt;,以避免在DOMContentLoaded 事件之前运行querySelectorgetElementById 引起的问题,这在JS 中经常出现sn-ps 人们在互联网上发帖。
    • event.stopPropagation()(在PayPal 的代码中)或event.preventDefault()(在您的代码中)的调用是多余且不必要的。重要的是在更改 HTMLInputElement.type 属性的同一事件处理程序中调用 input.focus()
    • 避免将onmousedown 与按钮一起使用。 'click' 事件适用于所有类型的交互(鼠标、键盘、触摸等),而 'mousedown''mouseclick' 事件仅由 实际 鼠标输入引发(尽管也经常触摸) .

    function toggleVisibilityOnClick( event ) {
        
        const button = event.currentTarget;
        const input = document.getElementById( button.dataset['for'] );
        if( !input ) throw new Error( "Couldn't find password input." );
        
        if( input.type === 'text' ) {
            input.type = 'password';
        }
        else {
            input.type = 'text';
        }
    
        input.focus();
    }
    <input placeholder="Password" type="password" id="pwdInp" />
    <button data-for="pwdInp" onclick="toggleVisibilityOnClick(event)">Show Password</button>

    Microsoft's browsers have -ms-reveal,这会使您的切换变得多余,因此在这种情况下您应该隐藏切换:

    @supports selector(::-ms-reveal) {
        
        input[type="password"] + button[data-for] {
            display: none;
        }
    }
    

    【讨论】:

    • 感谢您的详细介绍。回答!您知道使用onMouseDown preventDefault-选项的解决方案,它不会影响光标位置吗?
    • @Hey 你不应该为此使用onmousedown(因为它比 `onclick' 更难访问),那么你为什么要问呢?
    • @嘿,我已经更新了我的答案,原来stopPropagation()preventDefault() 完全没有必要。
    • 太棒了!感谢更新。我想在我的反应应用程序中使用它,并且 useRef 和 forwardRef 使代码更加“复杂”。仅带有事件的解决方案要简单得多。 (所以我认为这是个人喜好:))
    • @Hey 如果您使用的是 React,那么您根本不应该直接接触 DOM,所以我的代码不会帮助您。
    猜你喜欢
    • 2011-01-08
    • 2020-12-26
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 2019-11-14
    相关资源
    最近更新 更多