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

How to replace email addresses with mailto links in a live web page?

本文关键字:mailto 链接 替换 电子邮件地址 实时 网页      更新时间:2023-09-26

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

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

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

使用innerHTML替换电子邮件-,这会打断页面,尤其是因为事件侦听器已删除,属性也已替换。

递归循环通过所有节点:

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

Demo

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

Chrome扩展

(regexp基于MongoEngine的EmailField模式):

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脚本时将立即工作,因为它与页面的唯一交互是DOM。为了完整起见,以下是manifest.json文件的内容:

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

履约通知

当前脚本将替换活动文档中的所有节点。在操作之前,请考虑将根节点(例如<body>)移动到文档片段。