Whenever I use querySelectorAll
in Microsoft Edge with the :scope
pseudo-selector, this error appears in the console
SCRIPT5022: SCRIPT5022: SyntaxError
I was wondering if there was an alternative to querySelectorAll
, where I use this parameter: :scope > * > table
. I do not want to use jQuery for this. Thanks.
I also wanted to add that querySelector
works by itself
Okay, here is the code sample:
function pJSON(panel) {
var json = {tables: [], images: [], text: ""};
var tables = Array.from(panel.querySelectorAll(":scope > * > table"));
var images = Array.from(panel.querySelectorAll(":scope > * > img"));
var text = panel.querySelector(":scope > textarea");
tables.forEach(table => {
json["tables"].push(tJSON(table));
});
images.forEach(image => {
json["images"].push(image.outerHTML);
});
if (text) {
json["text"] = text.value;
}
return json;
}
I will note again that it works in all browsers except IE and Microsoft Edge
Oh, and an example of some HTML that might be dynamically added, this is the code that was there when I called this method:
<div>
<input type="file" multiple=""><br>
<button>Add Table</button><br>
<div>
<table style="display: inline-table;">
<tbody>
<tr>
<td>
<input type="file" multiple=""><br>
<button>Add Table</button><br>
<textarea placeholder="Write some text"></textarea>
</td>
<td>
<input type="file" multiple=""><br>
<button>Add Table</button><br>
<textarea placeholder="Write some text"></textarea>
</td>
<td>
<button style="margin-left: 100px;">x</button>
</td>
</tr>
<tr>
<td>
<input type="file" multiple=""><br>
<button>Add Table</button><br>
<textarea placeholder="Write some text"></textarea>
</td>
<td>
<input type="file" multiple=""><br>
<button>Add Table</button><br>
<textarea placeholder="Write some text"></textarea>
</td>
<td>
<button style="margin-left: 100px;">x</button>
</td>
</tr>
</tbody>
</table>
<button style="margin-left: 100px;">x</button>
</div>
</div>
So what you are after is actually a polyfill for :scope
.
There is one available at https://github.com/jonathantneal/element-qsa-scope
How it works is basically to first define a unique enough selector on the element to be matched and prepend it to the selector passed to querySelector.
const li = document.getElementById('target');
console.log('no :scope', li.querySelector('li>a')) // Link
// workaround
const UUID = Date.now()+'';
li.setAttribute('data-scope-uuid', UUID);
console.log('workedaround', li.querySelector('[data-scope-uuid="'+UUID+'"] li>a'));
li.removeAttribute('data-scope-UUID');
// where supported
console.log(':scope', li.querySelector(':scope li>a'));
<ul>
<li id="target"><a>Link</a>
<ul>
<li><a>Sublink</a></li>
</ul>
</li>
</ul>
And to test for native support, you can simply wrap a document.querySelector(':scope') === document.documentElement
in a try catch block.