分享缓存的光标选区range变量指向被莫名修改的经历

有时我们在做文本输入的时候,经常会需要缓存用户上次输入时的鼠标光标位置,这里就会用到Selection和Range的知识。 前置知识简述 我们在鼠标进行选中文字(不选择也行,点击几个),是可以有API获取当前鼠标的位置信息 通过window.getSelection().getRangeAt(0)获取当前的第一个选区,里面的commonAncestorContainer 就是当前选区的最近的共同父级节点。如果我恩选中多个节点的内容,比如选区包含一个div、一个img和另外一个div,那样这个commonAncestorContainer 就是这三个节点最近的父级节点,比如另一个div。 举例 我们选中了“日期”这两个字,用变量r记录选区range信息。 const r = window.getSelection().getRangeAt(0) 我们可以看到“日期”两个字是数据A标签的,它的父级节点有div.post-meta和div.post-item。 如果我们直接把它的父级节点删掉为怎么样,我们把div.post-item这个节点删掉试试。 现在在控制台打印下之前的变量r,发现它的range指向了div.post-list,而它正是被删掉的div.post-item最近的父级节点。 总结 我们缓存range信息开发的时候一定要注意啦,不能完全信赖自己之前缓存值,不要简单的认为用一个变量保存之前的选区,等到后面想使用的时候随时都能用,这时一定要注意之前的选区有没有被删掉,小心掉坑里了。

【转载】Keep运动记录可以转换成fit和tcx格式导入高驰佳明啦

本文源自运动记录转换工具的《支持转换Keep运动记录啦》 导出数据 先从Keep官方申请导出数据,等收到官方的回复邮件,邮件内容大致如下: 亲爱的 Keeper , 您好,已将您所需信息数据导出,详情可参考附件,文件密码是您账号绑定的手机号,辛苦您注意查收。若有格式需求辛苦您自行转换呢,如果有造成不便的地方还请您谅解,感谢您对 Keep 的支持。 导出的数据在附件里面,解压后只有一个excel文件,里面的内容如下啊: 有运动类型、运动时长、开始时间、结束时间、时长、距离、卡路里、平均心率、最大心率、心率记录(应该是一秒一个记录值)、运动轨迹(但是是一个轨迹图片,不是具体的经纬度信息) 数据转换 Keep官方的邮件已经明确说了若有格式需求辛苦您自行转换呢,看来只能自行想办法了。 经过开发后,转换工具已经支持了Keep记录的转换,转换后的效果如下: 总结 Keep的运动记录也是可以导出的,官方导出的数据细节不是很全,没有轨迹经纬度信息,仅心率数据(如果有的话)是齐全的 根据现有数据的情况,转换结果能完美还原

nextjs动态生成sitemap.xml的修改日期

