Querying complex html document - javascript

I'm trying to query a complex web app for some data...
A very simplified example is the below
<section class="Test newTest testTest active">
<div>
</div>
<a class="classLink1 classlink2 classlink3" data-render="test">Link</a>
</div>
</div>
</section>
<section class="Test newTest testTest">
<div>
</div>
<a class="classLink1 classlink2 classlink3" data-render="test">Link</a>
</div>
</div>
</section>
Problem
There are a few <a> tags with very similasr class names and some dataset with unique values which I don't want to query
I'm trying to only target the <a> tag where the parent <section> has an .active class. But it may not be the immediate parent if that makes sense
I am trying something like this
document.querySelectorAll('section.Test.newTest.testTest.active a.classLink1.classlink2.classlink3 [data-render="test"]')
But it seems to return an empty nodelist.

You must not have the space between classlink3 and [data-render="test"], as the elements you are searching for have both classes and attribute, and aren't nested inside the "classes" element.
The right selector should be
'section.Test.newTest.testTest.active a.classLink1.classlink2.classlink3[data-render="test"]'
Which will select the following
Instead of

Related

How can I get a Node's only direct children with a specific class name?

How can I get a Node's only direct children with a specific class name?
Example
<div class="list-group">
<div class="list-group-item">
<div class="list-group"> <!--I have this-->
<div class="list-group-item"> <!--And I want to reach this-->
<div class="list-group">
<div class="list-group-item"></div> <!--Not this-->
<div class="list-group-item"></div>
</div>
</div>
<div class="list-group-item"></div> <!--And get this-->
</div>
</div>
</div>
I have a list-group that contains items and groups and I want to keep that hierarchy and get a list-group's only direct list-group-items.
How can I do so?
You haven't mentioned if you use any JS frameworks, but with JQuery it is fairly simple... just use children()
In example $("#haveThis").children()
You can also filter children like: $("#haveThis").children("list-group-item")
docs: https://api.jquery.com/children/
For vanilla JS I'd do this:
[].slice.call(document.getElementById("havethis").children).filter(el=>el.className==='list-group-item')
In vanilla JS (if you're not using jQuery) element.children (where element is the parent you wish to query) will return a list of all direct child nodes, you would then itterate over the list list, looking for node.className = "list-group-item";
I've not found a way to do this with standard CSS selectors, so a coded solution seems to be the only option.
Get all elements with the specified class name:
var x = document.getElementsByClassName("list-group-item");
Link https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName

JQuery find text nodes with not selector on nested elements work only with .contents() and filter()

Please help me understand why this is happening.
(UPDATE) TL;DR:
nested elements' text will be included when using find with not(NESTED_ELEMENT) selector but will be excluded when using find with not(NESTEDT_ELEMENT)+contents+filter(TEXT_NODE).
I want to get the text from a page but to exclude some elements.
For the simplicity, I have excluded <p> element only (and descendants) but when I use the text(), I'm also getting the text in the excluded element.
When I filter the results with contents() to include only text nodes, only then the not selector is "working" by not returning the text from the excluded elements. Please see image below with the code used:
Why isn't it working without using contents()?
Thanks.
For your convenience:
The URL that I tested on is this one.
The code that gives me the excluded element's text:
$('body').find(':not(p, p *)').text()
The code that gives me the desired text (excluded element's text not present):
$('body').find(':not(p, p *)').contents().filter(function(){return this.nodeType == 3}).text()
And here's the HTML part from the URL. As you can see, there's a <p> element there and As described, I want to get the text from this HTML but to exclude some elements (p was selected for simplicity, there will be lots more rules in production).
<div class="col-lg-12">
<header id="header" role="banner" class="jumbotron">
<h1>
<img src="/img/icon/apple-touch-icon-114-precomposed.png" class="offscreen" alt="">
<i class="icon-html5" aria-hidden="true"></i><span class="offscreen">HTML 5</span>
<span>Semantics and Accessibility: <span class="subheader">Heading Structure</span></span>
</h1>
<p class="lead" id="lead_content">The more you understand the specification, the more you'll realize there are more right
ways to implement <em>proper</em> semantic HTML markup than wrong. Thinking in terms of web accessibility can provide direction.</p>
</header>
</div>
Try using .clone() , .remove() , .text()
var filtered = $(".col-lg-12").clone();
filtered.find("p").remove();
console.log(filtered.text())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="col-lg-12">
<header id="header" role="banner" class="jumbotron">
<h1>
<img src="/img/icon/apple-touch-icon-114-precomposed.png" class="offscreen" alt="">
<i class="icon-html5" aria-hidden="true"></i><span class="offscreen">HTML 5</span>
<span>Semantics and Accessibility: <span class="subheader">Heading Structure</span></span>
</h1>
<p class="lead" id="lead_content">The more you understand the specification, the more you'll realize there are more right ways to implement <em>proper</em> semantic HTML markup than wrong. Thinking in terms of web accessibility can provide direction.</p>
</header>
</div>

Why is my onclick script not changing my innerhtml?

I have a very simple webpage I took from a template. On the right I have a list of links in a div and when clicking on them I want an html page located on my server to load in the inner div area. When clicking on the link, nothing happens. I've also tried setting the innerHtml to just a text value in case the src part is invalid, but that too does nothing. What am I missing? This looks like all the examples I've gone through.. And note I'm only giving the partial html, so I know the body isn't closed etc.
I have:
<body>
<script>
function results()
{
document.getElementsByClassName('mid-left-container').innerHTML="src="..\VRS_BVT\VRS_Test.html""
}
</script>
<div id="main-wraper">
<div id="top-wraper">
<div id="banner">Automation Server</div>
</div>
<div id="mid-wraper">
<div class="mid-wraper-top">
<div class="mid-leftouter">
<div class="mid-left-container">
blah blah
</div>
</div>
<div class="right-container">
<div class="right-container-top">
<h3><span class="yellow-heading">Projects</span></h3>
<ul>
<li>VRS BVT</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</body>
getElementsByClassName() returns an array (actually a NodeList) of matching elements.
You're creating a new innerHTML property on that array, which has no effect.
Instead, you need to get an actual element from the array and set its innerHTML:
document.getElementsByClassName(...)[0].innerHTML = ...
Also, your string literal is invalid syntax.
You need to use single-quotes or escape the double-quotes.
Also, putting src="..\VRS_BVT\VRS_Test.html" in the content of an HTML element will not load anything from the server.
You need to use AJAX or an <iframe>.

How can i assign ID to array of DIVs like "#page_pricing .col1 div div"

How can i assign ID to array of DIVs like "#page_pricing .col1 div div"
<div id="page_pricing">
<div class="col1">
<div>
<div id="###">
<h1>Express Portrait</h1>
<p>Need professional pictures, but don't have a lot of time? This session is for you</p>
</div>
</div>
</div>
</div>
It doesn't really work like that, there has to be a container object (think html element). So the best way to get the result you want is to wrap up the divs you want to be in an array inside a parent object, a parent div, or span would work. So then that container can be given an id and you can reference your array by the children property of the parent object.
<div id=parent>
<div id=child0></div>
<div id=child1></div>
<div id=child2></div>
<div id=child3></div>
</div>
You would reference the array of children as document.getElementById('parent').children

(Javascript) Inserting elements dynamically in a specific position

Basically what I have is this:
<body>
<div class="class1">
</div>
<div class="class2">
</div>
<div class="class3">
</div>
...
</body>
I have no idea why the site creator used classes instead of IDs (they're unique), but it doesn't really matter as I'm writing a GM script and so getElementsByClassName('')[0] effectively does the same thing.
How can I insert an element between the first and second div?
Create your own insertAfter function
you can use JQuery it very simple
$(".class1").after( document.createTextNode("Hello") );

Categories

Resources