惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

Fooleap's Blog

渴望理想 | Fooleap's Blog 19 年底一些事 | Fooleap's Blog 藉秋风,跑起来 | Fooleap's Blog 一个人去跑步 | Fooleap's Blog 8 月的跑量仿佛是那暑假的作业 | Fooleap's Blog 三伏天跑步那么难受,为何还要跑? | Fooleap's Blog 解决小程序开发“当前系统代理不是安全代理” | Fooleap's Blog 忘却配速的夏日跑步 | Fooleap's Blog 六月天时“带水”跑步更爽 | Fooleap's Blog 出来混迟早要还的 | Fooleap's Blog 跑步不能当饭吃 | Fooleap's Blog 将京东移动端详情页链接转为 PC 端 | Fooleap's Blog 不是热就是雨 | Fooleap's Blog 这半月,我跑了 11 个 520 | Fooleap's Blog 跑完流汗一时爽,一直流汗一直爽 | Fooleap's Blog 初夏夜跑 | Fooleap's Blog Electron 中打开 QQ 临时会话 | Fooleap's Blog 春节期间的培隆角 | Fooleap's Blog 从春天跑到夏天 | Fooleap's Blog 晨雾中奔跑 | Fooleap's Blog 漫步春雨中 | Fooleap's Blog 跑在木棉花下 | Fooleap's Blog 我在春节依然坚持跑步 | Fooleap's Blog 伴随着日出跑步 | Fooleap's Blog 没有最好,只有更好 | Fooleap's Blog 电子气温计 | Fooleap's Blog 渡亭小学的金凤花 | Fooleap's Blog 随心而跑 | Fooleap's Blog 2018 跑步小结 | Fooleap's Blog 在 gVim 中使用“非等宽字体” | Fooleap's Blog 动车进汕,喜大普奔 | Fooleap's Blog 雨战汕马,漫步鮀城 | Fooleap's Blog 准备出发汕马 | Fooleap's Blog 环苏溪跑个半马 | Fooleap's Blog 不义之财 | Fooleap's Blog 跑去培隆看日落 | Fooleap's Blog 雨后跑土路 | Fooleap's Blog 秋意渐浓 | Fooleap's Blog 在夕阳下奔跑 | Fooleap's Blog 准备参加 2018 汕马 | Fooleap's Blog 不可立见的 spoiler 标签 | Fooleap's Blog TomTom Spark 表带 | Fooleap's Blog Disqus 支持新浪微博图床 | Fooleap's Blog 暂存 Disqus 匿名评论者邮箱地址 | Fooleap's Blog 组一台迷你主机 DeskMini 310 | Fooleap's Blog 我的个人信息卖给了谁? | Fooleap's Blog 我发了违法短信? | Fooleap's Blog 使用 Python 合并地图瓦片 | Fooleap's Blog 使用 Python 合并瓦片图 | Fooleap's Blog 拆电热水壶 | Fooleap's Blog 使用树莓派做监控显示 | Fooleap's Blog 南方的冷 | Fooleap's Blog 蓝牙耳机 Avantree Jogger Plus | Fooleap's Blog 新厝布网 | Fooleap's Blog 报装移动宽带 | Fooleap's Blog 双十一战绩 | Fooleap's Blog 郁闷的心情 | Fooleap's Blog 像 Disqus 一样获取链接颜色 | Fooleap's Blog Disqus 的 URL 编码问题 | Fooleap's Blog 选择框的全选联动 | Fooleap's Blog 弹出层中的视频全屏问题 | Fooleap's Blog 2016 年台风海马 | Fooleap's Blog 纯 CSS 实现导航图标动画 | Fooleap's Blog 湾头晨跑路线推荐:南湾小学跑道 | Fooleap's Blog Jekyll 显示每一年的文章数 | Fooleap's Blog 湾头晨跑路线推荐:南湾堤顶 | Fooleap's Blog 近日渡亭堤顶的夕阳 | Fooleap's Blog 使用 Disqus API 上传图片 | Fooleap's Blog Disqus API 评论嵌套问题 | Fooleap's Blog Disqus API 的权限问题 | Fooleap's Blog 湾头晨跑路线推荐:环三湾 | Fooleap's Blog 如何下载 Apple Emoji 的 PNG 图片 公众号文章二维码 | Fooleap's Blog Disqus 的评论预审核 | Fooleap's Blog 湾头最好的跑道 | Fooleap's Blog 结合七牛和高德地图 API 显示照片位置 | Fooleap's Blog Zip 压缩排除特定目录 | Fooleap's Blog 流水涸摸蚬热 | Fooleap's Blog 2017 跨年跑 | Fooleap's Blog Jekyll 的中文字数统计 | Fooleap's Blog 为 Jekyll 文章页添加相关文章 | Fooleap's Blog 为 Jekyll 添加一个标签页面 | Fooleap's Blog 干了这瓶蛇草水 | Fooleap's Blog 在 macOS 上使用 NTFS 差点丢数据 Disqus Moderator Badge Text 已支持中文 为 Jekyll 添加一个简单的 API | Fooleap's Blog 为 Jekyll 加上简单搜索功能 | Fooleap's Blog 解决 Jemoji 的出错 | Fooleap's Blog 检测网络是否能够访问 Disqus | Fooleap's Blog 解决 This socket is closed 问题 更好的 Markdown 插图方式 | Fooleap's Blog 转换 Nike+ 的坐标数据 | Fooleap's Blog 高德地图 API 显示跑步路线 | Fooleap's Blog 善用 Google 搜索工具 | Fooleap's Blog 利用 Nike+ API 获取跑步路线数据 | Fooleap's Blog 七牛 API 生成页面 URL 二维码 旧年 12 月跑步笔记 | Fooleap's Blog 科学使用 Disqus | Fooleap's Blog 培隆角的日出 | Fooleap's Blog 11 月跑步笔记 | Fooleap's Blog
Disqus 的 @ 提及功能 | Fooleap's Blog
fooleap · 2017-08-15 · via Fooleap's Blog
  1. 留言者不一定要回复某人,却想提醒某人来看
  2. Disqus 的回复邮件通知,默认只通知其父评论的留言者,其余均不通知

