瑞昌市环保局网站建设,wordpress文章字体大小,郑州seo排名公司,网站的话术目录
1、配置 manifest.json 文件
2、编写侧边栏结构
3、查找关键词并高亮的方法
3-1#xff09; 如果直接使用 innerHTML 进行替换
4、清除关键词高亮
5、页面脚本代码
6、参考 1、配置 manifest.json 文件
{manifest_version: 2,name: 如果直接使用 innerHTML 进行替换
4、清除关键词高亮
5、页面脚本代码
6、参考 1、配置 manifest.json 文件
{manifest_version: 2,name: key_word_plugin,version: 1.0,description: find_key_word,// 添加权限permissions:[*://*/*,activeTab],icons: {48: icons/flower.jpg},content_scripts: [{matches: [*://*/*],js: [index.js],run_at:document_idle}],// 侧边栏sidebar_action: {default_title: My tool,default_panel: ./sidebar/sidebar.html,default_icon: ./sidebar/sidebar_icon.png},// 背景脚本background: {scripts: [bg.js],persistent: false,type: module}
} 2、编写侧边栏结构
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0style/* 略 *//stylelink relstylesheet href./top_area.css
/head
bodydiv classcontainer!-- 关键词查找 --div classtop-areasection classinp-areainput classinp typetext maxlength10button classfind-btn查找/button/sectionsection classresult-areap共找到/pp classcount!-- 将查找到的结果条目数量写入此处 --/pp处;/p/sectionsection classbtn-areainput typenumber step1 min1 classgoto-keyword-inp usablebutton classusable goto-btn跳转/button/sectionsection classbtn-areabutton classusable last-btn上一个/buttonbutton classusable next-btn下一个/buttonbutton classclear清除所有标记/button/section/div/div
/body
script srckeyword.js/script
/html 效果图 3、查找关键词并高亮的方法 // 获取当前激活的标签页面 使用 tabs 需要权限 activeTab在 manifest 中配置browser.tabs.query({active: true, currentWindow: true}).then((logTabs,onError){// 然后往当前页面中注入内容脚本document将是当前页面的 documentbrowser.tabs.executeScript({code:
(function action(keyword, nodes){Array.from(nodes).forEach(node {let {nodeType, data : content} node;if(nodeType 3 content.includes(keyword)){let parentNode node.parentNode;let split_arr node.data.trim().replaceAll(keyword,- keyword -).split(-).filter(e e);for(let item of split_arr){if(item keyword){let strong document.createElement(strong)strong.innerText keyword;strong.classList.add(${KEYWORD_CLASS_NAME})strong.style ${__style}parentNode.insertBefore(strong, node)}else{let text document.createTextNode(item);parentNode.insertBefore(text, node)}}parentNode.removeChild(node)}else if(nodeType 1 node.textContent.includes(keyword)){action(keyword, node.childNodes)}})
})(${keyword}, Array.from(document.body.childNodes).filter((e){return (e.textContent.includes(${keyword}) e.tagName ! SCRIPT)
}))
document.querySelectorAll(.__keyword_word__).length}).then((onExecuted, onError){
// onExecuted[0] 的内容就是document.querySelectorAll(.__keyword_word__).length的结果total onExecuted[0]})}) 点击查找关键词后页面脚本向当前的页面注入一段JavaScript代码。该代码包含一个立即执行的函数 和 一个关键词数量的获取。 该立即执行的函数 action接收一个 要匹配的关键词 keyword 和 当前搜索节点数组 nodes 作为参数。 遍历每一个节点取出节点的类型--nodeType 和节点的文本内容 --content。 如果是纯文本节点则该节点的 nodeType 为3如果是元素节点则为 1。 如果有纯文本节点并且该纯文本节点中的内容包含了关键词那么构造出一个数组使用该数组来区分非关键词内容和关键词内容以及他们之间的位置关系。
let split_arr content.trim().replaceAll(keyword, - keyword -).split(-).filter(e e); 如关键词为 我们 纯文本节点的内容为
我们的征途是星辰大海请和我们一起永远相信美好的事情即将发生 那么构造的数组为
[ 我们, 的征途是星辰大海请和, 我们, 一起永远相信美好的事情即将发生 ] if(nodeType 3 content.includes(keyword)){let parentNode node.parentNode;let split_arr content.trim().replaceAll(keyword,- keyword -).split(- ).filter(e e);for(let item of split_arr){if(item keyword){let strong document.createElement(strong)strong.innerText keyword;strong.classList.add(${KEYWORD_CLASS_NAME})strong.style ${__style}parentNode.insertBefore(strong, node)}else{let text document.createTextNode(item);parentNode.insertBefore(text, node)}}parentNode.removeChild(node)} 遍历构造的数组中的内容如果当前值等于关键词那么构造一个强调标签 Strong 将关键词作为 innerText并添加指定的样式和样式类名然后加入到当前所遍历的节点之前如果该当前值与关键词不相等则直接构造一个文本节点将其添加到当前所遍历的节点之前...... 当遍历完构造的数组后将当前遍历的节点从其父节点中删除。这样就将纯文本节点中的内容全部高亮处理了。 没有包含关键词的纯文本节点直接跳过。 如果该节点不是纯文本结点那么判断其 textContent 中是否包含关键词如果是那么让其所有子节点再参与 action 处理。否则就不用继续递归。 3-1 如果直接使用 innerHTML 进行替换
如果标签中的属性出现了关键词则会出现标签结构混乱的问题 原代码
bodydiv classmy_nameimg srchttps://tse1-mm.cn.bing.net/th/id/OIP-C.duz6S7Fvygrqd6Yj_DcXAQHaF7?rs1pidImgDetMain alt我的图片p我的图片/pdiv你的图片p我们的图片/pspan都是/span图片/div/divscriptdocument.body.innerHTML document.body.innerHTML.replaceAll(图片,strong stylecolor:red图片/strong)/script
/body 4、清除关键词高亮
browser.tabs.query({active: true, currentWindow: true}).then((){browser.tabs.executeScript({code:
(function action(keyword){document.querySelectorAll(.${KEYWORD_CLASS_NAME}).forEach(e {let parent e.parentNode;let textNode document.createTextNode(keyword);parent.replaceChild(textNode, e)})
})(${keyword})})}) 获取到所有 strong 强调标签根据自定义的 class 名称然后进行遍历获取到每一个strong 的父元素。使用 createTextNode 创建一个纯文本节点其内容就是关键词。然后将该文本节点替换掉 strong 标签即可。 5、页面脚本代码
// 简单封装document.querySelector
const getFirstEle sign document.querySelector(sign);// 关键词
var KEYWORD ;// 总共找到多少处
var total 0;
const count_ele getFirstEle(.count)
count_ele.innerText ____const KEYWORD_CLASS_NAME __keyword_word__
const __style color: #b60404; background-color: #f9f906; text-decoration: underline; text-decoration-style: double;
var INDEX null; // 当前记录的关键词索引用于跳转 [1 ~ total]const find_btn getFirstEle(.find-btn);
const clear_btn getFirstEle(.clear);
const last_btn getFirstEle(.last-btn);
const next_btn getFirstEle(.next-btn);
const goto_keyword_inp getFirstEle(.goto-keyword-inp)
const goto_btn getFirstEle(.goto-btn)// 控制关键词跳转是否可用
const usables document.querySelectorAll(.usable);
const set_usable (res){ usables.forEach(e { e.disabled !res; }) }// 默认不可用
set_usable(false);// 点击查找关键词
find_btn.addEventListener(click, (e){// 获取用户的输入let keyword document.querySelector(.inp).value.trim()if(!keyword) return;// 获取上次的关键词let last_keyword sessionStorage.getItem(_keyword_);// 如果上次查找的关键词存在并且与当前的关键词相等if(last_keyword last_keyword keyword){ return; }// 如果上次的关键词与当前的关键词不相等那么页面的高亮没有被清理// 因为上次的关键词session中没有被清除。先清理页面残留else if(last_keyword last_keyword ! keyword){clear_action(last_keyword, false, false, false)}// 更新关键词sessionStorage.setItem(_keyword_, keyword)KEYWORD keyword;// 获取当前激活的标签页面 使用 tabs 需要权限 activeTab在 manifest 中配置browser.tabs.query({active: true, currentWindow: true}).then((logTabs,onError){// 然后往当前页面中注入内容脚本document将是当前页面的 documentbrowser.tabs.executeScript({code:
(function action(keyword, nodes){Array.from(nodes).forEach(node {let {nodeType, textContent : content} node;if(nodeType 3 content.includes(keyword)){let parentNode node.parentNode;let split_arr content.trim().replaceAll(keyword,- keyword -).split(-).filter(e e);for(let item of split_arr){if(item keyword){let strong document.createElement(strong)strong.innerText keyword;strong.classList.add(${KEYWORD_CLASS_NAME})strong.style ${__style}parentNode.insertBefore(strong, node)}else{let text document.createTextNode(item);parentNode.insertBefore(text, node)}}parentNode.removeChild(node)}else if(nodeType 1 content.includes(keyword)){action(keyword, node.childNodes)}})
})(${keyword}, Array.from(document.body.childNodes).filter((e){return (e.textContent.includes(${keyword}) e.tagName ! SCRIPT)
}))
document.querySelectorAll(.__keyword_word__).length}).then((onExecuted, onError){total onExecuted[0]count_ele.innerText total;// 开启跳转功能if(total 0) set_usable(true);})})
})// 点击清除按钮 回归页面原始的状态
clear_btn.addEventListener(click, (){let keyword sessionStorage.getItem(_keyword_);clear_action(keyword)
})// 清除关键词标记
const clear_action (keyword, clear_inptrue, clear_keyword_sessiontrue, clear_counttrue){browser.tabs.query({active: true, currentWindow: true}).then((){browser.tabs.executeScript({code:
(function action(keyword){document.querySelectorAll(.${KEYWORD_CLASS_NAME}).forEach(e {let parent e.parentNode;let textNode document.createTextNode(keyword);parent.replaceChild(textNode, e)})
})(${keyword})})})if(clear_inp) document.querySelector(.inp).value ;if(clear_keyword_session) sessionStorage.setItem(_keyword_, );if(clear_count) count_ele.innerText _____;set_usable(false)KEYWORD goto_keyword_inp.value
}// 跳转到上一个关键词位置
last_btn.addEventListener(click, (){if(!INDEX) INDEX 1;else if(INDEX 1 ) INDEX total;else if(INDEX total) INDEX total - 1;else INDEX --;goto_keyword_site(INDEX - 1, KEYWORD);
})// 跳转到下一个关键词位置
next_btn.addEventListener(click, (){if(!INDEX) INDEX 1;else if(INDEX 1) INDEX 2;else if(INDEX total) INDEX 1;else INDEX ;goto_keyword_site(INDEX - 1, KEYWORD);
})// 跳转到指定的位置
goto_btn.addEventListener(click, (){let index parseInt(goto_keyword_inp.value)if(!index) return;if(index total) index total;else if(index 1) index 1;goto_keyword_site(index - 1)INDEX index;
})// 跳转到具体的关键词位置
const goto_keyword_site (index) {goto_keyword_inp.value index 1;browser.tabs.query({active: true, currentWindow: true}).then((logTabs,onError){// 然后往当前页面中注入内容脚本document将是当前页面的 documentbrowser.tabs.executeScript({code:
document.querySelectorAll(.${KEYWORD_CLASS_NAME})[${index}].scrollIntoView({behavior:smooth
}) })})
} 6、参考
[1]: 扩展是什么 - Mozilla | MDN
[2]: Firefox插件拓展开发_火狐浏览器插件开发-CSDN博客