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

推荐订阅源

宝玉的分享
宝玉的分享
T
Threat Research - Cisco Blogs
H
Hacker News: Front Page
N
News and Events Feed by Topic
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
SecWiki News
SecWiki News
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tor Project blog
K
Kaspersky official blog
Forbes - Security
Forbes - Security
Webroot Blog
Webroot Blog
Schneier on Security
Schneier on Security
P
Privacy & Cybersecurity Law Blog
H
Heimdal Security Blog
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
V
Vulnerabilities – Threatpost
T
Tenable Blog
T
Tailwind CSS Blog
P
Privacy International News Feed
WordPress大学
WordPress大学
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
博客园 - Franky
Hacker News: Ask HN
Hacker News: Ask HN
Jina AI
Jina AI
C
Cybersecurity and Infrastructure Security Agency CISA
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
雷峰网
雷峰网
Vercel News
Vercel News
A
About on SuperTechFans
爱范儿
爱范儿
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog
The Last Watchdog
The Last Watchdog
Engineering at Meta
Engineering at Meta
Spread Privacy
Spread Privacy
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园 - 司徒正美
量子位
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recorded Future
Recorded Future
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Martin Fowler
Martin Fowler
Project Zero
Project Zero

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活 翻译 – CSS Sprites:实用技术还是生厌之物? « 张鑫旭-鑫空间-鑫生活 纯CSS实现易拉罐3D滚动效果 « 张鑫旭-鑫空间-鑫生活 纯CSS实现侧边栏/分栏高度自动相等 « 张鑫旭-鑫空间-鑫生活 CSS+JavaScript实现页面不同布局的切换 « 张鑫旭-鑫空间-鑫生活 JavaScript实现最简单的拖拽效果 « 张鑫旭-鑫空间-鑫生活 自己写的无图片版jQuery zxxbox弹出框插件 « 张鑫旭-鑫空间-鑫生活 中国古代道家思想与网页重构的思考 « 张鑫旭-鑫空间-鑫生活 让所有浏览器支持HTML5 video视频标签 « 张鑫旭-鑫空间-鑫生活 纯CSS实现各类气球泡泡对话框效果 « 张鑫旭-鑫空间-鑫生活 JS HEX十六进制与RGB, HSL颜色的相互转换 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变、高光等文字效果 « 张鑫旭-鑫空间-鑫生活 去除冗余 – 精简您的CSS样式代码 « 张鑫旭-鑫空间-鑫生活 对overflow与zoom”清除浮动”的一些认识 « 张鑫旭-鑫空间-鑫生活 jQuery Pagination Ajax分页插件中文详解 « 张鑫旭-鑫空间-鑫生活 absolute绝对定位的非绝对定位用法 « 张鑫旭-鑫空间-鑫生活 网页布局思想浅议-淘宝新版首页为实例 « 张鑫旭-鑫空间-鑫生活 回流与重绘:CSS性能让JavaScript变慢? « 张鑫旭-鑫空间-鑫生活 CSS float浮动的深入研究、详解及拓展(二) « 张鑫旭-鑫空间-鑫生活 CSS float浮动的深入研究、详解及拓展(一) « 张鑫旭-鑫空间-鑫生活 60个极富创造性的震撼的电影海报设计 « 张鑫旭-鑫空间-鑫生活 jQuery Lightbox(balupton版)图片展示插件讲解 « 张鑫旭-鑫空间-鑫生活 博客内嵌flash音乐播放器代码、下载与使用 « 张鑫旭-鑫空间-鑫生活 CSS3 animate实现图片墙3D翻转效果 « 张鑫旭-鑫空间-鑫生活 图片旋转效果的一些研究、jQuery插件及实例 « 张鑫旭-鑫空间-鑫生活 CSS3 border-image详解、应用及jQuery插件 « 张鑫旭-鑫空间-鑫生活 jQuery-两款不同原理的圆角插件讲解 « 张鑫旭-鑫空间-鑫生活 页面可用性之outline轮廓外框的一些研究 « 张鑫旭-鑫空间-鑫生活 CSS3 transition实现超酷图片墙动画效果 « 张鑫旭-鑫空间-鑫生活 HTML CSS列表元素ul,ol,dl的研究与应用 « 张鑫旭-鑫空间-鑫生活 jQuery图片文本滚动切换插件jCarousel中文翻译与详解 « 张鑫旭-鑫空间-鑫生活 酷酷的jQuery鼠标悬停图片放大切换显示效果 « 张鑫旭-鑫空间-鑫生活 IE6下z-index犯癫不起作用bug的初步研究 « 张鑫旭-鑫空间-鑫生活 checkbox复选框的一些深入研究与理解 « 张鑫旭-鑫空间-鑫生活 jQuery之使用slideToggle实现垂直下拉菜单 « 张鑫旭-鑫空间-鑫生活 jQuery-innerfade内部列表自动淡入淡出插件 « 张鑫旭-鑫空间-鑫生活 jQuery-火焰灯效果导航菜单 « 张鑫旭-鑫空间-鑫生活 IE下css bug集合-翻译自haslayout.net « 张鑫旭-鑫空间-鑫生活 翻译-IE7/8@font-face嵌入字体与文字平滑 « 张鑫旭-鑫空间-鑫生活 jQuery-马化腾产品设计与用户体验的一些技术实现 « 张鑫旭-鑫空间-鑫生活 像素的世界及其在web开发制作中的应用 « 张鑫旭-鑫空间-鑫生活 css行高line-height的一些深入理解及应用 « 张鑫旭-鑫空间-鑫生活 CSS实现圆角六色渐变自适应按钮详解 « 张鑫旭-鑫空间-鑫生活 我熟知的三种三栏网页宽度自适应布局方法 « 张鑫旭-鑫空间-鑫生活 jQuery照片图像剪裁插件Jcrop中文翻译详解 « 张鑫旭-鑫空间-鑫生活 Ajax Upload多文件上传插件翻译及中文演示 « 张鑫旭-鑫空间-鑫生活 告别图片—使用字符实现兼容性的圆角尖角效果beta版 « 张鑫旭-鑫空间-鑫生活 大小不固定的图片、多行文字的水平垂直居中 « 张鑫旭-鑫空间-鑫生活 jQuery boxy弹出层对话框插件中文演示及讲解 « 张鑫旭-鑫空间-鑫生活 JavaScript实现新浪微博文字放大显示动画效果 « 张鑫旭-鑫空间-鑫生活 翻译:让网络更快一些——最小化浏览器中的回流(reflow) « 张鑫旭-鑫空间-鑫生活 jQuery之addClasas与removeClass使用实例 « 张鑫旭-鑫空间-鑫生活 关于Google圆角高光高宽自适应按钮及其拓展 « 张鑫旭-鑫空间-鑫生活 JavaScript实现图片幻灯片滚动播放动画效果 « 张鑫旭-鑫空间-鑫生活 jQuery-鼠标经过显示大图并跟随鼠标效果插件 « 张鑫旭-鑫空间-鑫生活 关于gif图片(或png8)杂边锯齿的问题 « 张鑫旭-鑫空间-鑫生活 对html与body的一些研究与理解 « 张鑫旭-鑫空间-鑫生活 鲜为人知的一个解决兼容性问题的利器——小数 « 张鑫旭-鑫空间-鑫生活 搜狐白社会似iphone短信对话框效果的优化 « 张鑫旭-鑫空间-鑫生活 关于文字内容溢出用点点点(…)省略号表示 « 张鑫旭-鑫空间-鑫生活 jquery之append与insertBefore使用实例 « 张鑫旭-鑫空间-鑫生活 jQuery之图片关联伸缩效果 « 张鑫旭-鑫空间-鑫生活 jquery之图片左右切换动画效果 « 张鑫旭-鑫空间-鑫生活 jQuery之replace字符串替换实现不同尺寸图片切换 « 张鑫旭-鑫空间-鑫生活 jQuery-实现图片的放大镜显示效果 « 张鑫旭-鑫空间-鑫生活 jQuery-单击文字或图片内容放大显示效果插件 « 张鑫旭-鑫空间-鑫生活 reflection.js-实现图片投影倒影效果js插件 « 张鑫旭-鑫空间-鑫生活 jQuery-很酷的弹出层效果js插件 « 张鑫旭-鑫空间-鑫生活 复选框单选框与文字对齐问题的研究与解决 « 张鑫旭-鑫空间-鑫生活 css margin的相关属性,问题及应用 « 张鑫旭-鑫空间-鑫生活 IE6下png背景不透明问题的综合拓展 « 张鑫旭-鑫空间-鑫生活
gitee上撸了个类似飞书OKR输入框的@提及项目 « 张鑫旭-鑫空间-鑫生活
张鑫旭,zhangxinxu · 2022-08-31 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10513 鑫空间-鑫生活
本文可以全文转载,无需授权,欢迎分享,欢迎点赞。

