新增画廊模式 我的博客系统一直有个缺撼是没有画廊模式,所以我不写有大量图片的文章——横竖图宽度不一,并且页面过长,极不美观。我没有想到好的开发方案,搁置至今。但是为了写《2025 CMS 杭州车展小记》,我重新拾起这个历史包袱攻克之。 开发画廊的困难不在前端,而在后端如何组织数据。我研究过 WordPress 块编辑器的图库,以及插件实现的画廊。一来操作步骤繁琐,二来存入数据库的是 html 代码,都不如意。我的设计理念是人只需最简洁的操作,剩下全由程序完成。我只想基于 Markdown 本身实现,不想引入新的复杂操作。 我注意到 Markdown 解析图片有以下情况: 同一行排列,两个 由相应数量的空格分隔: ![][1]![][2] [1]: img1.jpg [2]: img2.jpg 换行排列,两个 由 分隔: ![][1] ![][2] [1]: img1.jpg [2]... 2025-06-09
新增语音转文字效果 我做了一个栏目叫做“有话直说”,用于表达负面或激烈的情绪。以语音的形式来直观生动地呈现,同时在 RSS 结果中排除,避免被搜索引擎爬取。我感觉不错,但是obaby说要加语音转文字。怎么办呢?自己的榜一自己宠,连夜做了功能。 分享一下设计思路。前端比较简单,就是点击后向下展开一个气泡框。前端唯一的思考就是怎么做点击交互,首先当然是参考微信,但是存在两个问题。一是长按语音条呼出操作界面,在手机端比较自然——得益于微信等软件的用户习惯培养——但是在电脑端这就很怪。二是微信长按呼出的是一组功能键,而我只有一个功能。长按呼出界面,再点击里面唯一的按钮,这就是典型的脱裤子放屁。最终我的方案是在语音条上显式地放置一个图标 作为按钮。 再来说后端。我只是要做语音转文字的【效果】,并不需要真实的即时转换,实现起来就是将整理好的文字录入后台。那么最大的难点是怎样保存这个文本。最简单的就是用一组闭合标签包裹... 2025-01-25
内嵌抖音视频 抖音开放平台提供了内嵌抖音视频的方法,详见《通过VideoID获取IFrame代码》。 示例代码: 与B站不同,抖音iframe没有做自适应,需要结合自己网站调整样式。下面以我的网站为例。 手机端代码: .douyin { width: min(324px, 100%); margin-inline: auto; overflow: hidden } .douyin iframe { aspect-ratio: .4821 } 电脑端代码: .douyin { width: max(730px, 100%); margin-inline: auto } 写这篇文章的起因是我刷到了上面这条搞笑视频,想写文章分享。之前在风记星辰那里看到过内嵌抖音视频,参考他的样式,并研究了抖音官方文档,实现了期望效果。不过有一个坑是父级元素宽度小于730px会强... 2025-01-12
新增亲子日记封面保护 新增亲子日记封面保护机制:可信设备展示缩略图,陌生设备展示模糊图。可信设备(Cookie标记)包含博主(我本人)、知道日记口令的(我家人)、当前设备发表过评论并被审核通过的。图片表现如下: 老婆跟我抱怨过很多次,首页展示宝宝照片封面有隐私风险,这次解决了这个问题。最初就想到用图片模糊来处理,但碍于影响浏览体验没有下决心。现在想通了,除了我和家人,并没有人会在乎宝宝每天的成长照片。 因为前面已经做了权限验证,所以加一道拦截非常容易。实际开发这个功能的时间花在纠结用哪种模糊效果上,我筛选后的方案分别是Low Poly、毛玻璃和油画。 Low Poly 是我最感兴趣的方案,用了最长的时间来研究和测试。但经过反复验证,应用在小尺寸的封面图上效果很糟糕,将单元调大就毫无细节,调小就有锯齿感,无奈放弃。而毛玻璃效果有令人不适的粗糙感,也淘汰了。最后我选定的方案是油画效果,画面足够模糊,同时细节又足够丰... 2024-11-18
iOS Safari 回退导致 alert 失效 我在文章页增加了解析运行 html 和 js 源码的功能。然后发现一个诡异的问题,在手机端 Safari 按回退和前进键会导致 alert 失效。验证了电脑端和手机端各种浏览器,仅手机端 Safari 复现这个问题。 我查到的解释是: alert/confirm/prompt dialogs will not be displayed if the user has navigated back to a pushState location. Once a user has navigated back (at any point), calling alert(…), confirm(…), or prompt(…) will not display dialog boxes. confirm(…) will always return false, and prompt(…) wil... 2024-11-10
全屏事件触发 resize 事件 我之前发现播放视频时进入全屏会闪退。奇怪的是 Chrome 和 Firefox 存在这个问题,但 Safari 正常。正因为如此对我造成了误导,没有找到问题所在。直到今天发现了这个乌龙。 拖动改变浏览器窗口大小时会造成图文排版变形,所以我监听到 resize 事件就会重新渲染页面——表现之一就是视频进入全屏时“闪退”成了非全屏窗口,video 元素被清除了,重新渲染为缩略图 img。 那么解决这个问题就是监听到 resize 事件时增加一个判断是否全屏。 is_fullscreen = () => !!( document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement... 2024-10-25
也谈网站镜像攻防 近期不少博友遇到网站被恶意镜像的问题。我在 Google 没查到自己的镜像站,不过后台发现很多来源是不良网站的访问,不确定是否跟镜像站有关,因此也谈一下这个话题。 先说结论,网站被镜像易攻难守,没有完美的解决方案。前端可以拦截正常的浏览器访问,但是拦不住爬虫;后端拦不住域名伪造。目前我做了前端拦截 + 防盗链,可以将正常访客引导到主站,但是对搜索引擎爬虫没有找到办法。 接下来从攻防两个视角来分别讨论。 攻 Nginx 实现镜像 server { listen 80; listen 443 ssl http2; #篡改域名 server_name dujun.us.kg; location / { gzip off; proxy_set_header Accept-Encoding ""; #替换网页内容... 2024-09-26
双击全选代码文本 我代码高亮是几年前参考Prism改写的,留有一个遗憾是缺失复制代码文本的功能,因为我一直没有找到理想的交互方式。常见的办法是在右上角放一个常驻或悬停可见的复制按钮,点击后自动将全文复制到剪贴板。我不认可这个设计,一是按钮造成一小块遮挡,二是移动鼠标去找一个按钮进行复制不是很自然的交互,特别是文本较长需要往上回滚的情况下。 我平时习惯双击选中一段文本,按照这个方式增加了双击全选代码文本的功能——仅全选而不自动加入剪贴板,防止误触。 $pre.on('dblclick', () => { let range = document.createRange(), selection = window.getSelection(); range.selectNodeContents($pre[0]); selection.removeAllRanges()... 2024-09-26
乱码导致 json_encode 失败的解决方法 发现访客日志缓存失效,定位到写入 redis 时数据经 json_encode 变成了空字符。调用 json_last_error_msg() 打印出报错信息为:"Malformed UTF-8 characters, possibly incorrectly encoded"。 解决办法是增加参数 JSON_INVALID_UTF8_IGNORE,过滤掉乱码字符: json_encode($value, JSON_INVALID_UTF8_IGNORE); 2024-09-19
更换天气信源 宝宝日记后台编辑器根据定位自动获取当日天气信息。这项功能开发于 2017 年,当时选定的方案是采集中国天气网页面,通过正则表达式提取相关数据。但现在偶然发现其天气信息与墨迹天气 APP 有差别,我到中国气象局官网验证,与墨迹天气是一致的,也就是说中国天气网数据是错误的。不准确的信源毫无意义,马上决定更换。 经过对比,最终选定和风天气作为新的天气信源,免费版接口支持每天1000次请求。 注册 在官网注册账号(需要邮箱和手机号),创建一个免费订阅,记录 KEY 值。 调用 详见文档:https://dev.qweather.com/docs/api/weather/weather-daily-forecast/ 接口调用 PHP 代码参考: declare(strict_types = 1); /** * 天气 (和风天气) */ class Vendor_Weather { //... 2024-09-11