How to Query Whole Dom for Elements Matching Some Computed Style ? (In Pure Js)

how to query whole DOM for elements matching some computed style ? (in pure js)

Instead of selecting all (*) elements, and use getComputedStyle + getPropertyValue, you can follow the following steps:

  • Loop through all CSS rules (via document.styleSheets [1]) and take the selectors which contains position: fixed.

  • Select all elements whose style attribute contains position: fixed.

  • Use document.querySelectorAll to select all elements which match the selector.

    • Test whether window.getComputedStyle(elem, null).getPropertyValue('position') equals fixed to filter elements which are not at a fixed position (possibly overridden through a more specific selector, or !important).
    • If it matches, push the element in an array
  • At this point, you have an array containing all position: fixed elements.

[1] The external stylesheets have to be located at the same origin, because of the Same origin policy.

Code (small demo: http://jsfiddle.net/GtXpw/):

//[style*=..] = attribute selector
var possibilities = ['[style*="position:fixed"],[style*="position: fixed"]'],
searchFor = /\bposition:\s*fixed;/,
cssProp = 'position',
cssValue = 'fixed',
styles = document.styleSheets,
i, j, l, rules, rule, elem, res = [];

for (i=0; i<styles.length; i++) {
rules = styles[i].cssRules;
l = rules.length;
for (j=0; j<l; j++) {
rule = rules[j];
if (searchFor.test(rule.cssText)) {
possibilities.push(rule.selectorText);
}
}
}
possibilities = possibilities.join(',');
possibilities = document.querySelectorAll(possibilities);
l = possibilities.length;
for (i=0; i<l; i++) {
elem = possibilities[i];
// Test whether the element is really position:fixed
if (window.getComputedStyle(elem, null).getPropertyValue(cssProp) === cssValue) {
res.push(elem);
}
}
res; //<-- = Array containing all position:fixed elements

Select all elements with a data-xxx attribute without using jQuery

You can use querySelectorAll:

document.querySelectorAll('[data-foo]');

Find all CSS rules that apply to an element

EDIT: This answer is now deprecated and no longer works in Chrome 64+. Leaving for historical context. In fact that bug report links back to this question for alternative solutions to using this.


Seems I managed to answer my own question after another hour of research.

It's as simple as this:

window.getMatchedCSSRules(document.getElementById("description"))

(Works in WebKit/Chrome, possibly others too)

Get only visible element using pure javascript

Here's something you can use, pure Javascript:

// Get all elements on the page (change this to another DOM element if you want)
var all = document.getElementsByTagName("*");

for (var i = 0, max = all.length; i < max; i++) {
if (isHidden(all[i]))
// hidden
else
// visible
}

function isHidden(el) {
var style = window.getComputedStyle(el);
return ((style.display === 'none') || (style.visibility === 'hidden'))
}

How to use JavaScript to fetch all HTML elements containing text,and filter out the specified element and its children?

Your expectations are not quite accurate according to the code you've shown in your question. For example: the top-level text node which includes Don't get code: is a valid node according to your criteria.

You can use the TreeWalker API to achieve the desired results. Part of the solution to your problem is to select the closest parent of the text node which matches one of your criteria in order to validate the node:

Code in TypeScript Playground

<!doctype html>
<html>
<head>
<script type="module">
function filterTextNode (textNode) {
if (!textNode.textContent?.trim()) return NodeFilter.FILTER_REJECT;
const ancestor = textNode.parentElement?.closest('pre,script,style,.this_is_code');
if (ancestor) return NodeFilter.FILTER_REJECT;
return NodeFilter.FILTER_ACCEPT;
}

function getFilteredTexts (textNodeFilterFn) {
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
{acceptNode: textNodeFilterFn},
);
const results = [];
let node = walker.nextNode();
while (node) {
results.push(node.textContent);
node = walker.nextNode();
}
return results;
}

function main () {
const texts = getFilteredTexts(filterTextNode);
console.log(texts);
}

main();
</script>
</head>
<body>
<p> </p>

get text:
<div>This is text, get</div>
<p>This is text, get too</p>

Don't get code:
<pre>
This is code,Don't get
<p>this is code too, don't get</p>
</pre>

<div class="this_is_code">
This is className is code, Don't get
<span>this is code too, don't get</span>
</div>
</body>
</html>


Related Topics



Leave a reply



Submit