Insert markup before and after elements from NodeList - javascript

I got the following mark up:
<ul class="category-top-navigation__group--level-2">
<li class="category-top-navigation__item--column-1">
<li class="category-top-navigation__item--column-1">
<li class="category-top-navigation__item--column-2">
<li class="category-top-navigation__item--column-2">
</ul>
By using the following JavaScript selector:
document.querySelectorAll('.category-top-navigation__group--level-2 .category-top-navigation__item--column-1');
I can select a NodeList of all the column-1 or column-2 elements. Now what I wanna do is wrap the elements with column-1 and column-2 with a new element, perhaps a span so that the new markup would look like this.
<ul class="category-top-navigation__group--level-2">
<span class="new-element-1">
<li class="category-top-navigation__item--column-1">
<li class="category-top-navigation__item--column-1">
</span>
<span class="new-element-2">
<li class="category-top-navigation__item--column-2">
<li class="category-top-navigation__item--column-2">
</span>
</ul>
I was thinking to use insertAdjacentHTML afterend and beforebegin, however I am not quite sure how to get this working, or if that is the best approach to the task.

Related

How to getElement of an "a" tag within a "class"?

I've been wrestling with vanilla javascript for GetElementsBy(ID/Tag/Span) for some time, and was wondering if any of you have encountered this or know a solution to this problem.
I'm trying to getElementBy(...) for 3 innerHTML texts in the DOM that looks like this:
<ul class ="main_Bucket">
<li class="id_category">
<span class="id_item">
<span class="id_device">
This is the Data I want to Grab
</span>
</li>
<ul class ="main_Bucket">
<li class="id_category">
<span class="id_item">
<span class="id_device">
This is the Data I want to Grab
</span>
</li>
<ul class ="main_Bucket">
<li class="id_category">
<span class="id_item">
<span class="id_device">
This is the Data I want to Grab
</span>
</li>
Ultimately, I want to grab all three texts inside the text tag using GetElementsBy(...). What is the right approach to get this data?
Your HTML is pretty messy. I tried to clean it up in the example below, and added some distinct text for each bit of text you're trying to extract so it's more illustrative that we're grabbing 3 different links' texts. The code iterates over the anchors found, and uses the same highly specific selector #Jaromanda X wrote in his comment.
Click the "Run" button below to see it in action.
let anchors = document.querySelectorAll('ul.main_Bucket>li.id_category>span.id_device>a');
console.log(anchors.length, "anchors found");
anchors.forEach((anchor)=>console.log(anchor.innerText));
<ul class ="main_Bucket">
<li class="id_category">
<span class="id_item"></span>
<span class="id_device">
ONE: This is the Data I want to Grab
</span>
</li>
</ul>
<ul class ="main_Bucket">
<li class="id_category">
<span class="id_item"></span>
<span class="id_device">
TWO: This is the Data I want to Grab
</span>
</li>
</ul>
<ul class ="main_Bucket">
<li class="id_category">
<span class="id_item"></span>
<span class="id_device">
THREE: This is the Data I want to Grab
</span>
</li>
</ul>

jQuery - known class of child: find next descendent of parent in top (from parent ID)

