Reputation: 95
Using either document.getElementsByName('spanName')
or jQuery('[name="spanName"]')
fails (returning []) when
called from within a Chrome extension (or console). However, document.getElementById('spanId')
works, as does a CCS selector on a class name.
The span is already part of the DOM, prior to any intervention by the extension. However, the name attribute was added by the extension, the style attribute was modified, and a class name was added:
Original:
<div id="parentDiv">
<span style="background-color:Yellow">Some highlighted text</span>
</div>
Updated:
<div id="parentDiv">
<span id"spanId" name="spanName" class="highlighted" style="">Some highlighted text</span>
</div>
In addition, at one point the entire parentDiv
's innerHTML is replaced and the spans are transferred
let spanNodeList = ...
let newInnerHTML = ...
let patterns = ...
for (let i = 0; i < spanNodeList.length; i++) {
newInnerHTML.replace(patterns[i], spanNodeList[i].outerHTML)
}
document.getElementById('parentDiv').innerHTML = newInnerHTML
I am performing this transfer before adding the name attribute. Could this innerHTML replacement be the source of my woes?
By the Way...
I'm updating the spans with:
let spans = document.getElementsByTagName('span')
spans[Symbol.Iterator] = [][Symbol.Iterator]
for (let span of spans) {
if (!/yellow/i.test(span.style.CSSText) continue;
span.style.CSSText = ''
span.id = <uniqueSpanId>
span.name = 'spanName'
span.className = "highlighted'
}
Upvotes: 1
Views: 1220
Reputation: 669
My testing agrees that:
document.getElementsByName(name) does not work from chrome extensions,
but
document.getElementById(id) works, and
document.getElementsByTagName(name) works too.
If you really need to use getElementsByName, a possible solution may be to inject a script into the page, like this:
function getEls() {
// This should work when it runs in the original page
let results = document.getElementsByName('spanname');
// but we have to shuttle the results back to the content script
document.body.setAttribute('data-myresults', my_encode(results));
}
// Runs "func" in the page we are attached to
function injectScript(func) {
const codeString = '(' + func + ')();';
const script = document.createElement('script');
script.textContent = codeString;
(document.head || document.documentElement).appendChild(script);
}
injectScript(getEls);
// then, after it has had enough time to asynchronously do the job...
let results = my_decode(document.body.getAttribute('data-myresults'));
(Also, you will have to write my_encode to convert your data to a string, and my_decode to do the opposite.)
Upvotes: 0
Reputation: 804
Per the spec, document.getElementsByName()
returns an array of elements. You will either have to loop through the result or do document.getElementsByName('spanName')[0]
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByName
Upvotes: 1