1. 現象:
フレームワーク: angular 環境: 最新バージョンの chrome
Google Chrome がパスワードを記憶すると、入力ボックスがパスワードの種類の場合、保存されているユーザー名とパスワードのリストが自動的に表示されます。
以下に示すように:
コードは以下のように表示されます。
<!-- 登录密码输入框代码 -->
<input nz-input [placeholder]="'Please input the password' | translate" formControlName="password" type="password" />
解決:
解決策 1: autocomplete="new-password" 属性を元のベースに追加しますが、結果は失敗し、パスワード ボックスをクリックすると、記憶されているパスワードのリストが引き続き表示されます。
解決策 2: readonly 属性を設定すると、フォーカスの喪失とフォーカスの取得に応じて readonly 属性が制御され、結果は成功になります。コードを添付します。
ステートメント3点:
1. なぜ ID を追加する必要があるのですか? domノードを取得するため。
2. フォーカス コントロール イベントのパラメーターとして ID を渡すのはなぜですか? 現在のページには、再利用できるパスワード ボックス タイプの入力ボックスが 2 つあるためです。
3. フォーカス制御イベントは遅延を使用できませんか? いいえ、遅延を使用しない場合、通常は呼び出すことができません。マウスはクリックされていますが、この時点では入力ボックスはまだ読み取り専用状態です。
冗長な説明は終わりました。正しいコードは次のとおりです。
HTMLコード
<!-- 注册页面登录密码输入框 增加【id autocomplete readonly onfocus onblur】属性 -->
<input nz-input [placeholder]="'Please input the password' | translate" formControlName="password" type="password" id="pwd" autocomplete="off" readonly onfocus="removeAttr('pwd')" onblur="setAttr('pwd')" />
<!--确认密码输入框 -->
<input nz-input [placeholder]="'Please input the password again' | translate" formControlName="confirmPw" type="password" id="confirmPw" autocomplete="off" readonly onfocus="removeAttr('confirmPw')" onblur="setAttr('confirmPw')" />
JavaScriptコード
export class RegisterComponent implements OnInit, AfterViewInit {
constructor(
...
) {
window['removeAttr'] = this.removeAttr.bind(this);
window['setAttr'] = this.setAttr.bind(this);
}
.....
// 移除密码框类型的只读属性
public removeAttr(idName) {
setTimeout(() => {
document.getElementById(idName).removeAttribute('readonly');
}, 300)
}
// 增加密码框类型的只读属性
public setAttr(idName) {
setTimeout(() => {
document.getElementById(idName).setAttribute("readonly", 'true');
}, 300)
}
}
効果:
現時点では、正常に操作すれば効果は正常ですが、テスト後も次のような欠点があり、解決する必要があり、解決後に更新される予定です。
1. 入力ボックス内でマウスをクリックし続けると、パスワード プロンプト リストが再度表示されます。
2. パスワードを入力し、空のパスワードを削除すると、パスワード プロンプト リストが再度表示されます。
5.14 更新:前回から残った 2 つの問題がついに解決されました。リンクを参照してください: https://blog.csdn.net/qq_35264415/article/details/105160728
最終的な完璧な解決策:
HTML 部分は変更されていません。
<!-- 之前的两个输入框代码没有变动 -->
<input nz-input [placeholder]="'Please input the password' | translate" formControlName="password" type="password" id="pwd" autocomplete="off" readonly onfocus="removeAttr('pwd')" onblur="setAttr('pwd')" />
<input nz-input [placeholder]="'Please input the password again' | translate" formControlName="confirmPw" type="password" id="confirmPw" autocomplete="off" readonly onfocus="removeAttr('confirmPw')" onblur="setAttr('confirmPw')" />
JS部分:
// 移除密码框类型的只读属性
public removeAttr(idName) {
document.getElementById(idName).addEventListener('click', this.handleClick);
document.getElementById(idName).addEventListener('keydown', this.handleKeydown);
document.getElementById(idName).addEventListener('mousedown', this.handleMousedown);
//使用setTimeout,告诉JS是异步执行,这样子,就可以阻止第一次点击获取焦点时,下拉用户密码清
//单的框的出现
setTimeout(() => {
//获取焦点时 同时去除只读,这样可以获取光标,进行输入
document.getElementById(idName).removeAttribute('readonly');
}, 300)
}
// 增加密码框类型的只读属性
public setAttr(idName) {
//失去焦点立马更新为只读
document.getElementById(idName).setAttribute("readonly", 'true');
}
// 点击事件
private handleClick(e) {
//为什么先失去焦点,在获取焦点,这样子可以避免第二次或更多次连续点击输入框时,出现的用户密
// 码清单的框可以快速去除
if (e.type === 'click') {
document.getElementById(e.target.id).blur();
document.getElementById(e.target.id).focus();
}
}
// 监听键盘输入事件
// 当keyCode=8(backspace键) 和 keyCode=46(delete键)按下的时候,判断只剩下最后一个字符的时
// 候阻止按键默认事件,自己清空输入框
// 当keyCode=8(backspace键) 和 keyCode=46(delete键)按下的时候,判断如果处于全选状态,就阻
// 止按键默认事件,自己清空输入框
// 这种用来避免删除最后一个字符完后出现下拉用户密码清单的框
private handleKeydown(e) {
if (e.type === 'keydown') {
const keyCode = e.keyCode;
// 和JS不一样,TS中写法如此,不然报类型“HTMLElement”上不存在属性“value”
const passwordText = (<HTMLInputElement>document.getElementById(e.target.id));
if (keyCode === 8 || keyCode === 46) {
//backspace 和delete
const len = passwordText.value.length;
if (len === 1) {
passwordText.value = "";
return false;
}
if (e.target.selectionStart === 0 && e.target.selectionEnd === len) {
passwordText.value = "";
return false;
}
}
return true;
}
}
//用来阻止第二次或更多次点击密码输入框时下拉用户密码清单的框一闪而过的问题
private handleMousedown(e) {
if (e.type === 'mousedown') {
document.getElementById(e.target.id).blur();
document.getElementById(e.target.id).focus();
}
}
効果: