为掘金编写了一款简易版一键三连的油猴脚本(二)

简介: 为掘金编写了一款简易版一键三连的油猴脚本(二)

为掘金编写了一款简易版一键三连的油猴脚本(一)+https://developer.aliyun.com/article/1394364

3.2、尝试让div获取焦点

在这一步的时候,率先尝试的是下面的这个方法,因为这位作者尝试用Vue去实现掘金发送沸点的那个选择表情的功能,这篇文章也让我避免了一些坑~

Vue实现可编辑div获取焦点🎉 感谢作者~

这篇文章用了

image.png

以上三种方式来尝试实现,第一个 tabindex=0,好像是不行的,我就直接跳过了。

我又接着去找寻第二种方式:

发现下面这篇文章:

在可编辑div中定位光标和设置光标,还给了代码和实例

image.png

作者的源代码,大家可以点链接过去看一下,我就不增加篇幅了。

参考完上面作者的代码,我改成了下面这样:

// 定义最后光标对象
 var lastEditRange;
 // 编辑框点击事件
 document.getElementsByClassName("rich-input")[0].onclick = function () {
     // 获取选定对象
     var selection = getSelection();
     // 设置最后光标对象
     lastEditRange = selection.getRangeAt(0);
 };
 // 编辑框按键弹起事件
 document.getElementsByClassName("rich-input")[0].onkeyup = function () {
     // 获取选定对象
     var selection = getSelection();
     // 设置最后光标对象
     lastEditRange = selection.getRangeAt(0);
 };
 // 发送表情
 function editContent() {
     // 获取可编辑框
     var editor = document.getElementsByClassName("rich-input")[0];
     // 获取输入框
     var comment = [
         "针不戳呀,写的针不戳!",
         "学习了!b( ̄▽ ̄)d",
         "本文不错( ̄ˇ ̄),值得学习!(= ̄ω ̄=)",
         "感谢博主的分享!(^ ^)/▽▽\(^ ^)",
         "感谢博主,你的文章让我得到一些收获!( ̄ˇ ̄)",
     ];
     var STARTNUMBER = -1;
     var ENDNUMBER = 5;
     var temp_count =
         Math.floor(Math.random() * (STARTNUMBER - ENDNUMBER + 1)) + ENDNUMBER; //取STARTNUMBER-ENDNUMBER之间的随机数 [STARTNUMBER,ENDNUMBER]
     var editComment = comment[temp_count];
     // 编辑框获得焦点
     editor.focus();
     // 获取选定对象
     var selection = getSelection();
     // 如果保存的有上次的光标对象
     if (lastEditRange) {
         // 清除所有选区
         selection.removeAllRanges();
         // 添加最后光标还原之前的状态
         selection.addRange(lastEditRange);
     }
     // 如果选定对象范围是编辑框范围
     // 创建表情文本节点进行插入
     var emojiText = document.createTextNode(editComment);
     // 如果文本框的子元素大于0,则表示有其他元素,则按照位置插入表情节点
     if (editor.childNodes.length > 0) {
         for (var i = 0; i < editor.childNodes.length; i++) {
             if (i == selection.anchorOffset) {
                 editor.insertBefore(emojiText, editor.childNodes[i]);
             }
         }
     } else {
         // 否则直接插入一个表情元素
         editor.appendChild(emojiText);
     }
     // 创建新的光标对象
     var range = document.createRange();
     // 将光标对象的范围界定为新建的表情节点
     range.selectNodeContents(emojiText);
     // 定位光标位置在表情节点的最大长度位置
     range.setStart(emojiText, emojiText.length);
     // 将选区折叠为一个光标
     range.collapse(true);
     // 清除所有光标对象A
     selection.removeAllRanges();
     // 添加新的光标对象
     selection.addRange(range);
     // 记录最后光标对象
     lastEditRange = selection.getRangeAt(0);
 }
 editContent();

执行效果如下:

image.png

(图片说明:focus 方法确实成功,点亮文本框了,但是内容的改变,仍然无法被监听)

包括光标的位置此时也改变了,但它仍然只算我修改了视图内容,因为评论的按钮仍然是暗的。

