javascript - 如何在实时网页中用 mailto 链接替换电子邮件地址?

标签 javascript google-chrome-extension firefox-addon

想象一下:您看到一个网页,上面写着“只需向 user@example.com 发送消息”,但要真正发送电子邮件,您需要突出显示地址,然后将其剪切并粘贴到收件人字段中您选择的电子邮件客户端的新撰写窗口。

显然,如果它只是一个 mailto: 链接,生活会更轻松,因此您可以单击它并自动创建一条新消息。如何构建将电子邮件地址转换为可点击的 mailto: 链接的扩展程序?

我本来想问是否有一个扩展来为未链接的 Twitter @username 提及启用类似的功能,但我认为这个电子邮件地址问题会是一个更简单的情况。

最佳答案

使用 innerHTML替换电子邮件 - ,这会破坏页面,尤其是因为事件监听器被删除并且属性也被替换。

递归遍历所有节点:

  • 以相反的顺序循环,以防止在修改 DOM 时发生冲突。
  • 对于每一项,检查它的 nodeType 值(value)。
    • 如果.nodeType === 1 (元素),再次调用函数(递归)。
    • 如果.nodeType === 3 (文本节点):
      1. 使用正则表达式和 exec 查找一个电子邮件地址的方法。使用结果的 .index属性以了解电子邮件地址的起始位置,以及 result[0].length知道地址的长度。
      2. 使用节点的 splitText 方法将文本节点分成三部分。
      3. 创建 <a>元素。
      4. 将电子邮件的文本节点(前一个文本节点的第二个)附加到此 anchor 。它会自动从文档中删除。
      5. 在第三个节点之前插入此链接。

演示

不是 chrome 扩展,但它显示了 chrome 扩展的行为方式:http://jsfiddle.net/ckw89/

Chrome 扩展

(正则表达式基于 MongoEngine's EmailField pattern ):

script.js

 // Initiate recursion
 wrapLink(document.body);

 function wrapLink(elem) { // elem must be an element node
     var nodes = elem.childNodes
       , i = nodes.length
       , regexp = /([-!\x23$%&'*+\/=?^_`{}|~0-9A-Z]+(\.[-!\x23$%&'*+\/=?^_`{}|~0-9A-Z]+)*|^"([\x01-\x08\x0b\x0c\x0e-\x1f!\x23-\\[\\]-\x7f]|\\[\x01-011\x0b\x0c\x0e-\x7f])*")@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}/i
       , node, emailNode, a, result;
     while (node = nodes[--i]) {
         if (node.nodeType === 1) {
             // Skip anchor tags, nested anchors make no sense
             if (node.nodeName.toUpperCase() !== 'A')
                wrapLink(node);
         } else if (node.nodeType === 3) {
             // 1: Please note that the regexp has NO global flag,
             //    and that `node.textContent` shrinks when an address is found
             while (result = regexp.exec(node.textContent)) {
                 // 2: Contact <SPLIT> me@example.com for details
                 node = node.splitText(result.index);

                 // 2: Contact <SPLIT>me@example.com<SPLIT> for details
                 node = node.splitText(result[0].length);

                 // me@example.com
                 emailNode = node.previousSibling

                 // 3. Create link
                 a = document.createElement('a');
                 a.href = 'mailto:' + result[0];

                 // 4: Append emailNode
                 a.appendChild(emailNode);

                 // 5: Insert before
                 elem.insertBefore(a, node);
             }
         }
     }
 }

当用作 Content script 时,此脚本将立即运行,因为它与页面的唯一交互是 DOM。为了完整起见,这里是 manifest.json 的内容文件:

{
    "name": "Turns email addresses in `mailto:`s",
    "version": "1",
    "version_version": 2,
    "content_scripts": [{
        "matches": ["*://*/*"],
        "js": ["script.js"]
    }]
}

性能通知

当前脚本替换事件文档中的所有节点。考虑将根节点(例如 <body> )移动到 document fragment在操作之前。

关于javascript - 如何在实时网页中用 mailto 链接替换电子邮件地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12209628/

相关文章:

javascript - 如何在 PhpStorm 的 js 源代码中禁用 html 检查器?

javascript - 跨域 OAuth...如何获得响应?

html - 如何获取最新版本的 Firefox 插件的链接?

javascript - 什么是 Javascript 中 window.open() 的返回类型

javascript - 如何在 native react 中切换抽屉导航器?

javascript - Angular - 将变量传递到指令范围

javascript - 如何根据链接包含的字母/单词查找并单击链接

javascript - 使用 chrome 扩展程序将自定义按钮添加到 gmail 收件箱

Firefox Addon 开发 - 使用低级或非 SDK 接口(interface)

javascript - 如何在 Firefox 控制台中访问附加内容脚本?