【问题标题】:Disabling Chrome Autofill禁用 Chrome 自动填充
【发布时间】:2013-03-22 05:18:49
【问题描述】:

我在几个表单上遇到了 chrome 自动填充行为的问题。

表单中的字段都有非常常用且准确的名称,例如“email”、“name”或“password”,并且还设置了autocomplete="off"

自动完成标志已成功禁用自动完成行为,在您开始输入时会出现下拉值,但并未更改 Chrome 自动填充字段的值。

除了 chrome 错误地填充输入(例如用电子邮件地址填充电话输入)之外,这种行为是可以的。客户对此进行了投诉,因此已证实它在多种情况下都会发生,而不是作为我在我的机器上本地完成的某事的某种结果。

我能想到的唯一当前解决方案是动态生成自定义输入名称,然后在后端提取值,但这似乎是解决这个问题的一种非常老套的方法。是否有任何标签或怪癖可以改变可用于解决此问题的自动填充行为?

【问题讨论】:

  • 不是重复的。这个处理禁用自动填充,一个处理自动填充颜色的样式...
  • autocomplete="false" 而不是 autocomplete="off" 根据 Kaszoni Ferencz 的回答,投票给它的人。
  • 看看这个问题的答案数量 - 它应该告诉你一些事情:你正在打一场失败的战斗。这不再是 Chrome 的问题,Firefox 等也纷纷效仿。不管你喜不喜欢,你需要接受浏览器行业的决定,表单自动完成是用户的选择——你可以和他们抗争,但你会输。归根结底,您应该问的问题不是,我如何才能颠覆自动完成功能,而是如何创建与自动完成功能兼容的表单。您担心的不是您的安全问题,而是用户。
  • 抱歉,@mindplay.dk 的回复适得其反。我的情况是我的用户已经登录到我的站点,并且站点上的一个页面供他们输入其他系统的帐户/密码信息。当我为他们输入一个新的对话框时,他们对我网站的登录信息被填写,这是完全错误的,如果/当用户无意中输入该信息时会导致问题。这两者没有任何关系彼此。在这种情况下,浏览器正在做一些与用户想要的相反的事情。
  • @mindplay.dk - 我的 Web 应用程序是工作场所的工作流管理应用程序,因此,不,安全问题是我需要担心的,这是最高管理层的要求,必须遵守所有员工,也就是“用户”。然而,要求他们自己设置 Chrome、IE 或任何其他浏览器会在身份验证过程中留下空白,因为他们可以有意或无意地使用自动填充。 A并非所有 Web 应用程序都属于同一类型,具有相同类型的用户或关注点。

标签: html forms google-chrome autocomplete autofill


【解决方案1】:

1 月 20 日 Chrome 更新

上述解决方案(包括添加虚假字段或设置 autocomplete=new-password)均无效。是的,这些 chrome 不会自动完成,但是当您输入密码字段时,它会再次提示密码。

我发现如果您删除密码字段然后再次添加它没有 id 那么 chrome 不会自动填充它并且不会在输入时提示密码。

使用类来获取密码值而不是 id。

对于 Firefox,仍然需要添加一个虚拟元素。

此解决方案还允许基于标志允许/禁止自动完成:

html:

<!-- form is initially hidden, password field has a dummy id and a class 'id' -->
<form id="loginForm" style="display:none;">
   <span>email:</span><input type="text" placeholder="Email" id="loginEmailInputID"/>
   <span>Password:</span><input class="loginPasswordInput" type="password" placeholder="Password" id="justForAutocomplete"/>
</form>

页面加载:

function hideAutoComplete(formId) {
    let passwordElem=$('#'+formId+' input:password'), prev=passwordElem.prev();
    passwordElem.remove();
    prev.after($('<input type="password" style="display:none">'), passwordElem.clone().val('').removeAttr('id'));
}

if (!allowAutoComplete) hideAutoComplete('loginForm');
$('#loginForm').show();

