Yesterday while I was optimizing a development project to Internet Explorer, I realized that :scope
is a deprecated keyword from all browsers and that it has never been supported by IE.
What is :scope
:scope
lets your run a query selector, that takes the current element into the parameter string. For example
node.querySelector(':scope > div')
This would only find div
that are direct children to node
as I used scope.
Considerations
But since this isn't going to be working in IE I had to come up with another solution. Some solutions suggested prototype hacking to node.find()
to make it look similar to jQuery. While I agree sometimes prototyping is okay, however in my opinion that is the case when it's adding new features for old browsers, such as polyfill.io.
The solution
My solution was to create a function, that generates a random ID for the node, if it doesn't have one, and remove it again. Thereby I can still select on it. I created 2 functions one for querySelector
and one for querySelectorAll
.
To use the function simply call find(document.querySelector('body'), 'div')
to find all div
that are direct children of body
.
/**
* Find direct children to node, replicating .querySelector(':scope > [...]')
*/
function find(node, selector) {
removeId = false
if (node.getAttribute('id') === null) {
node.setAttribute('id', 'ID_' + new Date().getTime())
removeId = true
}
let result = document.querySelector('#' + node.getAttribute('id') + ' > ' + selector)
if (removeId)
node.removeAttribute('id')
return result
}
/**
* Find direct children to node, replicating .querySelectorAll(':scope > [...]')
*/
function findAll(node, selector) {
removeId = false
if (node.getAttribute('id') === null) {
node.setAttribute('id', 'ID_' + new Date().getTime())
removeId = true
}
let result = document.querySelectorAll('#' + node.getAttribute('id') + ' > ' + selector)
if (removeId)
node.removeAttribute('id')
return result
}