inner span is not getting ref in jQuery.Why? - javascript

I have one html structure:
enter code here <ul>
<li><span>aaa</span>
<div>
<ul>
<li><span>bbb</span> </li>
</ul>
</div>
</li>
<li><span>ccc</span>
<div>
<ul>
<li><span>ddd</span> </li>
</ul>
</div>
</li>
</ul>
now what should be the exact code to access
<span>aaa</span>and <span>ccc</span>
but not span with bbb and ddd...I have used $("li span:first-child") and its working fine..is it rite I mean as per standard...bcoz I think it should ref every first child span under any li inside that html file....what should be the exact code?

This maybe because you are nesting li without ol/ul, li should be inside ol/ul not inside another li

Your HTML is not well formed. li elements aren't closed. This could be causing the problem.

So you want all the <span>s which are a direct child of an <li> which has a nested list inside it? Here's my go at it:
$("li:has(ul) > span")
Explanation, step by step:
li // find all <li>s
:has( // which have inside them
ul // a <ul> tag
) // (current context is still at the <li>
> // now find just immediate children (not grandchildren, etc)
span // ..which are spans
The result set should now be a list of <span>s whose parent is an <li> which has a <ul> descendant.

Pay a visit to http://validator.w3.org/. Browsers do amazing things in trying to build a DOM from illegal markup, but the results are often not what you expect and inconsistent across browsers.
Use correct markup — then worry about tools dealing with it in unexpected ways. See GIGO.

Related

How to get value inside div inside ul inside li with Javascript?

I'm not learning jQuery yet, so javascript please. here is the HTML like below
<ul style="position: absolute;">
<li style="position: absolute;">
<div role="checkbox" class="filter-list-cell filter-text css-ahhuez">
<span class="dog-123" title="dogname">TEDDY</span>
<span>8%</span>
</div>
</li>
<li style="position: absolute;">
<div role="checkbox" class="filter-list-cell filter-text css-voqwhr">
<span class="dog-123" title="dogname">OZZY</span>
<span>7%</span>
</div>
</li>
.
.
.
8 more <li>
</ul>
what i try to get is inside the li > span value "TEDDY" and next li > span "OZZY" and the rest of 8 more li value inside the span, make the result as a array like:
dogname = [TEDDY,OZZY,REX...]
i tried right click to copy selector path then use document.querySelectorAll(), i got 10 NodeList, i Array.from it but i still need to pass the div to get the span value.
i think i should loop through them? but it looks weird to me...
im not really familiar with html so please give me some hint or direction for this problem
Thanks!
Grab the dogs by the dog-123 class name, and then map over the (converted to an array) node list to create a new array of names from each node's text content.
const dogs = document.querySelectorAll('.dog-123');
const names = [...dogs].map(dog => dog.textContent);
console.log(names);
<ul>
<li>
<span class="dog-123">TEDDY</span>
<span>8%</span>
</li>
<li>
<span class="dog-123">OZZY</span>
<span>7%</span>
</li>
<li>
<span class="dog-123">Bob from Accounting</span>
<span>700%</span>
</li>
</ul>
Additional documentation
Spread syntax
You can do it by using CSS selectors: grab the first span inside every div which is inside a li which is inside an ul. The :first-child part is called a pseudo-class, that is, it selects an element with respect not only to itself and its parents / siblings, but against characteristics of the XML tree or even external characteristics such as browser history.
Careful, though, because if you have another ul whose descendants have those characteristics, you would be selecting undesired values.
In one line:
Array.from(document.querySelectorAll("ul > li > div span:first-child")).map(x => x.innerText);
If you wanted to be more precise (in a scraper, for example), you would probably start with a root element with a known id (thence unique). So let's say you have <ul id="myList">, then the CSS selector would be #myList > li > div span:first-child.

JQuery hide list elements by partial class name

I need to find and hide all li tags in my page that have the partial class of 'fos-crs-'.
<li class="minimal-product-wrapper toggle-container fos-crs-XXX">...<li>
where the XXX is some course-code that comes from a database call. The "fos-crs" class is one I added so I can specifically find and manipulate these specific li tags. The other classes in the li tags are part of work created by off-site developers using Foundation. In other areas these have not been a problem for my JQuery.
I have tried:
$('[class^="fos-crs-"]').hide();
... and ...
$('li[class^="fos-crs-"]').hide();
Would someone tutor me in this? Much appreciated.
You are targeting the class that starts with(^) operator. Rather you should target with any occurrence(*).
i.e,
$('li[class^="fos-crs-"]').hide();
should be
$('li[class*="fos-crs-"]').hide();
http://jsfiddle.net/d4uk2fmg/
The attribute selector looks at the entire attribute, not each class in the attribute. So what you're code is looking for is elements whose class attribute starts with "fos-crs". You need to check if that string is contained within the attribute at all, so you need the * modifier.
$('li[class*="fos-crs-"]').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="minimal-product-wrapper toggle-container fos-crs-XXX">...<li>
<li class="minimal-product-wrapper toggle-container fos-crs-XXX">...<li>
<li class="minimal-product-wrapper toggle-container fos-crs-XXX">...<li>
<li class="minimal-product-wrapper toggle-container">...<li>
</ul>

How to distribute (insert) content nodes programmatically