当你需要密码时:

$('.loginPasswordInput').val();

【讨论】:

    【解决方案2】:

    由于 display none 似乎不再起作用 添加

    <input type="text" name="fakeusernameremembered"/>
    <input type="password" name="fakepasswordremembered"/>
    

    在隐藏溢出的 div 中,最大宽度和最大高度为 0px

    所以它变成了这样的:

    <div style="overflow: hidden; max-width: 0px; max-height: 0px;">
        <input type="text" name="fakeusernameremembered"/>
        <input type="password" name="fakepasswordremembered"/>
    </div>
    

    【讨论】:

    • 这不起作用,输入,假的和新的都是黄色自动完成的:(
    • 仍然对我有用,你能提供更多关于你在做什么的细节吗?另外:您是否将带有隐藏输入的 div 放在可见输入之前?
    【解决方案3】:

    Mike Nelsons 提供的解决方案在 Chrome 50.0.2661.102 m 中对我不起作用。 只需添加具有 display:none 设置的相同类型的输入元素不再禁用本机浏览器自动完成。现在需要复制您希望禁用自动完成的输入字段的名称属性。

    此外,为避免输入字段在表单元素中时重复,您应该在未显示的元素上放置禁用。这将阻止该元素作为表单操作的一部分提交。

    <input name="dpart" disabled="disabled" type="password" style="display:none;">
    <input name="dpart" type="password">
    <input type="submit">
    

    【讨论】:

    • 对于 2016 年 6 月和 Chrome 51.0.2704.106 m,这是这里唯一可行的解​​决方案
    • 但是表单会选择您需要的正确(可见)输入字段吗?因为是同名。
    • @Vaia,将 disabled 属性添加到重复元素将阻止它被提交。
    【解决方案4】:

    你必须添加这个属性:

    autocomplete="new-password"
    

    来源链接:Full Article

    【讨论】:

    【解决方案5】:

    尝试在值中添加一个空格:

    <input type="email" name="email" value="&nbsp;">
    <input type="password" name="password" value="&nbsp;">
    

    铬 54.0.2840.59

    【讨论】:

    • 这会将不间断的空间插入到输入中。
    【解决方案6】:

    在 Chromium 53.0.2785.92(64 位)上,以下工作

    <div style="visibility:hidden">
        <input type="text" name="fake_username_remembered">
        <input type="password" name="fake_password_remembered">
    </div>
    

    display:none 不起作用

    【讨论】:

      【解决方案7】:

      以前输入的由 chrome 缓存的值显示为下拉选择列表。这可以通过 autocomplete=off 禁用,在 chrome 的高级设置中显式保存的地址会在地址字段获得焦点时弹出自动填充弹出窗口。这可以通过 autocomplete= 禁用“false”。但它会允许 chrome 在下拉列表中显示缓存的值。

      在输入的 html 字段上,以下两者都将关闭。

      Role="presentation" &amp; autocomplete="off"

      在为地址自动填充选择输入字段时,Chrome 会忽略那些前面没有标签 html 元素的输入字段。

      为了确保 chrome 解析器忽略自动填充地址弹出的输入字段,可以在标签和文本框之间添加隐藏按钮或图像控件。这将破坏自动填充的标签输入对创建的 chrome 解析序列。 解析地址字段时忽略复选框

      Chrome 还考虑标签元素上的“for”属性。可以用来打断chrome的解析顺序。

      【讨论】:

      • 我爱你。此页面上唯一有效的解决方案。
      • 这对我有用,但只在 Chrome 上测试过。
      • 我单独尝试了 autocomplete="off" 不起作用,在添加了 role="presentation" 之后,它就起作用了
      【解决方案8】:
      <input readonly onfocus="this.removeAttribute('readonly');" type="text">
      

      为标签添加只读属性以及删除它的 onfocus 事件修复了问题

      【讨论】:

        【解决方案9】:

        autocomplete="new-password" 添加到密码字段的最新解决方案非常适合防止 Chrome 自动填充它。

        但是,正如 sibbl 所指出的,这并不妨碍 Chrome 在表单提交完成后要求您保存密码。从 Chrome 51.0.2704.106 开始,我发现您可以通过添加一个同样具有属性 autocomplete="new-password" 的不可见虚拟密码字段来完成此操作。请注意,“display:none”在这种情况下不起作用。例如在真实密码字段之前添加类似这样的内容:

        <input type="password" autocomplete="new-password" 
        style="visibility:hidden;height:0;width:1px;position:absolute;left:0;top:0">`
        

        这仅在我将宽度设置为非零值时才对我有用。感谢 tibalt 和 fareed namrouti 的原始答案。

        【讨论】:

        • 此解决方案之所以有效,是因为它做了两件事:1. 防止 chrome 在真实密码字段下显示“使用密码”;2. 防止 chrome 询问您是否要保存更新的密码(因为标记为“新密码”的隐藏密码字段没有值)
        【解决方案10】:

        通过添加“display: none;”来隐藏它的方法如果表单是通过 javascript 生成的,那么输入对我不起作用。

        所以我把它们放在看不见的地方,让它们不可见:

        <input style="width:0;height:0;opacity:0;position:absolute;left:-10000px;overflow:hidden;" type="text" name="fakeusernameremembered"/>
        <input style="width:0;height:0;opacity:0;position:absolute;left:-10000px;overflow:hidden;" type="password" name="fakepasswordremembered"/>
        

        【讨论】:

          【解决方案11】:

          我想我会发布我的修复。发现你不能使用 display:none 所以我想出了一个快速而肮脏的解决方案,只是让假输入变小并将其移出视线。到目前为止一切顺利,直到他们再次打破它。

                              &lt;input id="FakePassword" type="password" style="float:left;position:relative;height:0;width:0;top:-1000px;left:-1000px;" /&gt;

          【讨论】:

            【解决方案12】:

            显然,针对此问题的最佳修复/黑客方法现在不再有效。我使用的 Chrome 版本是 49.0.2623.110 m,我的帐户创建表单现在显示与表单无关的已保存用户名和密码。谢谢铬!其他黑客似乎很可怕,但这种黑客不那么可怕......

            为什么我们需要这些 hacks 工作是因为这些表单通常是帐户创建表单,即不是应该允许填写密码的登录表单。您不希望删除用户名和密码的麻烦的帐户创建表格。从逻辑上讲,这意味着永远不会在渲染时填充密码字段。所以我使用了一个文本框和一些 javascript。

            <input type="text" id="password" name="password" />
            
            <script>
                setTimeout(function() {
                    $("#password").prop("type", "password");
                }, 100); 
                // time out required to make sure it is not set as a password field before Google fills it in. You may need to adjust this timeout depending on your page load times.
            </script>
            

            我认为这是可以接受的,因为用户不会在短时间内访问密码字段,并且如果该字段是密码字段,则回发到服务器没有任何区别,因为它无论如何都是以纯文本形式发回的。

            警告: 如果像我一样,您使用与更新表单相同的创建表单,事情可能会变得棘手。我使用 mvc.asp c#,当我使用 @Html.PasswordFor() 时,密码不会添加到输入框中。这是一件好事。我已经对此进行了编码。但是使用@Html.TextBoxFor() 并且密码会被添加到输入框中,然后隐藏为密码。但是,由于我的密码是散列的,输入框中的密码是散列密码,永远不应该发回服务器 - 意外保存散列散列密码对于尝试登录的人来说会很痛苦。基本上.. .如果使用这种方法,记得在输入框渲染之前将密码设置为空字符串。

            【讨论】:

            • 最适合我。谢谢你。
            【解决方案13】:

            它是如此简单和棘手:)

            google chrome 基本上会在&lt;form&gt;&lt;body&gt;&lt;iframe&gt; 标签内搜索每一个可见的密码元素,以便为它们启用自动填充功能,因此要禁用此功能,您需要添加一个虚拟密码元素如下:

              • 如果您的密码元素位于&lt;form&gt; 标签内,您需要将虚拟元素作为表单中的第一个元素紧跟在&lt;form&gt; 打开标签之后

              • 如果您的密码元素不在&lt;form&gt; 标记内,则将虚拟元素作为您的html 页面中的第一个元素,紧跟在&lt;body&gt; 打开标记之后

            1. 您需要隐藏虚拟元素而不使用 css display:none 所以基本上使用以下作为虚拟密码元素。

              <input type="password" style="width: 0;height: 0; visibility: hidden;position:absolute;left:0;top:0;"/>
              

            【讨论】:

            • 干得好,你是怎么知道Chrome的算法的?我刚刚发现,在使用 setTimeout 计时器加载页面后,我使用 JS 更改值的旧方法不再起作用。但这很完美!
            • 很遗憾,它不适用于常规的 TextBox 输入。
            • 实际上它正在工作,只需设置 name 属性;)
            • 在 Chrome 58 上这不起作用。使用宽度:1px。如果密码字段完全隐藏,Chrome 会正常自动填充。 z-index:-999 也很有用,因此它不会与任何内容重叠。
            • 适用于 Chrome 67.0 的 Angular html 组件 &lt;form *ngIf="!loggedIn()" #loginForm="ngForm" class="navbar-form navbar-right" (ngSubmit)="login()"&gt;&lt;input type="password" style="width: 0;height: 0; visibility: hidden;position:absolute;left:0;top:0;"/&gt;&lt;input type="text" #username="ngModel" placeholder="Username" class="form-control" required autocomplete="off" name="username" [(ngModel)]="model.username"&gt;&lt;input type="password" #password="ngModel" placeholder="Password" class="form-control" required autocomplete="off" name="password" [(ngModel)]="model.password"&gt;...
            【解决方案14】:

            对于 chrome,如果您用标签包围输入并在标签内输入街道、地址或两者,它将忽略任何禁用自动填充的尝试。

            <label for="searchAddress" class="control-label"> Street Address <input type="text" class="form-control" name="searchAddress></label>
            

            Chrome 会检测标签中的关键字以确定输入类型。它也可能与其他关键词一起使用。

            【讨论】:

              【解决方案15】:

              通过将autocomplete 设置为off 应该在这里工作,我有一个谷歌在搜索页面中使用的示例。我从检查元素中找到了这个。

              编辑: 如果off 不起作用,请尝试falsenofill。就我而言,它正在使用 chrome 版本 48.0

              【讨论】:

                【解决方案16】:

                而不是“这对我有用”的答案和其他看起来像完整黑客的答案......这是目前 chrome(和最新规范)将如何处理您的 autocomplete 元素上的 autocomplete 属性:

                https://developers.google.com/web/fundamentals/design-and-ui/input/forms/label-and-name-inputs?hl=en

                TLDR:在您的输入中添加autocomplete='&lt;value&gt;',其中&lt;value&gt; 应该是定义字段用途的任何字符串。这类似于name 属性。尽可能使用上面链接中的建议值。

                另外,从您的表单中删除自动完成属性

                【讨论】:

                • 这并没有解决正在讨论的问题。这是关于如何阻止 Chrome 自动填充。不是“如何正确创建表单”。无论是那个还是你的 TLDR 都没有完全遵循你正在解决的问题或结果。
                【解决方案17】:

                不幸的是,这些解决方案似乎都不起作用。我能够使用

                清空电子邮件(用户名)
                                    <!-- fake fields are a workaround for chrome autofill getting the wrong fields -->
                                    <input style="display:none" type="text" name="fakeusernameremembered"/>
                                    <input style="display:none" type="password" name="fakepasswordremembered"/>
                

                技术,但密码仍然填充。

                【讨论】:

                  【解决方案18】:

                  不同的解决方案,基于 webkit。如前所述,只要 Chrome 找到密码字段,它就会自动完成电子邮件。 AFAIK,这与 autocomplete = [whatever] 无关。

                  为了规避这种情况,请将输入类型更改为文本并以您想要的任何形式应用 webkit 安全字体。

                  .secure-font{
                  -webkit-text-security:disc;}
                  
                  <input type ="text" class="secure-font">
                  

                  据我所知,这至少与输入类型 = 密码一样安全,它是复制和粘贴安全的。但是,通过删除将删除星号的样式很容易受到攻击,当然 input type = password 可以很容易地在控制台中更改为 input type = text 以显示任何自动填充的密码,因此实际上几乎相同。

                  【讨论】:

                  • 谢谢!这是在 chrome 49 中唯一有效的方法。以前的方法坏了,因为 chrome 现在似乎用type="password" 填充所有输入。
                  【解决方案19】:

                  我的 hack — 在 Chrome 48 中测试:

                  由于 Chrome 试图通过查看 &lt;input&gt;idname 属性以及相关的 &lt;label&gt; 内容来找出字段的类型,因此您只需要找到无意义的名称对于这些。

                  对于idname,很容易选择未列出here 的其他内容。

                  对于label,我在中间插入了一个不可见的&lt;span&gt;,例如对于一个城市(它搞乱了我的Places autocomplete)

                  <span>Ci<span style="display:none">*</span>ty</span>
                  

                  完整的工作示例:

                  <!DOCTYPE html>
                  <html>
                    <body>
                      <form method="post" action="/register">
                        <div>
                          <label for="name">Name</label>
                          <input id="name" type="text" name="name" />
                        </div>
                        <div>
                          <label for="email">Email</label>
                          <input id="email" type="text" name="email" />
                        </div>
                        <div>
                          <label for="id1">City</label>
                          <input id="id1" type="text" name="id1" /> <-- STILL ON :(
                        </div>
                        <div>
                          <label for="id2">Ci<span style="display:none">*</span>ty</label>
                          <input id="id2" type="text" name="id2" /> <-- NOW OFF :)
                        </div>
                      </form>
                    </body>
                  </html>

                  【讨论】:

                    【解决方案20】:

                    对于用户名密码组合,这是一个很容易解决的问题。 Chrome 启发式查找模式:

                    <input type="text">
                    

                    接着是:

                    <input type="password">
                    

                    通过使这个无效来破坏这个过程:

                    <input type="text">
                    <input type="text" onfocus="this.type='password'">
                    

                    【讨论】:

                    • 不幸的是,这不仅仅适用于用户名/密码类型的东西。 Chrome 将查看占位符文本以推断建议的内容。例如:jsbin.com/jacizu/2/edit
                    • 正如您的示例所示,您仍然可以使用浏览器建议填充字段是有效的,因此这并不能真正解决 OPs 问题。此解决方案只是阻止浏览器“自动”填充用户名和密码组合,如顶部答案的示例中所示。这可能对某些人有用,但不是禁用自动完成的最终解决方案,这必须来自 Google。
                    • 虽然,如果您在占位符文本前添加一个空格,它也会禁用基于占位符的自动建议。绝对是一个黑客,虽然不比其他建议更多。 jsbin.com/pujasu/1/edit
                    • 实际上...它似乎适用于您的示例,但由于某种原因它不适用于我:-(
                    • 哈!这就是为什么它被称为黑客......你有一个例子可以分享它不起作用的地方吗?
                    【解决方案21】:

                    根据Chromium bug report #352347,Chrome 不再尊重autocomplete="off|false|anythingelse",无论是表单还是输入。

                    对我有用的唯一解决方案是添加一个虚拟密码字段

                    <input type="password" class="hidden" />
                    <input type="password" />
                    

                    【讨论】:

                      【解决方案22】:

                      我需要一些额外的字段才能使其正常工作,因为 chrome 实际上填充了许多字段。而且我还需要以一种比 display:none 更奇特的方式隐藏字段才能真正起作用。

                      <style>.stylish { position:absolute; top:-2000px; }</style>
                      <input id="_____fake_email_remembered" class="stylish" tabindex="-1"  type="email" name="email_autofill"/> 
                      <input id="_____fake_userName_remembered" class="stylish" tabindex="-1"  type="text" name="userName_autofill"/>
                      <input id="_____fake_firstName_remembered" class="stylish" tabindex="-1"   type="text" name="firstName_autofill"/>
                      <input id="_____fake_lastName_remembered" class="stylish" tabindex="-1"   type="text" name="lastName_autofill"/>
                      <input id="_____fake_phone_remembered" class="stylish"  tabindex="-1"  type="text" name="phone_autofill"/>
                      <input id="_____fake_address_remembered" class="stylish"  tabindex="-1"   type="text" name="address_autofill"/>
                      <input id="_____fake_password_remembered" class="stylish"  tabindex="-1"   type="password" name="password_autofill"/>
                      <input id="_____fake_password_remembered2" class="stylish"  tabindex="-1"   type="password" name="passwordRepeated_autofill"/>
                      

                      【讨论】:

                      • 经过其他尝试后,这确实对我有用。我正在使用 Chrome 50。
                      【解决方案23】:

                      我发现将此添加到表单会阻止 Chrome 使用自动填充功能。

                      <div style="display: none;">
                          <input type="text" id="PreventChromeAutocomplete" name="PreventChromeAutocomplete" autocomplete="address-level4" />
                      </div>
                      

                      在这里找到。 https://code.google.com/p/chromium/issues/detail?id=468153#hc41

                      真正令人失望的是,Chrome 决定它比开发人员更了解何时自动完成。有一种真正的微软感觉。

                      【讨论】:

                      • 你说的PreventChromeAutocomplete并不是真的。我可以通过说 autocomplete="off" 和 name="somename" 来让自动完成工作。但这仅在您将两个不同的输入命名为相同名称时才有效。因此,在您的情况下,PreventChromeAutocomplete 必须已应用于两个不同的输入。很奇怪……
                      【解决方案24】:

                      我的解决方案:

                      $(function(){
                          $("form[autocomplete=off]").find('input').attr('autocomplete', 'false');
                      });
                      

                      它在具有“autocomplete="off"' 的表单中的所有输入字段上设置属性 'autocomplete="false"'。

                      这适用于 chrome、firefox 和 safari。

                      【讨论】:

                        【解决方案25】:

                        我也遇到过同样的问题。这是在 Chrome 上禁用自动填充用户名和密码的解决方案(仅在 Chrome 上测试过)

                            <!-- Just add this hidden field before password as a charmed solution to prevent auto-fill of browser on remembered password -->
                            <input type="tel" hidden />
                            <input type="password" ng-minlength="8" ng-maxlength="30" ng-model="user.password" name="password" class="form-control" required placeholder="Input password">
                        

                        【讨论】:

                        • 奇怪的修复,但不知何故,这是在 chrome 48 上唯一对我有用的东西 :)
                        【解决方案26】:

                        为用户名字段输入值“”(空格)。

                        <input type = 'text' value = ' ' name = 'username' />
                        

                        如果您曾经使用用户输入的值填充用户名,如果没有用户输入的值,请输入代码以输入“”。

                        编辑:我还必须更改“用户名”字段以使用“用户名”以外的名称,例如'用户名'

                        【讨论】:

                          【解决方案27】:

                          就像 Dvd Franco 所说,对我来说,只在它工作的所有领域都设置了 automplete='off'。所以我把这个 jquery 规则放在 $(document).ready();在我的主 .js 文件上运行

                          $('form.no_autofill').attr('autocomplete','off');
                          $('.no_autofill input').attr('autocomplete','off');
                          

                          【讨论】:

                            【解决方案28】:

                            我知道这并不完全相关,但这就是我所做的。 自动填充的字段会引发“更改”事件,但前提是您尽早将其绑定到它们。

                            所以我把它放在头部。

                              $(document).ready(function(){
                                        $('input').on('change',function(){$(this).val('')})
                                 }); 
                            

                            它对我有用。

                            【讨论】:

                              【解决方案29】:

                              我在“立即登录或注册”模式窗口中遇到了这个问题,如果用户已将他们的凭据保存到浏览器,就会出现问题。登录和注册字段都已填充,因此我可以使用以下 Angular js 指令清除它们:

                              (function () {
                                  "use strict";
                              
                                  var directive = function ($timeout) {
                                      return {
                                          restrict: "A",
                                          link: function (scope, element, attrs) {
                                              $timeout(function () {
                                                  element.val(" ");
                                                  $timeout(function () {
                                                      element.val("");
                                                  });
                                              });
                                          }
                                      };
                                  };
                              
                                  angular.module("app.directives").directive("autofillClear", ["$timeout", directive]);
                              }());

                              它与之前使用 jquery 的一些答案基本相同,但以角度方式完成。

                              【讨论】:

                              • 它几乎没有修改,$timeout(function() { element.val("") }, 300)
                              【解决方案30】:

                              最后,我想我提出了一个不错的解决方案。更好地了解下拉菜单如何与 Chrome 一起使用有助于 :) 基本上,当您聚焦输入时,当您输入与 Chrome 内存中的内容匹配的条目时,当您生成鼠标按下事件时,将显示下拉菜单。记住这一点,当某些输入具有“名称”、“电子邮件”等默认名称时,Chrome 会执行此操作。然后我们只需要在要显示下拉列表时删除名称,然后再将其添加回来:) 我想使用一种解决方案,只需添加属性自动完成功能即可使其工作。我认为这是有道理的。这是代码:

                              解决方案 1

                              jQuery('body').on('mousedown','[name="name"][autocomplete="off"], [name="email"][autocomplete="off"]',function(e){
                                  e.stopImmediatePropagation();
                                  if(typeof this.currentName =="undefined")
                                      this.currentName=jQuery(this).attr('name');
                                  jQuery(this).attr('name','');
                              });
                              
                              jQuery('body').on('blur','[autocomplete="off"]',function(e){
                                  e.stopImmediatePropagation();
                                  jQuery(this).attr('name',this.currentName);
                              });
                              

                              解决方案 2(我最喜欢的一个)

                              我上面描述的解决方案将删除输入的名称,直到我们删除焦点(模糊),在那一刻它会放回原来的名称。但是可能会发生我们有兴趣在输入时通过其名称属性访问输入。这意味着我们需要在每次输入后立即放回名称。这个解决方案,基本上是基于第一个解决方案。在这种情况下,我们将在 key down 上添加名称,然后将其放回 keyup。我认为这更适合与“自动完成关闭”行为的兼容性。无论如何,这是代码:

                              jQuery('body').on('mousedown keydown','[name="name"][autocomplete="off"], [name="email"][autocomplete="off"]',function(e){
                                  e.stopImmediatePropagation();
                                  if(typeof this.currentName =="undefined")
                                      this.currentName=jQuery(this).attr('name');
                                  jQuery(this).attr('name','');
                              });
                              jQuery('body').on('blur keyup','[autocomplete="off"]',function(e){
                                  e.stopImmediatePropagation();
                                  if(typeof this.currentName !="undefined")
                                      jQuery(this).attr('name',this.currentName);
                              });
                              

                              请注意,对于解决方案 1 和 2,我仅采用了输入名称为“名称”和“电子邮件”的情况。对于此属性使 Chrome 生成下拉列表的任何其他情况,您必须将其添加到鼠标按下事件的选择器中。

                              解决方案 3

                              这个解决方案更加混乱。我没有意识到我们试图纠正的行为只是基于那些具有特定名称的输入,如“姓名、电子邮件等”。该解决方案的方法是针对 Chrome 显示我们事先不知道的其他名称的情况。这将是一个非常通用的解决方案。我不像其他两个那样喜欢,主要是因为当我们按下删除键时可能会有一个小的闪烁。我将在下面解释。

                              我发现,当您第一次关注输入时,第二次单击输入后会出现下拉菜单,但在第一次单击时不会出现下拉菜单。我为所有这些元素绑定了一个“mousedown”事件,其中处理程序基本上检测它是否已经集中在输入上,如果它检测到另一个“mouse down”,则强制 .blur() 然后 .focus() 之后,防止聚焦后第二次单击的下拉菜单。我希望很清楚,以防万一这是我使用的代码:

                              jQuery('body').on('mousedown','[autocomplete="off"]',function(e){
                                  e.stopImmediatePropagation();
                                  if(jQuery(this).is(':focus')) {
                                      jQuery(this).blur();
                                      jQuery(this).focus();
                                  }
                              });
                              

                              另一方面,为了防止您在输入时出现下拉菜单,以防它与 Chrome 建议匹配...这有点棘手。我只是决定在用户​​键入时替换输入的默认行为。下拉列表评估鼠标按下时的输入,因此我阻止了字母数字、空格等的默认行为。唯一的问题是命令、Ctrl 和删除。对于这种情况,我还必须在鼠标上绑定一个事件。它允许前两种情况下的默认行为,因此您可以进行复制、粘贴或全选。在删除的情况下,我必须允许默认行为,但如果在删除字符后输入与 Chrome 建议匹配,那么它再次显示下拉菜单。对于这种情况,我不得不使用相同的模糊和聚焦技巧。我发现的唯一不便之处是,由于我们取消了 keyup 的行为,并且 chrome 尝试在 keydown 上显示它,所以会有一点闪烁。无论如何,这是我能做的最好的了。可能需要在某一时刻过滤字符。我只是添加了现在更有意义的条件。这是代码的第二部分:

                              jQuery('body').on('keydown','[autocomplete="off"]',function(e){
                                  e.stopImmediatePropagation();
                                  var ctrlKey = 17,cmKey = 91;
                                  var charCode = e.which || e.keyCode;
                              
                                  if(charCode!=16 && this.commandDown != true && this.ctrlDown != true && ((charCode>47 && charCode<58)||(charCode>64 && charCode<91)||(charCode>96 && charCode<123)||charCode==0 || charCode==32)){ 
                                      e.preventDefault();
                                      var charStr = String.fromCharCode(charCode);
                                      if(!e.shiftKey)
                                          charStr = charStr.toLowerCase(charStr);
                                      $(this).val($(this).val() + charStr);
                                  }else{
                                      if (charCode == cmKey) this.commandDown = true;
                                      if (charCode == ctrlKey) this.ctrlDown = true;
                                  }
                              });
                              jQuery('body').on('keyup','[autocomplete="off"]',function(e){
                                  e.stopImmediatePropagation();
                                  var allowed=[8];//Delete
                                  var ctrlKey = 17,cmKey = 91;
                                  var charCode = e.which || e.keyCode;
                              
                                  if (charCode == cmKey) {this.commandDown = false};
                                  if (charCode == ctrlKey) {this.ctrlDown = false};
                                  if(allowed.indexOf(charCode)>=0 || (this.commandDown!=false && this.ctrlDown!=false)){
                                      jQuery(this).blur();
                                      jQuery(this).focus();
                              }
                              

                              正如我所说,这个解决方案更加混乱。这是我使用的第一个,直到我意识到某些输入名称才出现下拉列表。

                              抱歉写了这么多,我只是想确保一切都清楚。希望对你有帮助。

                              【讨论】:

                                猜你喜欢
                                • 2019-02-17
                                • 2019-04-10
                                • 2023-03-25
                                • 2016-10-02
                                相关资源
                                最近更新 更多