2020年1月13日

比较 HTML 和 JavaScript Input 验证

如果你想验证表单输入是否有效,比如你想让输入框只接受整数,而不是小数或文字,在 HTML5 中你可以用以下代码轻松实现:

<input type="number" pattern="[0-9]*" />

但是,用户仍然可以输入无效信息:

  1. 在 Firefox 里,你可以输入任何字符:比如“fsielfs”。
  2. 在 Chrome 里,你可以输入一些无效的数字:比如“1..2.2.2”。

输入框会显示为错误状态,但是如果你覆盖了原生样式就不会看到这个效果了。你需要用 :invalid 选择器来定义错误样式:

input[type="number"]:invalid {
	border-color: red;
}

但是对 JavaScript 来说,它几乎是一个黑箱:

  1. 无效输入不会触发 change 事件。
  2. 当输入无效时,value 返回空字符串 。
  3. validity 属性只能告诉你输入是否有效,而不能提供原始输入值。

也就是说,JavaScript 无法知道用户的错误输入,也无法更改它们。为什么会这样?

当你指定 type="number"pattern="[0-9]*" 时,你将表单格式验证的工作交给了浏览器。当输入无效时,浏览器会提醒并要求用户修正。JavaScript 可以检查 e.target.validity 来了解输入是否有效,但无法了解更多细节。HTML 表单验证对屏幕阅读器非常友好,也很易于使用,是 Web 标准的一部分。而 JavaScript 验证则难以做到这一点。

但是如果我们仍然想要用 JavaScript 来验证和过滤输入……

解决方案 1:用 type="text"

这样你就可以捕获所有字符输入了。你可以在 change 事件中验证和修订 e.target.value。这是最简单全能的方法。

缺点便是失去了系统对输入类型的优化。尤其是在移动设备中,会弹出标准键盘,而不是数字键盘。用户的输入步骤会更加繁琐,影响体验。

解决方案 2:监听 input 事件。

change 事件不同,只要用户输入了内容,不管有效无效,都会触发input 事件。你可以检查 e.data 属性存储输入值。

但它也不是万能的。e.data 得到的只是本次输入的字符,你并不知道光标在哪里,所以不能准确得到完整输入。加入用户按了删除键,你不知道他删除了哪里的多少字符。因此这个方法具有很大的局限性,并不是 100% 可靠。

加入你只要对单个输入字符进行逐一检查,而不需要考虑整体有效与否,那么用这种方法是可以的。在一些情况下,你需要保证每次输入后都是有效状态,可以和 change 事件组合使用,保存每个有效状态,一旦遇到无效输入状态,则退回上一个有效状态。但是,很多输入的中间状态可能是无效的,比如电子邮件,这种情况就不能用 input 事件来解决。

注意:不要用 keydownkeyup 事件,因为它们只检测键盘事件,而输入可能是由复制粘贴,语音输入或虚拟键盘实现的,而不会触发这些键盘事件。

总结一下,确实你可以只用 JavaScript 去验证表单输入。但是我并不推荐这样做。以上两种解决方案都有限制,而且不符合 Web 标准的原则。结合 HTML 和 JavaScript 表单验证,效果会更好。

2020年1月8日

Btrfs 断电损坏

强制关机是危险的,至少对于 Btrfs 文件系统来说。

即使如今 Linux 桌面的稳定性已经极大改善,使用滚动发行版或特殊显卡驱动的用户仍然可能会遇到系统卡死的情况。这时候很多人就会直接长按电源键关机。这会导致系统强制断电,而文件系统读写尚未完成(可能是文件系统层面,也可能是存储硬件层面)。

为什么偏偏 Btrfs 会特别敏感呢?

其实 Btrfs 本身并没有特别弱势的地方,但是使用 Btrfs 的发行版,比如 openSUSE,会定期进行 btrfs-balance 和 btrfs-cleaner。这些 Btrfs 维护任务会带来巨大的 CPU 和 IO 负担,让桌面更容易卡死崩溃。假如你正在玩一款特别占用资源的游戏,而这时 btrfs-balance 开始了,系统很可能会被卡死。如果此时强制断电,btrfs-balance 的数据转移就会被中断,从而使文件系统处于异常状态。

再次开机时,则可能会遇到无法挂载分区,无法进入系统,甚至无法启动的情况。通常系统的 /home 分区或子卷读写最频繁,也最容易因为断电而损坏。无法挂载 /home 分区或子卷的表现为:能进入登录界面却无法进入桌面。

这时要怎么做呢?

第一,重启后即使无法进入系统,也请先让机器继续运行。这可以让 SSD 硬件断电保护机制工作,将之前未完成的数据操作恢复,这可能需要几分钟。请尽量等待时间长一些,以确保数据写入已经完全完成。