Is there a way to programmatically distribute (insert) content from lightDOM to ShadowDOM?
I would like to wrap every single child node into an element.
For example :
<my-list>
<span>first element</span>
<div>second element</div>
<a>third element</a>
</my-link>
to be distributed as
<my-list>
<ul>
<li>
<span>first element</span>
</li>
<li>
<div>second element</div>
</li>
<li>
<a>third element</a>
</li>
</ul>
</my-link>
I need it not only to render that way, but also delegate entire HTML behavior (bindings, events, etc..) as each distributed node may contain entire app.
I have tried appending <content select=":nth-child(..)"> elements to template on attached callback
attached: function(){
//ensure any element upgrades have been processed
this.async(function asyncAttached(){
var list = this.$.container;
this.children.array().forEach(function(child, childNo){
var li = document.createElement("LI");
console.log(list, li, child);
li.innerHTML = '<content select=":nth-child('+childNo+')"></content>';
list.appendChild(li);
});
});
}
But it does not work (probably because content was already distributed).
Fiddle here
In general what I would like to achieve is something like http://jsbin.com/hegizi/3/edit, but without hard-coding class names, and make it work with variable number of child nodes.
What is more, it seems, that :nth-child is not supported natively: https://github.com/Polymer/polymer/issues/470
Composition is something Shadow DOM is designed for. If that spec bug gets fixed, the best way to do this would be interesting tricks with <content select=":nth-child(...)"> in a <template repeat>. Since you can't (currently) use :nth-child, you could instead use the distributed nodes and data-binding to wrap the content:
<template repeat="{{node in nodes}}">
<li>
<html-echo html="{{node.outerHTML}}"></html-echo>
</li>
</template>
<content id="c" select="*"></content>
nodes is generated from something like:
this.nodes = Array.prototype.slice.call(this.$.c.getDistributedNodes());
I'm using <html-echo> from this post: https://stackoverflow.com/a/22208332/274673
Working demo: http://jsbin.com/mamawugo/2/edit
There is quite old issue at W3C Bugzilla: #18429 - [Shadow]: Specify imperative API for node distribution
But as for now, there is nothing in spec about that.

s3slider code is not validating - cannot have <div> inside of <ul>?

My s3slider is working perfectly, but I cannot get it to validate. I keep getting the error message "document type does not allow element "div" here; assume missing "li" start-tag [XHTML 1.0 Transitional]" and "end tag for "li" omitted, but OMITTAG NO was specified [XHTML 1.0 Transitional]".
Lots of people use this slider, so they just all have invalid code? The problem is the <div class="clear s3sliderImage"></div> nested inside of the <ul>. If I place it outside of the ul, the last image of the silder doesn't show - just like the author points out in the link below.
See s3slider code and instructions here.
<div id="s3slider">
<ul id="s3sliderContent">
<li class="s3sliderImage">
<img src="#">
<span>Your text comes here</span>
</li>
<li class="s3sliderImage">
<img src="#">
<span>Your text comes here</span>
</li>
<div class="clear s3sliderImage"></div>
</ul>
The only valid child of a ul is an li. To get this to validate, move the clearer inside the last li, or outside the ul.
Better, set overflow: hidden on li.sliderImage and skip the clearing div altogether. In fact, removing it on the demo page doesn't seem to have any adverse effects, at least in Chrome. My guess is that it's a fix for old IE issues.

Add a space between ul and li element created by JavaScript

Been struggling with a problem now.
I have a list that behaves quite weird, and couldt find the problem until i firebugd it and saw that the entire file prints out in one row.
something like this.
<div class="clock-content-wrapper"><ul class="clock-digit-wrapper hour"><li class="clock-digit-one"></li><li class="clock-digit-three"></li></ul><ul class="clock-digit-wrapper minute"><li class="clock-digit-three"></li><li class="clock-digit-seven"></li></ul><ul class="clock-digit-wrapper second"><li class="clock-digit-zero"></li><li class="clock-digit-zero"></li></ul></div>
There is no spaces between the elements.
Now i didn't know that could be a problem so i started to fix the elements in firebug like this.
<div class="clock-content-wrapper">
<ul class="clock-digit-wrapper hour">
<li class="clock-digit-one"></li>
<li class="clock-digit-three"></li>
</ul>
<ul class="clock-digit-wrapper minute">
<li class="clock-digit-three"></li>
<li class="clock-digit-seven"></li>
</ul>
<ul class="clock-digit-wrapper second">
<li class="clock-digit-zero"></li>
<li class="clock-digit-zero"></li>
</ul>
</div>
And notice that if i have the </ul> element under my </li> the script actually works at it supposed to.
Is there a way to structure the file with javascript ?
I have a jsFiddle, where you can se the differens between the tree created in HTML and the one with JavaScript.
http://jsfiddle.net/Xk49c/
I really dont want to change anything in the css . since both html and js application is using the same css .
Your <ul> elements are displayed as inline-block in your fiddle. I suspect they are suffering from this little-known feature of inline-block.
The problem is, when you create the elements using HTML, you indent or separate the elements with one or more spaces, or even new lines. HTML renders these spaces as ONE single space and so you see the space between those elements.
To add spaces between elements created by JavaScript, either you ll have to add a padding left to minute and second class, or insert a text node between each UL
hours = createElementWithClass('ul', 'clock-digit-wrapper hour');
clock_toolbar_wrapper_close.appendChild(hours);
clock_toolbar_wrapper_close.appendChild(document.createTextNode(' ')); // Add this
minutes = createElementWithClass('ul', 'clock-digit-wrapper minute');
clock_toolbar_wrapper_close.appendChild(minutes);
clock_toolbar_wrapper_close.appendChild(document.createTextNode(' ')); // And this

Categories