使用 @(at) 提及功能引起某人的注意,是 Twitter 发明的[1]。现在这个功能已经是社交平台的标配,也成为我们所认为的社交平台都应有的功能。正如你想的那样,Disqus 评论框早在 2011 年开始便支持 at 提及功能[2]

Disqus 的 at 功能,不仅仅可以 at 参与该帖的评论者,而是全体 Disqus 注册用户均可提及,甚至还支持提及 Twitter 用户。至于如何使用,Disqus 已经说得很详细[3],在此鄙人就不再多话。

我们需要探讨的是,使用 Disqus API 实现的评论框,应该如何实现 at 提及功能?

Disqus 原生的文本编辑框,用的并不是普通文本输入控件 <textarea> 标签,所以它的表现形式比较多样化。抛去华丽的外表,at 某人之后发表评论时,看下请求(也可去后台管理点编辑查看)便可知道,它 at 某人的标识是这样的:

其中 username 是想要提及的 Disqus 用户的 username,若是想提醒 Twitter 用户则是:

自制评论框实现 @ 功能

那么采用 Disqus API 自己做的评论框,又应该怎么实现这个 at 功能呢?我目前评论内容部分用的是 <textarea>,也就是说,在不做任何处理的前提下,仅需在文本框内直接输 @fooleap:disqus 就能 at 到我。

此前 @sengmitnick 提到 @ 功能没什么卵用,我想让它有卵用,所以明白了 Disqus 提及功能之后,就决定动手为自制评论框做个相对好用一点的提及功能。我不打算改变原有的纯文本编辑框,依然使用 <textarea>

在实现之前,我梳理了下初步实现的思路:

  1. 支持 at 的对象:该帖已加载评论的 Disqus 用户,已够用。
  2. 以什么形式代表 at 某人?@username,比较折中的显示。
  3. 输入 @ 后怎么显示 autocompleter:观察到和 GitHub Issues 的编辑框有不少相似点,考虑过滤器跟 Github 一样的形式[4],跟随光标显示,可用鼠标或键盘选择。

替换字符

其中第 1、2 点,实现起来比较方便,思路清晰:

  1. 在后端返回每条评论作者的 Username 即可,定义一个数组 users,遍历评论时,判断里面是否存在该评论者的 Username,没有就扔进去。
  2. 发表评论时,使用正则替换,符合 @username 的字符串,若 username 存在于 users 数组,便替换为 @username:disqus

第二步可实现如下:

// message 为评论内容,users 为 username 数组
var mentions = message.match(/@\w+/g);
if( !!mentions ) {
    mentions = mentions.filter(function(mention) {
        return users.indexOf(mention.slice(1)) > -1;
    });
    if( mentions.length > 0 ){
        var re = new RegExp('('+mentions.join('|')+')','g');
        message = message.replace(re,'$1:disqus');
    }
}

没有过滤处理,因每篇文章的 Disqus 用户并不多,少数情况下会出现 BUG。

显示自动完成过滤框

第三点稍微复杂一点,看似简单的跟随光标显示筛选框,但里面有个比较烧脑的坑,那就是如何获取 textarea 内光标的坐标?

使用 selectionStartselectionEnd 可以获取到光标的位置,但是没办法获取到相关的坐标。我没有过多的研究,而是直接通过 Google 搜索解决,一种实现的思路[5]如下:

  1. 创建一个 div,将 textarea 的样式全部复制给它,并设置 position: absolute
  2. 复制开头到光标处的字符串到 div 内部,在字符串后面插个 span
  3. 获取到 span 在这个 div 的相对位置(offsetTop, offsetLeft),这也就是 textarea 光标处的相对坐标
  4. 一旦获取到就把 div 移除掉

其他的就相对简单一点,思路如下:

  1. 监听 keyup 事件,获取 selectionStart 前最后一个 @selectionStart 的字符串,字符串符合规则 /^@\w+$|^@$/ 就往前走。
  2. 以上字符串去掉 @ 字符,再去跟已存在的每个 username 做正则匹配(忽略大小写)。
  3. 若过滤后的 username 列表不为空,使用上面获取到的坐标显示出来,并监听鼠标事件 mouseroverclick,键盘事件 keydown(上下方向键、回车)。
  4. 一旦规则不符,移除过滤列表和键盘事件 keydown 的监听。

列表样式结合 GitHub 及 Disqus,具体的效果如下:

评论框 at 效果

目前仅局限于 at 已登录用户,匿名评论暂不添加。

参考资料

本文历史

  • 2017 年 08 月 15 日 完成初稿
  • 2017 年 08 月 15 日 修改部分 “@” 为 “at”

最近更新

猜你喜欢