这个时候,我突然想到,我手动给它赋值不行,我可以操纵复制粘贴方法啊。

然后这个时候又开始踩坑了!!!

3.3、尝试使用copy、paste 方法

我只是隐约知道浏览器可以操作 copy、paste 方法,并没有尝试过。

又继续开始疯狂的搜索~

这次尝试之前,我先了试,确定在获取到div内容框的焦点后,cv是可以的之后,我就想在粘贴板上做点文章

我的思路是,先把评论内容制造好,然后用Js复制到粘贴版上,之后再调用 paste 方法将内容粘贴到 div 的那个内容框中去。

想法还是挺美好的。

参考着下面的内容进行着尝试

尝试了下面的内容

  1. Document.execCommand()方法
  2. 异步的 Clipboard API
  3. copy事件和paste事件

3.3.1、Document.execCommand()

最先尝试的 Document.execCommand() 事件,Chrome、Firefox 不支持

document.execCommand('paste')

image.png

导致这一步直接GG 了~

3.3.2、Clipboard API

然后 Clipboard API 是偏向于操作剪贴板,就是可以写入,读出,但是并不是触发 paste方法,

我也找了一个小案例:

<body>
     <p>hello world</p>
     <button id="btn-copy">copy text</button>
     <button id="btn-paste">copy text</button>
     <script>
       const copyBtn = document.querySelector('#btn-copy');
       copyBtn.addEventListener(
         'click',
         async function () {
           try {
             // 将 p 标签内的文本编辑后写入剪切板
             await navigator.clipboard.writeText(
               `${document.querySelector('p').textContent}!`
             );
           } catch (e) {
             console.error('Failed to copy: ', e);
           }
         },
         false
       );
       const pasteBtn = document.querySelector('#btn-paste');
       pasteBtn.addEventListener(
         'click',
         async function () {
           try {
             // 读取剪切板中的文本
             const text = await navigator.clipboard.readText();
             console.log(text);
           } catch (e) {
             console.error('Failed to read clipboard content: ', e);
           }
         },
         false
       );
     </script>
   </body>

这个坑也让我躺了,又去尝试下一个方法:

另外还参考了 MDN 文档:Element: paste event

3.3.3、clipboard.js

我也尝试了这个方法,但是我发现,它只能监听用户的 paste 事件,当时粘贴事件发生时,才能处理事件~

<!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Document</title>
     <script
       type="text/javascript"
       src="https://cdn.bootcss.com/clipboard.js/2.0.1/clipboard.js"
     ></script>
   </head>
   <body>
     <!-- Target -->
     <input id="input" value="你好,我是宁在春" />
     <!-- Trigger -->
     <button class="copy">Copy to clipboard</button>
     <button id="paste">paste</button>
     <textarea id="output"> </textarea>
     <script>
       var clipboard = new ClipboardJS(".copy", {
         text: function (trigger) {
           return doCopy();
         },
       });
       var pastBtn = document.getElementById("output");
       pastBtn.addEventListener("paste", function (event) {
         console.log(pastBtn);
         if (event.clipboardData || event.originalEvent) {
           var clipboardData = event.clipboardData || window.clipboardData;
           var val = clipboardData.getData("text");
           if (val) {
             doPast(val);
           } else {
             throw new Error("剪切板内容为空或者非文本类型");
           }
           event.preventDefault();
         }
       });
       //获取要复制到剪切板的内容
       function doCopy() {
         return document.getElementById("input").value;
       }
       //处理剪切板内容
       function doPast(value) {
         alert(value);
       }
     </script>
   </body>
 </html>

补充:在这一步的时候,我原本还想继续去尝试用JavaScript 模拟键盘按键去尝试触发复制粘贴事件的,但是没有去尝试啦。

主要在网上搜到的知识,不敢说千篇一律,但是点开大都数文章略微有点让人失望~,还有一点就是转载来转载去(个人吐槽,轻喷),一篇文章能看见好几次,哈哈


后来想起第一篇看到的文章,聊到的掘金的表情,然后就有了下面的灵光一现~

3.4、灵光一现

这个时候,我想着,手动改你内容不行,直接点击表情,然后放到div中,这样总可以吧


