对于浏览器(Firefox)插件,我需要在某些页面上找到ISBN(例如:amazon.com,book.com)。
我需要找到那些包含ISBN的DOM元素并使用链接操作它们,该链接将ISBN发送到REST Web服务以获得进一步的逻辑。
由于我是JavaScript的新手,我不知道如何进入这一点,因为主页在显示ISBN方面有所不同。
这是当前的实施:
var self = require("sdk/self");
// a dummy function, to show how tests work.
// to see how to test this function, look at test/test-index.js
function dummy(text, callback) {
callback(text);
}
exports.dummy = dummy;
var tag = "body"
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;
var button = buttons.ActionButton({
id: "mozilla-link",
label: "Visit Mozilla",
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onClick: handleClick
});
function handleClick(state) {
//tabs.open("http://www.mozilla.org/");
tabs.open("http://www.amazon.com");
}
pageMod.PageMod({
include: "*",
contentScriptFile: data.url("modify-content.js"),
onAttach: function(worker) {
worker.port.emit("getElements", tag);
worker.port.on("gotElement", function(elementContent) {
console.log(elementContent);
});
}
});
这是modify-content.js
self.port.on("getElements", function(tag) {
var elements = document.getElementsByTagName(tag);
for (var i = 0; i < elements.length; i++) {
var isbn = elements[i].innerText.match("(ISBN[-]*(1[03])*[ ]*(: ){0,1})*(([0-9Xx][- ]*){13}|([0-9Xx][- ]*){10})");
if(isbn != undefined){
//self.port.emit("gotElement", elements[i].innerHTML);
console.log(isbn);
}
self.port.emit("gotElement", elements[i].innerHTML);
}
});
找到了ISBN。但是如何操纵ISBN周围的DOM元素?
答案 0 :(得分:0)
如果我正确理解了您的问题,则无法将innerText
正则表达式匹配(即字符串)转换回该匹配的最近 html元素。
困难的部分是DOM是一棵树。因此,如果<div>
的{{1}}的{{1}}具有ISBN编号,则所有这些元素“<p>
都将包含该ISBN编号。我们希望达到包含匹配的“最深”元素,忽略其所有父母。
一种(相当昂贵,蛮力)这样做的方法是逐层循环遍历你的元素。
<span>
中有匹配项,我们会查看每个子元素。除了表现之外,我认为仍然存在不匹配的边缘情况。例如,如果innerText
包含三个逗号分隔的ISBN号。您可能需要添加最后一个图层:在每个单独的字符串周围创建 new 元素的图层。
innerText
<span>
var isbnRegExp = new RegExp("(ISBN[-]*(1[03])*[ ]*(: ){0,1})*(([0-9Xx][- ]*){13}|([0-9Xx][- ]*){10})");
var start = document.body;
var findDeepestMatch = function(el, regexp, result) {
result = result || [];
if (regexp.test(el.innerHTML)) {
var childMatches = Array.from(el.children)
.filter(child => regexp.test(child.innerHTML));
// Case 1: there's a match here, but not in any of the children: return el
if (childMatches.length === 0) {
result.push(el);
} else {
childMatches.forEach(child => findDeepestMatch(child, regexp, result));
}
}
return result;
};
console.time("Find results")
var results = findDeepestMatch(start, isbnRegExp);
console.timeEnd("Find results")
var makeISBN = el => {
el.classList.add("isbn");
el.addEventListener("click", () => console.log(el.innerText));
};
results.forEach(makeISBN);