如何用邮件链接替换电子邮件地址在实时网页中? [英] How to replace email addresses with mailto links in a live web page?
问题描述
显然,如果只是一个mailto:链接,生活会更容易,所以你可以点击它,并有一个新的消息自动创建。我如何构建一个将电子邮件地址转换为可点击的mailto:链接的扩展?
我原本打算询问是否有一个扩展,为未链接的Twitter @用户名提到,但我认为这个电子邮件地址问题会更简单的情况。
循环遍历所有节点:$ b
$ b
- 以相反顺序循环,以防止在修改DOM时会发生冲突。
- 对于每个项目,检查它是
nodeType
的值。
$ b- 如果
.nodeType === 1
(element),再次调用函数(递归)。
- 如果
.nodeType === 3
(文本节点):
- 如果
Demo
不是Chrome扩展程序,扩展将表现如下: http://jsfiddle.net/ckw89/
Chrome扩展程序
(正则表达式基于 EmailField 模式):
script.js
//启动递归
wrapLink document.body的);
函数wrapLink(elem){// elem必须是元素节点
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])?\。)+ [AZ] {2,6} / i
,节点,emailNode,a,结果;
while(node = nodes [ - i]){
if(node.nodeType === 1){
//跳过锚点标签,嵌套锚点没有意义
if(node.nodeName.toUpperCase()!=='A')
wrapLink(node);
} else if(node.nodeType === 3){
// 1:请注意,正则表达式没有全局标志
//并且`node.textContent`会缩小(结果= regexp.exec(node.textContent)){
// 2:联系人< SPLIT> me@example.com获取详细信息
node = node.splitText(result.index);
// 2:联系人< SPLIT> me@example.com< SPLIT>详细信息
node = node.splitText(result [0] .length);
// me@example.com
emailNode = node.previousSibling
// 3.创建链接
a = document.createElement('a' );
a.href ='mailto:'+ result [0];
// 4:追加emailNode
a.appendChild(emailNode);
// 5:在
之前插入elem.insertBefore(a,node);
$脚本在作为内容脚本使用时会立即生效,因为它只与页面交互DOM。为了完整起见,以下是manifest.json
档案:
{
name:在mailto: ,
version:1,
version_version:2,
content_scripts:[{
*],
js:[script.js]
}]
}
性能通知
当前脚本替换实际文档中的所有节点。考虑将根节点(例如
< body>
)移动到 document fragment 。Imagine this: you come across a webpage that says "Just send a message to user@example.com" but to actually send the email, you need to highlight the address and then cut and paste it into the recipient field of a new compose window of your email client of choice.
Obviously life would be easier if it were simply a mailto: link, so you could click on it and have a new message created automatically. How do I build an extension that turns email addresses into clickable mailto: links?
I was originally going to ask if there was an extension to enable similar functionality for unlinked Twitter @username mentions but I thought this email address problem would be a simpler situation.
解决方案Use- No, this breaks page's, especially because event listeners are removed and attributes are also replaced.innerHTML
to replace the emailRecursively loop through all nodes:
- Loop in the reverse order, to prevent conflicts when you modify the DOM.
- For each item, check it's
nodeType
value.- If
.nodeType === 1
(element), call the function again (recursion). - If
.nodeType === 3
(text node):- Use a regular expression and the
exec
method to find one email address. Use the result's.index
property to know the starting position of the email address, andresult[0].length
to know the length of the address. - Use the node's
splitText
method cut the text node in three parts. - Create an
<a>
element. - Append the email's text node (the second text node from the previous) to this anchor. It's automatically removed from the document.
- Insert this link before the third node.
- Use a regular expression and the
- If
Demo
Not a chrome extension, but it shows how a chrome extension would behave: http://jsfiddle.net/ckw89/
Chrome extension
(the regexp is based on 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); } } } }
This script will work immediately when used as a Content script, because its only interaction with the page is the DOM. For completeness, here's the contents of the
manifest.json
file:{ "name": "Turns email addresses in `mailto:`s", "version": "1", "version_version": 2, "content_scripts": [{ "matches": ["*://*/*"], "js": ["script.js"] }] }
Performance notice
The current script replaces all nodes in the live document. Consider moving the root node (eg
<body>
) to a document fragment before manipulating.这篇关于如何用邮件链接替换电子邮件地址在实时网页中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- 如果