CSS selector for the element without any classname or attribute - html

Is it possible to write a CSS selector matching the element which does not contain any attributes or class names?
For example, I have html like the following (but with tons of divs and dynamic class names) and I want to match the second div (it does not contain class)
<div class="xeuugli x2lwn1j x1cy8">
<div>
<div class="xeuugli x2lwn1j x1cy8">
<div class="xeuugli x2lwn1j n94">
<div class="x8t9es0 x10d9sdx xo1l8bm xrohj xeuugli">$0,00</div>
</div>
</div>
<div class="xeuugli x2lwn1j x1cy8zghib x19lwn94">
<span class="x8t9es0 xw23nyj xeuugli">Helloworld.</span>
</div>
</div>
</div>
P.S. Getting the div like div:nth-child(2) is not a solution.
P.P.S. Could you please advise in general why the dynamic class names are used in the development?

Well, if you can't use classes, maybe try giving it an ID if possible, like
<div class="xeuugli x2lwn1j x1cy8">
<div id="myId">
<div class="xeuugli x2lwn1j x1cy8">
<div class="xeuugli x2lwn1j n94">
<div class="x8t9es0 x10d9sdx xo1l8bm xrohj xeuugli">$0,00</div>
</div>
</div>
<div class="xeuugli x2lwn1j x1cy8zghib x19lwn94">
<span class="x8t9es0 xw23nyj xeuugli">Helloworld.</span>
</div>
</div>
</div>
ad then you can select the ID via the css #id selector like so:
#myId {
/*stuff here*/
}
If you can't have IDs either, we could get really creative by finding a grouping element which you will swear to never use on another place, like <section> or <article>, and then you could use
const elem = document.getElementsByTagName("article")[0];
elem.style.border = '2px solid red';
which returns an array of all elements with that tag name, which in our case would be the only one you need. Then you could via Javascript give it the css you need.

Related

Traversing the DOM with querySelector

I'm using the statement document.querySelector("[data-testid='people-menu'] div:nth-child(4)") in the console to give me the below HTML snippet:
<div>
<span class="jss1">
<div class="jss2">
<p class="jss3">Owner</p>
</div>
</span>
<div class="jss4">
<div class="5" title="User Title">
<p class="jss6">UT</p>
</div>
<div class="jss7">
<p class="jss82">User Title</p>
<span class="jss9">Project Manager</span>
</div>
</div>
</div>
I'd like to extend the statement in the console to extract the title "User Title" but can't figure out what combination of nth-child or nextSibling (or something else) to use. The closest I've gotten is:
document.querySelector("[data-testid='people-menu'] div:nth-child(4) span:nth-child(1)")
which gives me the span with class jss1.
I expected document.querySelector("[data-testid='people-menu'] div:nth-child(4) span:nth-child(1).nextSibling") to give me the div with class jss4, but it returns null.
I can't use class selectors because those are generated dynamically at build.
Why not just add [title] onto your querySelector?
document.querySelector("[data-testid='people-menu'] div:nth-child(4) [title]")
You can then get whatever you are looking for from that section? This is assuming title will be unique attribute in this section of html

How to query nested level DOM using javascript and recursive

I have an issue like this and still cant find a solution for it.
I have a DOM query like this
#someid .someclass p
Below is the DOM
<div id='someid'>
<div class='someclass'>
<p>
some text
</p>
</div>
</div>
How can I query the p element by just using these 3 API
document.getElementById
document.getElementsByClassName
document.getElementsByTagName
I want to use recursive in this case until I can get the p element
Thanks everyone for your guidance.
I've edited my answer and my you are looking for something like this:
var targetContent1 = myFunction('someid', 'someclass', 'p')
var targetContent2 = myFunction('anotherId', 'anotherClass', 'span')
console.log('targetContent1', targetContent1)
console.log('targetContent2', targetContent2)
function myFunction(idName, className, tagName) {
return document.getElementById(idName).getElementsByClassName(className)[0].getElementsByTagName(tagName)[0].textContent;
}
<div id='someid'>
<div class='someclass'>
<p>some text</p>
</div>
</div>
<div id='anotherId'>
<div class='anotherClass'>
<span>Another Tag Text!</span>
</div>
</div>
Use these:
document.getElementById("someid");
document.getElementsByClassName("someclass");
document.getElementsByTagName("p")

How to access div element text based on adjacent text