nextjs是可以自行生成网站的sitemap.xml的,但是在打包发不到生产环境后,发现写的日期并没有生效,而是当时打包时的日期,百思不得其解。 此前是自定义src/sitemap.js来实现的。 import siteConfig from '@/app/siteConfig'; import { getMdList, getUpdateData } from '@/lib/utils'; export default function sitemap() { const mdList = getMdList(); const pathnameList = mdList.map(item => item.pathname); const updateDate = new Date(); const pageList = pathnameList.map(item => { // 如果是 /xxx/index, 则去掉 /index const pathname = item.replace(/\/index$/, ''); return Read more…

eletron应用、electron npm包和前端静态资源怎么通信

最近有个需求需要改动electron项目壳的功能,所谓壳的功能指的是electron套壳应用中前端静态资源自身做不了,需要借助electron应用的能力来实现的功能。 electron应用可以会需要引用npm包,只不过这些包是针对electon应用的。 分析 所以我们现在有这样三类资源可能存在通信 electron壳、electron npm包、前端静态资源,这些“应用”之间通常怎么通信呢? electron壳 <–> electron npm包 electron壳直接引用electron npm包即可,类似前端静态资源直接引用对应的npm包。 electron壳 <–> 前端静态资源 electron壳通过创建BrowserWindow来loadFile加载将前端静态资源,把需要暴露的功能直接挂载前端的window上面,它们就能实现通信了 electron npm包 — 前端静态资源 它们属于不同类型的“应用”,它们直接不能直接进行通信,需要借助electron壳,走前面的“electron壳 <–> 前端静态资源”路线 不同类型的应用(比如node应用和C++应用)直接需要通过IPC通信,它们之间通信一般只能通过发送消息传递数据(json或字符串),无法像平时注册回调函数,一般只有同类型的应用才能注册回调函数。 举例 下面以一个electron npm包(自带静态资源,整个包类似一个小electron应用)与前端静态资源通信为例 electron npm包通过创建BrowserWindow来loadFile加载自身的前端资源来实现交互部分,对外暴露接口初始化窗口UI。 index.js class Plugin{ … open(options) { const win = new BrowserWindow({ …options webPreferences: { … preload: ('./preload.js') } }); win.loadFile('xxx.html'); win.once('ready-to-show', Read more…

nextjs根据动态路由优雅处理目录首页url和无效url

前几天写到怎么让nextjs根据动态路由读取指定markdown文件内容,提到了在nextjs项目的app目录下创建一个[…slug],然后在里面的page.js里面实现路由 function absPath(dir) { return ( path.isAbsolute(dir) ? dir : path.join(process.cwd(), './src/markdown', dir) ); } async function getFileData(slug, dir = './') { const slugList = Array.isArray(slug) ? slug : [slug]; // 最后一项为文件名,其余是目录名 const rawId = slugList.pop() || ''; const id = rawId || 'index'; // 为空时默认为 index let dirPath = Read more…

怎么让nextjs根据动态路由读取指定markdown文件内容

最近用了用nextjs,发现用它建设个小型站点还是很方便的,兼备服务端渲染。 站点架设好之后,后面更多的是写文章,不需要太多的代码改动了,一般来说写写文章,又不用花哨的排版的话,用markdown就很方便了。 使用的是nextjs最新14.x版本+app router模式, front-matter 为了能让markdown文件如果文章内容部分外,还兼有标题、发布时间、关键词等自定义信息,我们可以借助front-matter — title: 测试 description: '测试下描述' keywords: '关键词' date: 2023-12-16 — 这里就是内容啦 这里的title等信息就可以在front-matter的帮助下,能程序能直接识别出来了,比如就可以将里面的title内容放在html的title里面了。 front-matter用法如下 import { promises as fsp } from 'fs'; import fm from 'front-matter'; const data = await fsp.readFile('abc.md', 'utf8'); const matter = fm(data); 然后我们就能在matter里面拿到title、description等信息,md文件的主体内容则在matter.body里面 marked 有时我们在markdown里面可能会写些html,并且有些排版只能依靠html来完成了 import { parse } from 'marked'; Read more…

目前市面上的拼写检查工具哪家强?没有调研就没有发言权

目前市面上的含拼写检查功能产品主要分两种,拼写检查类和写作助手(支持拼写检查、语法检查、书写润色等)类。 下面分别以这两类的典型产品举例。 拼写检查类产品 一、chrome类拼写检查 目标文本识别 自动识别特定html元素内的文字 具体要求如下: input、textarea以及设置contenteditable为可编辑的元素 input、textarea未设置disabled或readonly 未设置spellcheck=false 检查结果标记 自动对目标文本进行检查,并用自动用红色波浪线标记存在拼写错误的单词。 拼写错误替换 在结果标记处右键,系统会自动选中被标记字符,选择目标候选词进行点击即可完成覆盖替换 集成方式 无需额外安装 支持语种 南非荷兰语, 保加利亚语, 加泰罗尼亚语, 捷克语, 威尔士语, 丹麦语, 德语, 希腊语, 澳大利亚英语, 加拿大英语, 英国英语, 美国英语, 西班牙语, 拉丁美洲西班牙语, 阿根廷西班牙语, 西班牙西班牙语, 墨西哥西班牙语, 美国西班牙语, 爱沙尼亚语, 波斯语, 法罗语, 法语, 希伯来语, 印地语, 克罗地亚语, 匈牙利语, 亚美尼亚语, 印度尼西亚语, 意大利语, 韩语, 立陶宛语, 拉脱维亚语, 挪威博克马尔语, Read more…

markdown是不会用还是不好用?自研vscode插件来帮忙,甲方运营人员大呼好用

背景 随着使用markdown语法编写内容越来越流行,有的程序员也开始给甲方做网站时使用markdown来编写文章了,比如用hexo博客系统建站。 使用markdown语法能减轻程序员寻找富文本编辑器的成本,毕竟富文本编辑器的坑太多了,但是markdown有一定的语法门槛,并且它本身还是存在不足的,比如无法实现内容居中、文字两端对齐等。 程序员不能只顾自己方便,甲方说markdown不会用或者说不好用怎么办呢?我们可是试试用vscode的插件来帮忙,简化markdown的用法同时对它进行增强。 思路 使用markdown时一个几乎必备的辅助功能就是所见即所得,不预览看下的话,我们对自己编写的内容“长”什么样子总会觉得不放心吧,而我们平时基本都是借助编辑器自带的功能(或者插件)来实现markdown内容的预览。 既然要使用编辑器编写markdown的话,为何不使用开源的vscode,它免费,支持插件,并且插件开发简单,同时还可以在编辑器预览markdown时加载自己的css文件,功能可谓是相当强大啊。 markdown语法里面是可以嵌套html语法的,有了html就几乎无所不能了,对于markdown默认不支持的写法,我们可以换个思路,改用html+css的形式来实现了,只需要额外在vscode预览markdown时加载我们自己的css文件,我们特有的样式效果就出来了。 那我们就借助vscode插件来增强markdown功能吧。 步骤 编写html+css 因为markdown语法里面是可以使用html写法的,有了html就几乎无所不能了,对于markdown默认不支持的写法,我们可以换个思路,改用html+css的形式来实现。并且vscode在预览markdown的时候是可以加载自定义url的css的,这样我们就可以加载出自己特有的样式效果了。 比如图片居中 <div class="post_center"> <img class="post_block-item" style="max-width: 80%;margin-bottom: 16px;" src="https://https://www.baidu.com/img/pcyayunhuikaimushidoodle_35c0ef27c30a077f2e46ddb5db1993ef.gif"> </div> 我们可以把较为通用的样式写在自定义css文件里面,在html里面直接使用对应的class即可,用户可能需要调整的直接写在内联style里面,只要网站和编辑器预览使用同一个css文件,就能把我们增强的样式效果显示出来了。 markdown预览加载自定义css文件 在网站上加载这个自定义css文件很简单,只是编辑器预览markdown时怎么加载这个css文件呢?解决不了这个的话,用户在预览的时候不就没效果了吗? 这里就要用到vscode编辑器,它编写插件很简单 具体的vscode插件教程去官网看下文档就好 我们可以控制在当前的Workspace配置markdown加载的css地址 本功能的代码如下 import * as vscode from 'vscode'; export function activate(context: vscode.ExtensionContext) { vscode.window.showInformationMessage('md-editor-helper is activing!'); vscode.window.showInformationMessage('md-editor-helper is initialing'); vscode.workspace.getConfiguration().update("markdown.styles", [ "https://example.com/css/post.min.css"], vscode.ConfigurationTarget.Workspace).then(() Read more…

electron应用的拼写检查终于在给chromium提了issue之后,新的修复方案更好

之前提到过《electron应用更新版本后的拼写检查失效?原来一行代码就搞定 》,问题的原因是因为官方部分语种的下载地址重定向后的cdn地址不可访问,导致国内无法下载到字典文件,并且我提议直接将各语种的字典文件下载下来,放到自己的服务器上,然后修改electron应用下载字典文件的请求url(electron提供的有该api)。 setSpellCheckerDictionaryDownloadURL('http://example.com/'); 其实各语种字典文件更新并不频繁,我们甚至半年更新一次或者不更新都行,对用户来说现有的字典文件拼写检查能力足矣。 小组N多项目都有自己的服务器,将这些字典文件随便选一个现有服务器放置即可。 但是此解决方案领导并不认可,他拒绝的理由如下 这并不是最彻底的解决方案 不想自己维护一套字典文件 目前有临时方案:可以让TS团队协作报障的用户复制字典文件至本机 每次看日志发现国内用户基本就没有下载成功过,所以这个报障我个人是偏向于尽快解决的,手动复制太费事了。 我只能硬着头皮继续想解决方案,还好当时我在发现这个问题的时候尝试联系chromium反馈了这个问题,并且提了一个issue Issue 1468940: chrome spell check service redirect some language dictionary resouce to a bad url in China,我能看到的团队对我提的issue进行了分类(应该不是AI完成的吧),但是没有进行任何有效的答复,然后再半个月之后领导发现字典文件url重定向后的cdn地址更新了,不再是之前有问题的那个了。 但是又出现了一个新的问题。。。https证书问题 只有点击后能继续下载操作,我继续在issue反馈这个一问题。 同时发现将路径地址直接改成http访问可以正常下载,并且electron应用并没有强制要求一定得用https,这个问题总是得到了解决,虽然不是很完美,但是已经算不错了。 setSpellCheckerDictionaryDownloadURL('http://redirector.gvt1.com/edgedl/chrome/dict/'); 各个语种的字典文件总是都能成功下载了 拼写检查也能正常工作了

electron应用更新版本后的拼写检查失效?原来一行代码就搞定

小组的项目半个月前更新了一个小版本,然后大家纷纷问我是改了啥? 我也一脸懵逼啊,我啥以没干啊,那个小版本里面有我这边的一个紧急需求,这个“锅”我推都不好推,只能怪运气不好。 本来指望小组负责electron部分的同事来牵头解决的,虽然报障是从我复制的邮件这边开始报障的,主要是因为邮件客服比较依赖这个功能吧,功能失效了写英语也没底气了,直接报障了。 但是懂行的都知道,这个不是前端仔随便就能干预的功能,所以需要在electron层来想解决方案。 后面几天我还在码需求,改bug呢,临近发版前总算有些许闲暇,毕竟即使有无关紧要的bug也不宜再匆忙改代码了。 同事太忙也一直没时间跟进这个故障,那只能自己来了。 自己凭借个人经验开始了自己的故障定位之旅。 1、从electron官方SpellChecker模块了解到hunspell dictionary,它默认从Google CDN下载下来的。 猜测下载失败可能会影响拼写检查,了解相关知识点准备验证猜想。 2、从项目spellcheck关键词,发现有spellcheck-dictionary相关的事件 尝试在项目加入监听electron抛出的spellcheck-dictionary-download-begin、spellcheck-dictionary-download-success、spellcheck-dictionary-download-failure、spellcheck-dictionary-download-initialized等事件 发现监听到spellcheck-dictionary-download-begin和spellcheck-dictionary-download-failure,无spellcheck-dictionary-download-success、spellcheck-dictionary-download-initialized事件,确定spellcheck-dictionary的确下载失败 3、从网上搜索及electron源码了解到字典文件位于electron个人目录下的Dictionaries文件夹内,尝试在拼写检查未失效的electron应用中删除该文件,电脑提示该资源被electron应用占用,确定Dictionaries内的字典文件为electron应用使用 4、根据文档尝试setSpellCheckerDictionaryDownloadURL干预spellcheck-dictionary的下载地址,因具体待下载的语言词典文件名信息不确定,先本地用http-server启一个服务,测试setSpellCheckerDictionaryDownloadURL如何生效以及electron下载字典请求的url信息 在创建window时加入 newWindow.webContents.session.setSpellCheckerDictionaryDownloadURL('http://127.0.0.1:8080/'); 确认本地服务器接收到electron的下载请求,并且请求url形如 http://127.0.0.1:8080//en-us-9-0.bdic 5、寻找拼写检查字典en-us-9-0.bdic文件,从其它未失效的用户电脑复制或从互联网搜索,验证字典下载能否成功 成功接收到spellcheck-dictionary-download-success、spellcheck-dictionary-download-initialized事件,同时Dictionaries文件夹内成功下载字典文件 6、mcd重新打包,再次验证上述改动 setSpellCheckerDictionaryDownloadURL设置为能成功下载字典文件的外网url服务地址 newWindow.webContents.session.setSpellCheckerDictionaryDownloadURL('https://wp-img.daozhao.com/im_dict/'); 改动后的新版安装包拼写检查功能正常 7、获取拼写检查其它语言对应的字典文件名信息 8、优化代码,正式修复 总结 大胆假设,小心求证