繁体   English   中英

有没有办法禁用自动完成与 JS/CSS display none 属性的使用?

[英]Is there possibly a way to disable the use of autocomplete with JS/CSS display none attribute?

在此处输入图片说明 我最近尝试通过各种方式禁用网络浏览器autocomplete功能,包括许多autocomplete off场景,这似乎会导致浏览器之间的兼容性问题。 所以现在我现在试图弄清楚我是否可以使用autocomplete来解决问题并display none ,只有我在弄清楚如何将它们一起编码时遇到问题。 该代码适用于过滤器/(搜索)输入函数。

JS

<body>
<script>
var input, table, rows, noMatches, tr, markInstance;

$(document).ready(function init() {
input = document.getElementById('myInput');
noMatches = document.getElementById('noMatches');

table = document.querySelectorAll('#myTable table tr:first-child');
rows = document.querySelectorAll('#myTable table tr');

markInstance = new Mark(table);
input.addEventListener('keyup', _.debounce(ContactsearchFX, 250));
});    


function ContactsearchFX() {
  resetContent();
  markInstance.unmark({ done: highlightMatches });
}



function resetContent() {
    $('.noMatchErrorText').remove(); 
    //Remove this line to have a log of searches

    //noMatches.textContent = '';
  rows.forEach(function(row) {
    $(row).removeClass('show'); 
  });
}

function highlightMatches() {
  markInstance.mark(input.value, {
    each: showRow,
    noMatch: onNoMatches,
    exclude: ['.nonsearch']
  })
}



function showRow(element) {
//alert(element);
  $(element).parents('tr').addClass('show');                $(element).parents('tr').siblings('tr').addClass('show');
        //Parents incase of several nestings
}



function onNoMatches(text) {
  $('#myInput').after('<p class="noMatchErrorText">No records match: "' +     text +                '"</p>'); 
}



/* Prevents Return/Enter key from doing anything */

$(document).on('submit', 'form', function(e){
/* on form submit find the trigger */
if( $(e.delegateTarget.activeElement).not('input, textarea').length == 0 ){
    /* if the trigger is not between selectors list, return super false */
    e.preventDefault();
    return false;
 } 
 });    

    /* Prevents Return/Enter key from doing anything */    

CSS

.input-wrap  {
  margin-bottom: 12px;
}

#myInput:invalid ~ .hints {
  display: block;
}



#noMatches:empty, #noMatches:empty + .hints {
  display: none;
}


.style1 tr {
  display: none;
}


.style1 .show {
  display: table-row;
}



#myTable table tr:first-child td mark {
background: orange;
font-weight: bold;
color: black;
}
mark {
background: initial;
}    .style1  {
text-align: left;
}
</style>

HTML

<script src="https://code.jquery.com/jquery-3.3.1.js"></script>

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js">
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1
/mark.min.js"></script>
<head>
<body>
<div class="input-wrap">
<label>
Search 
<input id="myInput" type="text" required
   placeholder="Search Titles" />
</label>
</div>

<div class="hintsWrap">
<p id="noMatches"></p>
<p class="hints">
Hints: type "Title1", "Title2", "Title3"...
</p>
</div>
<br />
<br />
<br />
<table id="myTable" style="width: 100%" class="style1">
    <tr>
        <td>
<br />
<br />
<table style="width: 100%">
    <tr>
        <td>
        <table style="width: 100%">
            <tr>
                <th class="style1">Type</th>
                <td>type1</td>
            </tr>
            <tr>
                <th class="style1">Title</th>
                <td>title1</td>
            </tr>
            <tr>
                <th class="style1">Description</th>
                <td>description1</td>
            </tr>
            <tr>
                <th class="style1">Date</th>
                <td>date1</td>
            </tr>
        </table>
        </td>
    </tr>
</table>
<br />
<br />
        <table style="width: 100%">
            <tr>
                <th class="style1">Type</th>
                <td>type2</td>
            </tr>
            <tr>
                <th class="style1">Title</th>
                <td>title2</td>
            </tr>
            <tr>
                <th class="style1">Description</th>
                <td>description2</td>
            </tr>
            <tr>
                <th class="style1">Date</th>
                <td>date2</td>
            </tr>
        </table>
<br />
 <br />
        <table style="width: 100%">
            <tr>
                <th class="style1">Type</th>
                <td>type3</td>
            </tr>
            <tr>
                <th class="style1">Title</th>
                <td>title3</td>
            </tr>
            <tr>
                <th class="style1">Description</th>
                <td>description3</td>
            </tr>
            <tr>
                <th class="style1">Date</th>
                <td>date3</td>
            </tr>
        </table>
<br />
<br />
<br />
<br />
<br />
        </td>
    </tr>
</table>

</body>

这是一个奇怪的场景,但出于某种原因,某些浏览器不支持表单中的autocomplete="off"变量。

你可以这样做:

<form autocomplete="off">
    <input autocomplete="anything_but_false_or_a_valid_value" name="forHackToWork" />
    ...
</form>

对于 Safari:需要spellcheck="false"

据说自动完成是一项正在进行的工作。 随着浏览器在 BOM 中变得更加统一,甚至微软也转向了 Chromium 平台。