I have the following HTML code and am trying to access "QA1234", which is the value of the Serial Number. Can you let me know how I can access this text?
<div class="dataField">
<div class="dataName">
<span id="langSerialNumber">Serial Number</span>
</div>
<div class="dataValue">QA1234</div>
</div>
<div class="dataField">
<div class="dataName">
<span id="langHardwareRevision">Hardware Revision</span>
</div>
<div class="dataValue">05</div>
</div>
<div class="dataField">
<div class="dataName">
<span id="langManufactureDate">Manufacture Date</span>
</div>
<div class="dataValue">03/03/2011</div>
</div>
I assume you are trying to get the "QA1234" text in terms of being the "Serial Number". If that is correct, you basically need to:
Locate the "dataField" div that includes the serial number span.
Get the "dataValue" within that div.
One way is to get all the "dataField" divs and find the one that includes the span:
parent = browser.divs(class: 'dataField').find { |div| div.span(id: 'langSerialNumber').exists? }
p parent.div(class: 'dataValue').text
#=> "QA1234"
parent = browser.divs(class: 'dataField').find { |div| div.span(id: 'langManufactureDate').exists? }
p parent.div(class: 'dataValue').text
#=> "03/03/2011"
Another option is to find the serial number span and then traverse up to the parent "dataField" div:
parent = browser.span(id: 'langSerialNumber').parent.parent
p parent.div(class: 'dataValue').text
#=> "QA1234"
parent = browser.span(id: 'langManufactureDate').parent.parent
p parent.div(class: 'dataValue').text
#=> "03/03/2011"
I find the first approach to be more robust to changes since it is more flexible to how the serial number is nested within the "dataField" div. However, for pages with a lot of fields, it may be less performant.

HTML element to contain id or name from ko.observable using foreach

Below I have a for-each loop using knockout.js.
<div data-bind="foreach:Stuff">
<div class="row">
<span data-bind="text: $data.name"></span>
</div>
</div>
I need to have the HTML Element with an id or name or something that reflects a unique value related to the $data.name value, as another method runs asynchronously, and needs to know which HTML element to update.
Ideally, it would look something like this, I guess:
<div data-bind="foreach:Stuff">
<div class="row">
<span id="data-bind='text: $data.name'" data-bind="text: $data.name"></span>
</div>
</div>
I have found a knockout syntax that applies values during runtime to specified attributes:
<div data-bind="foreach:Stuff">
<div class="row">
<span data-bind="attr: { id: $data.name}"></span>
</div>
</div>
Are you looking for this
<div data-bind="foreach:Stuff">
<div class="row">
<span data-bind="text: $data.name,attr:{id:$data.name}'"></span>
</div>
</div>
Here name is a observable i believe when ever there is change in name in stuff it will automatically updates its value & attr:{id}just to give a dynamic id to element using available bindings .

How can I target a class within a class with CSS?

I've been up for hours trying and failing to make this work.
I have some code like this:
<h1 class="title ">MasterClass Lessons</h1>
<div class="view view-uc-products view-id-uc_products view-display-id-page_4 3col-grid view-dom-id-1">
<div class="view-content">
<table class="views-view-grid">
<tbody>
<tr class="row-1 row-first">
<td class="col-1"><div class="panel-display panel-1col clear-block" >
<div class="panel-panel panel-col">
<div>
<div class="views-field-field-image-cache-fid">
<div class="field-content">
<a href="/content/gold-pass-all-lessons">
</div>
</div>
<div class="views-field-title">
<span class="field-content">GOLD PASS - ALL LESSONS!</span>
</div>
I want to target the class "views-field-title" with a style sheet, but I only want to apply a style when it's a subclass of "3col-grid" which is specified in a div a few levels above. Drupal lets me specify my own class name (I used 3col-grid) for the specific purpose of this CSS targeting, but when I do the following…
<style>
.3col-grid .views-field-title {
font-weight:bold;
}
</style>
It doesn't work.
I also tried
.3col-grid>.views-field-title
and
.3col-grid * .views-field-title
and
.3col-grid*.views-field-title
I'm sure there must be a way to make it work, and I'm sure it's quite simple.
Anyone who can tell me what that is will make me a happy man.
Thanks,
Joe
Your HTML is invalid.
CSS classnames cannot begin with numbers.
Once you fix that, you can use the descendant selector:
.OuterClass .InnerClass