第二,再次重启。如果第一步有效,那么您应该能够正常进入系统了。您可以多试几次。如果最终仍然不能进入系统,那么您还需要检查和修复 Btrfs 文件系统。

第三,制作救援盘,从救援盘启动。

第四,插入移动硬盘,使用 btrfs restore 将数据恢复出来。这一步是完全安全的,不会更改已有文件系统。接下来的步骤都或多或少有些风险,因此建议您先保留数据。

第五,按照维基上的 Btrfs 修复教程操作。需要注意的是,这些修复方法的风险依次增大。某些情况下,btrfs check --repair /dev/sda1 甚至可能会完全摧毁一个 Btrfs 文件系统。

2019年10月5日

2019年10月2日

Code Journey #11

九月亮点:高分屏BUG修复模拟器打包

KDE:

  • Kompare 高分屏渲染支持 [patch]
  • Filelight 高分屏渲染支持 [patch]
  • KSysGuard 系统卫士高分屏渲染支持,传感器折线图尚未支持 [patch]
  • 字体管理器高分屏渲染支持 [patch]
  • 字体管理器的 enablefont 和 disablefont 图标 [patch]
  • KWallet 钱包高分屏渲染支持 [patch]
  • KWin 高分屏渲染支持 [patch]
  • Krita 加载界面高分屏渲染支持 [patch]
  • Kate/KonsolePart 多屏渲染问题 [bug] [patch]
  • Spectale 多屏渲染问题 [bug] [patch]

openSUSE:

  • 更新 python-PyMuPDF 包并修复库链接问题
  • 更新 arcanist 包并提交到 Factory [request]
  • 提交 PCSX2 包到 Factory [request]
  • 更新 retroarch 包使之开箱即用 [request 1] [request 2]
  • 创建 retroarch-assets 包 [request]
  • 创建 retroarch-joypad-autoconfig 包 [request]
  • 创建 libretro-core-info 包 [request]
  • 创建 libretro-database 包 [request]
  • 创建 libretro-mame2000 核心包 [request]
  • 创建 libretro-genesis-plus-gx 核心包 [request]
  • 创建 libretro-flycast 核心包 [request]
  • 创建 libretro-yabause 核心包 [request]

2019年9月11日

Code Journey #10

KDE:

  • 修复 JuK 每次启动都弹出文件夹设置对话框的 BUG
  • 翻译 TechBase
  • 修复每日一图不更新的 BUG
  • 研究蓝牙耳机自动连接后无法识别的 BUG。确认是 Linux 内核的问题,已经汇报给上游。

openSUSE:

  • 更新维基 FAQ 页面,还在继续
  • Chameleon 主题:新的导航栏的页脚设计,以及暗色模式
  • 更新文档网页主题
  • 更新维基网页主题

2019年9月6日

2019年7月20日

2019年6月26日

Code Journey #8

openSUSE

Wiki

  • 更新 FAQ 页面

Plasma 主题

  • 更新配色方案
  • 改进面板透明度

opi

  • 修复 Leap 15.1 系统版本空格问题

Geeko Store

  • OBS/PMBS 搜索 API 集成
  • 软件包列表

打包

  • 更新 php-composer
  • 创建 npm2rpm
  • 打包 npmjs-gulp-cli
  • 打包 npmjs-create-react-app
  • 打包 npmjs-webpack-cli
  • 更新 patterns-base,移除 dejavu-fonts 推荐,以改进 emoji 支持

KDE

翻译

  • 更新 KDE Connect 翻译
  • 构建同步到 SVN

2019年6月5日

Code Journey #7

openSUSE

opi

  • 解决了硬编码登录信息的安全问题,使用代理服务器转发请求
  • 支持 Packman 软件包查询
  • 解决了依赖关系缺失的问题

chameleon

  • 添加主题文档页面
  • 支持 hot reload 的开发模式
  • 增加暗色背景下的按钮和表单控件主题
  • 改进主题风格

打包

  • 更新 python-PyMuPDF

其他

Rabbit Lyrics

  • 支持多个歌词块

2019年5月5日

Code Journey #6

为了避免日志太多,以后将会按周总结。发布日期通常是每周日。

openSUSE

opi

  • 快捷安装 Packman codecs, VS Code, Skype
  • PMBS 搜索功能研究(只要得到账号,就能做了)

打包

  • 更新 adobe-sourcehansans-fontsadobe-sourcehanserif-fonts包,提供语言支持信息with additional provides for languages

KDE

翻译

  • 保持核心翻译 100%
  • 翻译 Kdenlive
  • 同步翻译到 SVN