I've been searching a lot for this, without any solution so far. As you might also have seen the topic title might be a little hard to interpret and that's because I'm not quite sure how to explain it shortly.
The problem
Looking at the HTML below, I know the class of the last element called "active" and this element is chosen dynamically in jQuery, based on which site the visitor is on currently - i.e. different elements has this class depending on the site. On another site the li with class first-sub-li could have the class active (or for that matter the li with class first). This class is, as said, added dynamically based on the site with jquery. From here on I wish to identify the parent of the element with active which is a direct descendent of top-parent and add a class called active-parent to this. I.e. in the case below i wish to add the active-parent class to the li with class second.
EDIT: Please note that the "depth" of the list can vary, therefore also requiring a "dynamic" approach to picking out the parent. I completely forgot this in the initial writing.
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li"></li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li">
<ul class="second-sub-sub-ul">
<li class="second-sub-sub-li active"></li> <!-- Here -->
</ul>
</li>
</ul>
</li>
</ul>
So far I've tried the following jQuery without succes as it doesn't identify it.
EDIT 2: This actually does work, but initially it didn't as it apparently was called before the class was loaded, despite appearing later in the javascript document. Wrapping it in a $(window).on("load", function() solves the problem as shown below.
$(window).on("load", function() {
$(".active").closest("#top-parent > li").addClass("active-parent");
});
The original code was just $(".active").closest("#top-parent > li").addClass("active-parent");
You can start traversing up with .parent(), it will excluding the self li.
$(".active").parent().closest("li").addClass("active-parent");
You can use :has() selector
$('#top-parent > li:has(.active)').addClass("active-parent");
$('#top-parent > li:has(.active)').addClass("active-parent");
.active-parent {
background-color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li"></li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li">
<ul class="second-sub-sub-ul">
<li class="second-sub-sub-li active"></li>
<!-- Here -->
</ul>
</li>
</ul>
</li>
</ul>
I think this is what you're looking for. Find all li which are direct descendants of topmost-parent and filter that for the one which has a child .active. Apply the class.
$('#top-parent > li').filter(function(e){
return $(this).find('.active').length>0;
}).addClass("active-parent");
.active-parent{background-color:red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li">1.1</li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li active">2.1</li> <!-- Here -->
</ul>
</li>
</ul>

Select specific anchor link with jquery

I have a menu structure like this:
<ul class="menu">
<li class="parent">
<a class="menu-link" href="http://url.com/#Id">Id</a>
</li>
<li class="parent">
<a class="menu-link" href="http://url.com/#Id">Id</a>
</li>
</ul>
and an English version where the menu is like this:
<ul class="menu">
<li class="parent">
<a class="menu-link" href="http://url.com/en/#Id">Id</a>
</li>
<li class="parent">
<a class="menu-link" href="http://url.com/en/#Id">Id</a>
</li>
</ul>
Using scrollspy, I’m detecting which section of the page is currently visible. So I can get the Id part of the anchor link. Now how do I select that specific anchor link?
I tried this:
$('.menu').find(":contains('#" + this.id"')" ).addClass('active');
But that doesn’t work (otherwise I wouldn’t be here!).
:contains will check html()/ text() part of the anchor tag, you need to use attribute selector for href of anchor tag as shown below
$('.menu').find("a[href*='#" + this.id + "']" ).addClass('active');
JSFiddle Demo
More Information on attribute contains selector
what about to separate url (which should be SEO) and set id independent of url query by using data-binding? I hope you are using some template engine to render this html code. If not its ok only one attribute more.
for example:
<ul class="menu">
<li class="parent">
<a class="menu-link" href="http://url.com/en/topic-for-women" data-id="1">Id</a>
</li>
<li class="parent">
<a class="menu-link" href="http://url.com/en/topic-for-men" data-id="2">Id</a>
</li>
For this you can use very simple calling of jquery:
$(".menu .menu-link[data-id='2']").addClass("active");
here s link enter link description here

How to add Dropdown arrow to a <li> which has child elements

This is my original menu.
<ul class="mymenu">
<li>1 HTML </li>
<li>2 CSS
<ul>
<li>3.1 jQuery
<ul>
<li>3.1.1 Download</li>
<li>3.1.2 Tutorial</li>
</ul>
</li>
</ul>
</li>
<li>3 Javascript </li>
</ul>
I want to convert it into
<ul class="mymenu">
<li>1 HTML </li>
<li>2 CSS <span class="parent">&#9660</span>
<ul>
<li>3.1 jQuery
<ul>
<li>3.1.1 Download</li>
<li>3.1.2 Tutorial</li>
</ul>
</li>
</ul>
</li>
<li>3 Javascript </li>
</ul>
The difference between two menu is,
<span class="parent">&#9660</span>
I want to add dropdown arrow to the each element which has submenu.
I want Jquery or javascript solution.
I will provide two solutions to the problem.
1). Javascript solution. Using jQuery you can achieve it pretty easy:
$('a + ul').prev('a').append('<span class="parent">&#9660</span>');
Demo: http://plnkr.co/edit/37k1KMpqJ6G2tPrvprBa?p=preview
2). CSS only solution. Using modern pseudo selectors you can do this:
li a:not(:only-child):after {
content: '\25bc';
}
Additional info: :only-child and :not selectors. Support: IE9+.
Note: CSS solution is not equivalent to javascript one, as it doesn't insert span.parent element in DOM.
Demo: http://plnkr.co/edit/sfoctCWzjRCBlXG9dVyD?p=preview

ng-repeat without an html element

i am trying to generate a blog list but i got a problem with ng-repeat. my list looks like this
<ul>
<li>
<h2>Title</h2>
<p>Message</p>
</li>
<li>
<h2>Title</h2>
<p>Message</p>
</li>
<span class="sep2"></sep>
<li>
<h2>Title</h2>
<p>Message</p>
</li>
<li>
<h2>Title</h2>
<p>Message</p>
</li>
<span class="sep2"></sep>
<li>
<h2>Title</h2>
<p>Message</p>
</li>
<li>
<h2>Title</h2>
<p>Message</p>
</li>
</ul>
So after every 2 list items, i have a span that levels my next 2 boxes.
Right now i have this angular code.
<ul>
<li ng-repeat="post in postsJSON">
<h2>{{post.title}}</h2>
<p>{{post.message}}</p>
</li>
</ul>
And i dont know how to generate that span after every second list item.
Thank you in advance, Daniel!
With angular v1.2 it becomes quite easy, using ng-repeat-start, ng-repeat-end and ng-if, you can check it here : http://jsfiddle.net/DotDotDot/XNJvj/1/
Your code will look like this:
<ul>
<li ng-repeat-start='post in postsJSON'>
{{post.item}}<br/>
{{post.message}}
</li>
<span ng-if="$odd && !$first" ng-repeat-end>
<span class="sep2">_____</span>
</span>
</ul>
ng-repeat-start/end allows you to enter a loop in a tag and close it in another, in this case, I also added a condition using the $odd parameter of the ng-repeat, showing only every other span
The issue here is not really with angular but more with the structure of your markup. ul tag should normally only contains li tags as children.
To resolve your issue I will stick to the ng-repeat you already have and create the separator with css. Something like that :
<ul class="blog list">
<li ng-repeat="post in postsJSON" class="blog entry">
<h2>{{post.title}}</h2>
<p>{{post.message}}</p>
</li>
</ul>
CSS :
.blog.entry {
border-bottom : 1px solid black // or whatever color
...
}
or if you need more control on the separator use css :after and do something like
.blog.entry:after {
content : "";
...
}
If you are not familiar with :after you can have a look there

Categories

Resources