因为只要打开emjoe 面板,点一下表情,就会自动的添加到那个内容框中去,这一次尝试竟然是ok的~

// 获取评论区焦点
       function getFocus() {
         document.getElementsByClassName("rich-input")[0].focus();
       }
       //打开emoje 表情选择框
       function getEmojeClick() {
         document.getElementsByClassName("emoji-box")[0].click();
       }
       //选择emoje表情
       function getChoseEmoje() {
         var emojipicker = document.getElementsByClassName("emojipicker")[0];
         var emojeImage = emojipicker.getElementsByClassName("list")[1];
         var item = emojeImage.getElementsByClassName("item")[0];
         var spanImage = item.getElementsByClassName("byte-tooltip__wrapper")[0];
         var img = spanImage.querySelector("img");
         img.click();
       }
       getFocus();
       getEmojeClick();
       getChoseEmoje();

大家可以直接把这一步放到掘金的文章页面,F12后,将代码复制运行,是可行的~

在这一步可行之后,我又想在这个基础上增强,既然选择掘金的表情是可以的,那我先加一个表情,然后再加上我自己的评论内容,不就行了吗~,说做就做

代码不贴了,直接说结果,失败了~,还是和之前一模一样,发起请求的时候,根本没有携带这个数据内容

后记

最后实现效果大家也看到了,因为暂时没有找到更好的一个方法去实现,我最后用表情妥协了,表情选用了几个比较正向的表情,然后在评论的时候进行随机选择

代码比较偏向于基础,使用到的全部都是 JavaScript 中的基础知识,写出来也是我的一个尝试,大家喜欢与否,我并不能知晓。

关于这篇文章,如果是对于从来没有接触过油猴脚本的小伙伴来说,拿来看一看这么简单,也算是一个接触。

除了这一点外,我也不敢说此文,对读者而言,能有多少收获了。

如果感兴趣可以多做尝试,在这其中,多少会有一些收获。

对了,不要被陌生的事物吓住了,只要迈出第一步,那么就是成功的😀

我明白我对于前端领域,就是一位小白,文中不可避免可能会出现错误或遗漏,请大家一定要进行指出!

当然如果让你有所收获的话,也希望可以留下你的赞~,哈哈

大伙可以直接将代码放进油猴,来试一试这个脚本的效果,可以在这篇文章中,让我看到你们的实操吗~

也可以把第一个中 function 中的所有代码直接放到网页中执行,也是可以的~


目录
相关文章
|
1月前
|
存储 前端开发 Java
Java后端如何进行文件上传和下载 —— 本地版(文末配绝对能用的源码,超详细,超好用,一看就懂,博主在线解答) 文件如何预览和下载?(超简单教程)
本文详细介绍了在Java后端进行文件上传和下载的实现方法,包括文件上传保存到本地的完整流程、文件下载的代码实现,以及如何处理文件预览、下载大小限制和运行失败的问题,并提供了完整的代码示例。
480 1
|
6月前
|
前端开发 JavaScript 开发者
为掘金编写了一款简易版一键三连的油猴脚本(一)
为掘金编写了一款简易版一键三连的油猴脚本
173 0
|
6月前
|
Linux Python
用Python实现一个CSDN自动三连工具
用Python实现一个CSDN自动三连工具
|
数据可视化 项目管理 C++
|
6月前
|
移动开发 前端开发 IDE
前端知识笔记(三十四)———HBuilder的下载与使用(详细步骤)
前端知识笔记(三十四)———HBuilder的下载与使用(详细步骤)
215 0
|
6月前
|
JavaScript 前端开发 索引
某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】
某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】
59 0
《C++避坑神器·二十》C++智能指针简单使用
《C++避坑神器·二十》C++智能指针简单使用
46 0
|
JavaScript 前端开发 C++
前端基础知识备忘(1)
巩固下备忘下前端的基础知识
1513 51
|
前端开发 JavaScript Java
前端基础知识备忘(2)
巩固下备忘下前端的基础知识
1345 61
|
存储 测试技术 开发工具
【遇坑记实 二】小坑合集
【遇坑记实 二】小坑合集
76 0