飞书

一、效果预览

先看demo:https://zhangxinxu.gitee.io/okr-at-mention/

效果如下视频所示(不动点击播放),输入 @ 字符会出现匹配的人名列表,由于是静态页面,所以请求的数据是死的,实际开发是后端根据搜索关键字动态返回的。

鼠标hover悬停在人名上,会出现 popover 提示浮层,可以查看人物相关的信息。

另外,本 JS 项目对复制或者拖拽进来的富文本进行了过滤处理,保证了了输入框里面内容的纯粹。

以及对回车行为进行了劫持,例如你希望回车不换行,而是做其他事情,也是可以的。

项目地址

项目地址:https://gitee.com/zhangxinxu/okr-at-mention

项目地址截图

欢迎 Star,欢迎 fork,也欢迎关注我的 gitee 账号,会不定期更新一些工作中遇到的小玩意,或者突然萌发的有趣的想法。

二、使用说明

使用很简单,引入对应的CSS和JS,然后按照暴露的方法进行调用就可以了。

例如:

<link rel="stylesheet" href="./src/atMention.css">

假设有容器元素(也就是输入框元素):

<div id="container"></div>

则对应的 JavaScript 代码则可以这么使用:

<script type="module">
    import atWakaka from './src/atWakaka.js';
    atWakaka('container', {
        url: './cgi/data.json'
    });
