密码输入框踩雷 input type='password'

853 阅读2分钟

项目历程: 项目里有需要输入用户token去调api的场景,由于token是隐私内容,因此需要对显示加密。 已知:

  1. 将input的type设置为password可以直接加密
  2. 此时edge和chrome浏览器对password type 的解析不同,edge自带眼睛图标控制显示和隐藏,但是chrome不带有,需要自行封装。

在chrome的显示: image.png 在Edge的显示: image.png

  1. 因此需要区分浏览器,使用navigator.userAgent来判断为什么浏览器。
  2. 区别了浏览器后,就是对眼睛图标的切换以及token的加密和显示,最开始准备给input动态绑定type,但是svelte不支持,必须在编译前确定input的type而不能动态绑定。
  3. 解决方法:两套input+svg 点击事件切换是否显示密码。
let showpsw = false
<div>
	{#if !parameters.name.includes('TOKEN')}
		<input
			class="px-3 py-1.5 text-sm w-full mb-2 bg-transparent border dark:border-gray-600 outline-none rounded-lg transition duration-300 ease focus:outline-none focus:border-slate-400 hover:border-slate-300 shadow-sm focus:shadow"
			placeholder={$i18n.t(`${parameters.description}`)}
			bind:value={parameters.value}
			required
		/>
	{:else if navigator.userAgent.indexOf('Edg') !== -1}
		<input
			class="px-3 py-1.5 text-sm w-full mb-2 bg-transparent border dark:border-gray-600 outline-none rounded-lg transition duration-300 ease focus:outline-none focus:border-slate-400 hover:border-slate-300 shadow-sm focus:shadow"
			placeholder={$i18n.t(`${parameters.description}`)}
			bind:value={parameters.value}
			required
			type="password"
		/>
	{:else if showpsw}
		<div class="relative">
			<input
				class="px-3 py-1.5 text-sm w-full mb-2 bg-transparent border dark:border-gray-600 outline-none rounded-lg transition duration-300 ease focus:outline-none focus:border-slate-400 hover:border-slate-300 shadow-sm focus:shadow"
				placeholder={$i18n.t(`${parameters.description}`)}
				bind:value={parameters.value}
				required
			/>
			<button on:click={() => (showpsw = !showpsw)}>
				<svg
					xmlns="http://www.w3.org/2000/svg"
					fill="none"
					viewBox="0 0 24 24"
					stroke-width="1.5"
					stroke="gray"
					class="size-5 absolute right-2 top-2"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88"
					/>
				</svg>
			</button>
		</div>
	{:else}
		<div class="relative">
			<input
				class="px-3 py-1.5 text-sm w-full mb-2 bg-transparent border dark:border-gray-600 outline-none rounded-lg transition duration-300 ease focus:outline-none focus:border-slate-400 hover:border-slate-300 shadow-sm focus:shadow"
				placeholder={$i18n.t(`${parameters.description}`)}
				bind:value={parameters.value}
				required
				type="password"
			/>
			<button on:click={() => (showpsw = !showpsw)}>
				<svg
					xmlns="http://www.w3.org/2000/svg"
					fill="none"
					viewBox="0 0 24 24"
					stroke-width="1.5"
					stroke="gray"
					class="size-5 absolute right-2 top-2"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
					/>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
					/>
				</svg>
			</button>
		</div>
	{/if}
</div>

这样就大功告成啦!实现一个密码框居然有这么长的代码,为了能复用需要再组件化一点,不过优化的部分就留到之后算工作量吧!之后优化了再更新!