Logo

site iconCyrus Yip | 叶寻

自学者,对编程、学习新事物充满热情。喜欢阅读、写作、看动画、玩单机游戏。每天进行正念冥想。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Cyrus Yip | 叶寻 RSS 预览

OPPO / 一加 / ColorOS 的 Google Play 安装教程

2024-11-15 00:00:00

  1. 开启谷歌服务:打开设置,搜索「google」,点击「Google 设置」,开启「Google 移动服务」。
  2. 安装 Google Play:打开应用商店,搜索「google play」,升级「谷歌应用市场」。升级完后桌面会出现「Play 商店」。

测试机型:一加 OnePlus Ace 3(ColorOS 14)、OPPO Reno12(ColorOS 14)。

概念解析:物理像素、逻辑像素、CSS 像素、物理分辨率、逻辑分辨率

2024-11-02 00:00:00

物理(physical)表示实际的值,逻辑(logical)表示经过缩放的值。

物理像素 #

像素(pixel)是显示器的基本单位,一个像素显示一种颜色。为了和逻辑像素(logical pixel)区分,像素(pixel)又称物理像素(physical pixel)。

逻辑像素 / CSS 像素 #

逻辑像素(logical pixel),亦称 CSS 像素(CSS pixel),是经过操作系统缩放的像素。CSS 的 px 就是 CSS 像素。

物理分辨率 #

物理分辨率(physical resolution)表示像素的数量。1920×1080 分辨率就表示显示器水平方向有 1920 个像素,垂直方向有 1080 个像素,共 2073600 个像素。尺寸相同时,显示器分辨率越高,显示效果就越精细。

逻辑分辨率 #

逻辑分辨率(logical resolution)是经过系统缩放的分辨率。

我用 1920×1080 分辨率,27 英寸的显示器,文字看得清楚。假如我换成同尺寸 3840×2160 的显示器,此时显示器像素数是前者的 4 倍,可以容纳更多的文字,文字会变得小得看不清。在浏览器按几下 Ctrl - 调节缩放也可以看到过小的文字。

在系统设置 200% 缩放后,分辨率就变成了 (3840/2)×(2160/2),也就是 1920×1080,此时文字大小又正常了。3840×2160 是物理分辨率,1920×1080是逻辑分辨率。

相关的 Web API #

以 2560×1440 物理分辨率,200% 缩放的显示器为例,展示相关 Web API 的用法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 逻辑宽度
console.log(window.screen.width) // 1280
// 逻辑高度
console.log(window.screen.height) // 720
// 缩放(物理高度/逻辑高度)
console.log(window.devicePixelRatio) // 2
// 物理宽度,需要借助 devicePixelRatio 来计算
console.log(window.screen.width*window.devicePixelRatio) // 2560
// 物理高度,需要借助 devicePixelRatio 来计算
console.log(window.screen.height*window.devicePixelRatio) // 1440

在线查看分辨率 #

我写了个查看物理分辨率、逻辑分辨率和视口大小的网站,欢迎使用。

网站链接:https://resolution-viewer.cyrusyip.org/

源代码:https://github.com/CyrusYip/resolution-viewer

jQuery 使用笔记

2024-10-23 00:00:00

jQuery 是一个经典的 JavaScript 库,其功能为修改 HTML 元素、处理事件、制作动画、发送请求(Ajax)。jQuery 首次发布于 2006 年 8 月 26 日,现在(2024 年)已经 18 岁了。截止于 2024 年 10 月 23 日,有 75.8% 的网站使用了 jQuery1

虽然 jQuery 的使用率高,但新项目没必要用 jQuery,原生 JavaScript 已经可以实现 jQuery 的操作,参看 You Might Not Need jQueryYou-Dont-Need-jQuery。维护老项目时可能会用到 jQuery。

jQuery 的引入方法很多,我在本文采用 CDN 引入。

1
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>

下面介绍一些常见用法。

获取元素 #

jQuery 使用 CSS 选择器获取元素。

1
2
3
$(document) // 获取整个文档
$("#id1") // 获取 id 为 id1 的元素
$(".class1") // 获取 class 为 class1 的元素

插入元素 #