</script>

就可以实现对应的功能了。需要注意的是,本 JS 依赖 tributejs 这个知名的原生AT提及 JS,所以,使用的时候,需要保证 atWakaka.js 同目录下有 tributejs。

tributejs项目截图

当然,不同项目对交互细节的要求也不一样,因此,也提供了对于的 API 参数接口。

语法和参数

语法为:

atWakaka(container, options, optionsTribute);

之所以叫做”wakaka”,没有什么特别的原因,纯粹是当时我就有这股莫名的冲动。

其中:

container
可输入的编辑框容器元素,可以是 DOM 元素本身,也可以是元素的 id 字符串。
options
可选参数,下面有注释说明。
{
    url: '',
    // 按下回车键后,如果希望阻止默认的回车换行
    // 并做一些事情,这个参数就可以用到
    pressEnter: null,
    // 鼠标经过的提示元素,默认本组件会自己创建
    // 也可以可以自己指定具体的元素
    popOver: 'auto',
    // 鼠标经过和移出 @ 元素的处理
    // event 是事件对象
    // data 是 @元素 对应的请求数据
    // popover 是浮层元素
    onMouseOver: function (event, data, popover) {},
    onMouseOut: function (event, data, popover) {}
}
optionsTribute
可选参数。参见 https://github.com/zurb/tribute 中的参数设置,或者源码中对应参数的使用(如下所示)。
{
    // 下拉容器类名
    containerClass: 'ui-at-drop-x',
    // 前面不需要有空格
    requireLeadingSpace: false,
    // 是否高亮匹配,这里走的是自己匹配
    // 这里其实仅 skip 有效
    searchOpts: {
        pre: '<mark>',
        post: '</mark>',
        // 是否服务端搜索数据
        skip: true
    },
    // 动态获取匹配的值
    values: valuesTribute,
    // 没数据时候返回的HTML内容
    noMatchTemplate: function () {},
    // 选中返回到输入框的HTML内容
    selectTemplate: function(item) {},
    // 下拉菜单每一项的HTML内容
    menuItemTemplate: function (item) {}
};