鉴于上述浏览器正在或已经完全忽略密码字段的属性,密码字段以前已为密码字段合并了 autocomplete=off。 有些已经将相同的内容扩展到数字和列表等。怪癖解释在这里输入链接描述

似乎没有可以在任何地方工作的海峡前进黑客。 这是浏览器智囊团仍在试图将他们的头脑集中在一起的那些有线事物之一。 原因是 W3C 要求严格实现 DOM 标准,但并不关心其 BOM 中的浏览器功能。 因此,polyfills 的世界,例如打印页面上的页眉和页脚,其马拉松式的跨浏览器控制。 同样是自动完成的怪癖,有些是“关闭”,有些是“假”,有些是“铬关闭”等。

现在来到您的案例中,我们有输入字段,但没有表单字段。 From 提供对提交时的子元素的控制,例如按钮、字段。 尽管根据 W3C 没有表单的字段是有效的 HTML,但它失去了控制属性。 然后我们必须寻求 JS 助手来执行控制。 这个 JS 仅限于 DOM 而不是 BOM。 在字段中作为自动完成捕获的是 BOM 范围而不是 DOM。 在站点上输入的内容在另一个站点(通常是电子邮件字段)中弹出的情况已经发生了很多次。 在此处输入链接描述

我们可以做的是如上面链接放置元素中所建议的,这些元素需要将控件放置在表单标签内,然后在表单和所需字段上设置属性 autocomplete=off。 它在大多数情况下都可以工作,但会出现一些边缘情况,尤其是 android 浏览器或一些古怪的浏览器混合引擎。

更新:后理论

chrome 之外的其他基于 Chromium 的浏览器似乎尊重autocomplete='off' 但是我在 chrome 中测试了臭名昭著的错误直到那里,这是合理的,因为谷歌已经决定开发人员正在滥用他们喜欢的属性,所以他们忽略了它。 这让我们回到 BOM 问题而不是 DOM 问题。

解决方法是混淆 BOM,因为我们不能将其排除在外。 然而,它有局限性;

  • 它要么必须在浏览器接收 HTML 之前应用,要么在浏览器开始在虚拟/轻量 DOM 级别构建节点树之前,即在其绘制在屏幕上之前。
  • 或者必须将节点更改为新实体。

PS 表单控件根据事物的方案与字段名称属性相关联,即<input names='fieldname' 这就是 BOM 将自动完成从一个站点/页面推送到另一个站点/页面的方式。 如果另一个页面/站点使用相同的字段名称作为输入,浏览器将使用它存储在其字段自动填充缓存中的内容自动完成。 有没有想过为什么删除历史记录有这个删除自动填充表单数据。 在此处输入图片说明

解决方法是永远不要在下次运行时保持相同的字段属性名称。 如果页面是从服务器端呈现的,那么将随机时间戳值附加到 avlue,例如 name='a2323232323' 或类似行上的内容。 或者从客户端通过 JS 以类似的方式更改它。 因此,当表单提交并下次呈现时,BOM 将不会有任何新条目供表单自动填充数据匹配。 下面的屏幕截图示例。

忽略自动完成的常见场景

    <form action="" >
  <div class="container">
    <label for="uname"><b>Username</b></label>
    <input id="testi" type="email" placeholder="Enter Username" name="uname" required >

From 没有自动完成属性,发生的情况如下; 首次运行时自动完成根本不运行在此处输入图片说明 但是在提交表单后的第二次运行时,相同的uname字段会触发自动完成在此处输入图片说明 在此处输入图片说明

如果我要更改 name 属性值,以免通过 jQuery 假设,现在的解决方法。

$('[name ="uname"]').attr('name', 'a'+Date.now());

在此处输入图片说明

没有触发自动完成。 因为每次页面被绘制时名称属性值都会改变。 在此处输入图片说明 关键是我们可以控制DOM而不是BOM,我们所做的是通过DOM操作欺骗了BOM。 看起来很愚蠢,但这就是事物的本质。

所以我的解决方案是将您的解决方法与上述解决方法结合起来。

  1. 像您所做的那样创建一个具有静态名称的隐藏字段 - 不要让它显示隐藏让它隐藏。 <input type="hidden" name='emailme'>

  2. 创建用户查看和交互的普通类型的视觉字段 - 在每次加载时或根据需要通过 JS 更改此字段的名称属性,以便自动完成不会触发。

  3. 然后分配 onchange 事件

    $("#visiblefield").on('change', function() { $('#hiddenfield').val($("#visiblefield").val());

    });

为什么需要第三步

由于表单被发送到服务器,并且由于表单控件是通过服务器端的名称属性(id 用于 DOM)运行的,因此假设 php 或您无法告诉脚本要查找的 POST 或 GET 值,因为它正在即时更改。 拥有一个隐藏字段很有吸引力,因为它可以保持用户交互方式并控制服务器端处理。

该解决方案适用于所有浏览器,即使是浏览器世界中古老的 IE9+ 浏览器也是如此。

希望这有帮助,不要忘记upvote。

暂无
暂无

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

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