1
2
<!-- HTML 示例 -->
<div id="container"><p>Container</p></div>
1
2
3
4
$("#container").append("<p>inside-end</p>"); // 在 #container 末尾插入子元素
$("#container").prepend("<p>inside-start</p>"); // 在 #container 开头插入子元素
$("#container").after("<p>outside-end</p>") // 在 #container 后面插入兄弟元素
$("#container").before("<p>outside-start</p>") // 在 #container 前面插入兄弟元素

现在页面上的元素是这样的:

1
2
3
4
5
6
7
<p>outside-start</p>
<div id="container">
 <p>inside-start</p>
 <p>Container</p>
 <p>inside-end</p>
</div>
<p>outside-end</p>

取值与赋值 #

jQuery 使用同一个函数来取值和赋值,根据参数数量进行不同操作。

1
2
<!-- HTML 示例 -->
<h1 id="title">Title</h1>
1
2
3
4
$("#title").html() // 获取 #title 的值
$("#title").html("Another title") // 修改 #title 的值
$("#title").width() // 获取 #title 的宽度
$("#title").width(1) // 修改 #title 的宽度

链式调用 #

jQuery 的每个操作都会返回 jQuery 对象,所以可以进行连续操作。

1
2
3
4
5
<!-- HTML 示例 -->
<div id="container">
 <p>Paragraph 1</p>
 <p>Paragraph 2</p>
</div>
1
2
3
4
5
6
7
$("div") // 选择 div 元素
 .find("p") // 查找 div 里的 p 元素
 .eq(1) // 选择第 2 个元素
 .html("end") // 把第 2 个元素内容修改为 end
 .end() // 退回到上一个选中的元素,也就是 .find("p")
 .eq(0) // 选择第 1 个元素
 .html("start") // 将第 1 个元素内容修改为 start

现在页面是 start 在上面,end 在下面。

资料 #

优化 Hugo 博客速度:Pjax、dynamic script、preload、minification

2024-10-18 00:00:00

本文介绍了优化博客速度的几个方式:Pjax(免刷新加载页面)、dynamic script(动态插入脚本)、rel=preload(预加载)、minification(极简化)。

本博客是 Hugo 生成的静态网站,感觉访问速度还不算慢。有天我看别人的博客(大概是单页应用),发现点击链接居然没刷新网页就加载了新页面,速度非常快。那时我想:要是我的 Hugo 博客也能这么流畅就好了。我感觉把博客改成单页应用要耗费不少时间,遂作罢。

后来我发现可以用 Pjax 技术让静态网站实现免刷新加载页面。Pjax 的意思是 pushState(修改 URL)+ Ajax(asynchronous JavaScript and XML,发送请求)。通俗来说,Pjax 就是请求网页、替换内容、修改 URL,这个过程比加载整个页面更快。

搜索 Pjax 库,找到两个好几年没更新的库(MoOx/pjaxdefunkt/jquery-pjax),我不想用不维护的库。我快放弃的时候发现了一个支持 Pjax 的 Hugo 主题:hugo-theme-luna,从自述文件可以看出 Pjax 是用 swup 实现的,然后我就用它了。

Pjax 免刷新加载页面 #

如果网站没有 JavaScript 代码,那直接加载 swup 就好了。

建议使用这些插件:

  • Head Plugin:刷新 <head> 元素的内容和 <html> 元素的 lang 属性。
  • Preload Plugin:光标在链接时预加载 URL,用户点击时就会内容会马上替换,还可以配置自动加载出现在可见区域的链接。
  • Progress Bar Plugin:加载时间较长时显示进度条。

注意要先加载插件再加载 swup。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<script src="https://unpkg.com/@swup/head-plugin@2"></script>
<script src="https://unpkg.com/@swup/preload-plugin@3"></script>
<script src="https://unpkg.com/@swup/progress-plugin@3"></script>
<script src="https://unpkg.com/swup@4"></script>

<script>
 const swup = new Swup({
 containers: ["body"], // 替换 <body> 的内容
 plugins: [
 new SwupHeadPlugin(),
 new SwupPreloadPlugin({ preloadVisibleLinks: true }), // 预加载页面可见的链接
 new SwupProgressPlugin(),
 ],
 });