大家如果希望改变下拉列表的元素结构,就是使用 optionsTribute 中的可选参数进行设置。

三、实现技巧

这里有三个实现技巧我觉得值得和大家分享下。

1. @描述整删整加

在可编辑的 div 元素中,要想让里面某段文字不能编辑,有个简单的方法,就是设置 contenteditable="false",例如,下面 HTML 代码中的 <span> 元素就无法编辑,里面的文字五毒不侵。

<div contenteditable="true">
   我是文字,可逐个删除,<span style="display:inline-block;" contenteditable="false">我只能整体删除</span>!
</div>

然后,上面的实现看似完美,实际上有个很头疼的问题,设置了 contenteditable="false" 的元素后面是不能光标定位的,这就导致我想定位在 @xxx 的后面,然后删除,做不到,要么 JS 实时观察并改变光标位置,要么在后面插入一个零宽空格。

上面无论哪个方法,成本都比较高。

在本 JS 的实现中,创新的采用了单标签元素 <hr> 来模拟 @xxx 效果,由于单标签元素本身内容 textContent 是空的,因此,无需设置contenteditable="false",就能实现删除只能删整体。

在所有浏览器中,<hr>元素都支持 ::before/::after 伪元素,因此,可以创建丰富的内容和图形生成,有兴趣的同学可以看看我之前的这篇文章:“666,看hr标签实现分隔线如何玩出花”。

2. hover出现浮层交互

Hover出现浮层的交互并不难实现,可如果是在可编辑的 div 内部呢?以及,要是是在 Vue 或者 React 等框架中的。

如果还是按照传统的实现,找到对应的 trigger 元素,然后使用组件包一下,那可能就会出现很多的问题,比方说包不了,又比方说事件绑定不上。

面对这样的场景,解决方法都是类似的,那就是委托。

将mouseover/mouseout的行为绑定在容器上,然后进行定位处理。

因为容器元素是固定的,而里面的元素是多变的,绑定在容器上就能以不变应万变,性能也更好。

具体实现参见 JS 源码

3. 复制粘贴或者拖拽进去的都是纯文本

富文本编辑机纯手打应该是打不了富文本的,但是粘贴和拖拽却能将富文本弄进去。

有没有什么办法过滤富文本,让用户粘贴或拖拽的内容默认就是纯文本呢?

有的哈!

浏览器其实提供了原生的能力。

包括获取剪切板里面的文本和富文本内容,获取拖拽内容中的文本和富文本,此时,我们就可以阻止默认行为,将纯文本内容插入就可以了。

来一招神不知鬼不觉的移花接木。

相关代码如下所示(拖拽和粘贴二合一了,因为 API 类似):

const doStripHtml = function (event) {
    var dataInput = event.clipboardData || event.dataTransfer;
    // 富文本
    let htmlOrigin = dataInput.getData('text/html');
    // 纯文本
    let textOrigin = dataInput.getData('text');

    // 如果包含富文本
    if (htmlOrigin) {
        // 手动插入
        // 阻止默认的行为
        event.preventDefault();

        // 只插入纯文本
        let lastRange = window.getSelection().getRangeAt(0);
        const newNode = document.createTextNode(textOrigin);
        lastRange.deleteContents();
        lastRange.insertNode(newNode);
        lastRange.setStartAfter(newNode);
        event.target.focus();
    }
};

其中,插入内容这段代码对于任意的富文本编辑器都是受用的,关于光标和选区更多知识可以参见这篇公众号文章:Web 中的“选区”和“光标”

四、结语

使用<hr> 来模拟 @xxx 效果也并非完美无瑕,也是有所牺牲的,首先就是 @xxx 这样的文字内容是无法框选复制的,因为伪元素生成的文本是无法选择的。

其次,就是数据提交的时候,直接 div.textContent 是不行的,因为会丢失 @xxx 这样的信息,需要在额外处理下。

不过相比弊,带来的利想让是更大的。

好,就说这么多的,希望对遇到类似需求的小伙伴有所帮助。

……

明天9月1号小朋友开学了,本应开心才对,可惜每天要各种码,各种上报,还要天天核酸,口罩长带,想想就脑壳疼。

(本篇完)