</script>

我的博客用到了 3 个 JavaScript 程序:Google Analytics(流量统计)、Giscus(评论服务)、Disqus(评论服务),用了 swup 之后要考虑是否需要额外处理。

读者点击链接加载新页面后的处理:

Dynamic Script 动态插入脚本 #

我写了个动态插入脚本的函数,可以设置等待时间、加载前执行的函数、async、加载后执行的函数、attribute。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function loadScript({
 url,
 delay,
 onloadCallback,
 async,
 preloadCallback,
 attributes = {},
}) {
 function load() {
 if (preloadCallback) preloadCallback();

 const script = document.createElement("script");
 script.src = url;
 script.async = async;

 // Set attributes
 Object.entries(attributes).forEach(([key, value]) => {
 script.setAttribute(key, value);
 });

 if (onloadCallback) script.onload = onloadCallback;

 document.body.appendChild(script);
 }

 if (typeof delay !== "undefined") {
 setTimeout(load, delay);
 } else {
 load();
 }
}

我给 Google Analytics、Giscus、Disqus 加了 100ms 等待时间,给 swup 添加了 200ms 等待时间。

rel=preload 预加载 #

<link> 标签使用 rel="preload" 可以让浏览器提前下载资源(字体、图片、脚本、样式等),后面动态插入脚本时浏览器就可以马上执行下载好的脚本。

示例:

1
2
3
4
5
<head>
 <link rel="preload" as="script" href="https://unpkg.com/@swup/head-plugin@2">
 <link rel="preload" as="script" href="https://unpkg.com/@swup/preload-plugin@3">
 <link rel="preload" as="script" href="https://unpkg.com/swup@4">
</head>

preload 应该叫 predownload,因为它并不会提前加载脚本,只是提前下载。

Minification 极简化 #

这次优化博客没用到极简化,不过既然讲到优化博客了,就顺便说一下吧。极简化就是移除代码中不必要的内容(比如:空格、空行、缩进),从而减小文件大小,这样浏览器就能更快下载完网页。

Hugo 可以极简化 HTML、CSS 和 JavaScript 文件。本博客的代码用 Hugo 极简化了。举个例子,样式文件大小原本是 13.8 kB,经过极简化后是 7.4 kB(原文件的 53.6%),传输过程中再经过 Brotli 压缩后是 2.1 kB(原文件的 15.2%)。

相关代码 #

以下是这次优化用到的代码:

感想 #

我已经用 swup 两三天了,非常满意,真没想到静态网站可以变成单页应用。Preload 插件能让浏览器会自动提前加载页面,读者点击链接时页面会瞬间加载,这个感觉太爽啦!

参考资料 #

将 LineageOS 20 升级到 LineageOS 21

2024-10-11 00:00:00

我手机用的系统是开源的 LineageOS 20(Android 13),跨版本升级到 LineageOS 21(Android 14)需要用电脑手动操作。因为怕操作失误导致无法开机,所以想着先备份资料,但我懒得备份资料,于是好几个月没升级。今天就来升级了。

备份 #

虽然升级 LineageOS 不会清空储存空间,但为了保险起见,我按照自己的需求备份以下内容:

  1. 微信聊天记录
  2. 图片
  3. 电子邮箱账户截图
  4. 闹钟截图
  5. 应用列表

升级 #

按照 Upgrade LineageOS on lisa | LineageOS Wiki 的步骤,安装 LineageOS 21、重启到 Recovery、安装 Google Apps、重启。

这里碰到一个奇怪的问题:手机通过数据线直接插到笔记本电脑的 USB 口,用 fastboot 可以检测到设备,但安装新系统时会报错。数据线插到 USB 集线器才行。

感受 #

升级过程比我预想的简单。系统正常运作,所以清除了前面的备份。目前遇到两个问题:状态栏的快捷设置在亮色模式下仍然是暗色;Fcitx5 输入法底下的导航栏不见了,将「导航栏背景」设置为「跟随键盘背景色」即可解决。

如果你也要升级 LineageOS,不要照搬我的步骤,要遵循 LineageOS Wiki 的步骤,不同设备的升级步骤可能有差异。