Change element css based on contents through Javascript - javascript

Suppose I have a vertical menu that is coded like this:
<ul class="sub-menu">
<li id="menu-item-1" class="menu-item">
Page1
</li>
<li id="menu-item-2" class="menu-item">
</li>
<li id="menu-item-3" class="menu-item">
Page3
</li>
</ul>
As you can see, the anchor element to page2 doesn't contain any text. Therefore, I want to hide it from the menu. So I'm looking for a javascript solution that does something like this:
if (content of anchor tag equals " ") then
set anchor's parent list element css to visiblity:hidden;
Note that I can't use document.getElementById on this one because the list id's are automatically generated and may change over time. So how do I get to the content of the anchor tag and set the correct list item's CSS?
Thanks.

var link=document.getElementsByTagName("a");
for(var i=0;i<link.length;i++)
if(link[i].innerHTML.replace(/^\s+|\s+$/g, "")==='')
link[i].parentNode.style.display="hidden";
Working Demo

You could use getElementByTagName('li') and then test that class="menu-item'
See this sample.

If you are using jQuery, you can do something like:
$("li").each(function() {
if ($(this).find("a").text() == "")
{
$(this).css('display','none');
}
});

You could use something like this..
$('.sub-menu a').each(function () {
if (this.innerHTML == " ") {
this.parentNode.style.visibility = 'hidden';
}
})

Related

i am trying add css to all ' li ' element after scroll down but it apply only first li

After scrolling down, it's applying only the home button.
Here is my code.
<ul class="mainmenu nav sf-menu" style="float: right;">
<li class="active" id="scrl-li">
<span>Home</span>
</li>
<li id="scrl-li">
<a href="about.html" ><span>About Us</span></a>
</li>
<li id="scrl-li">
<a href="about.html" ><span>Services</span></a>
</li>
</ul>
JavaScript code:
$(document).ready(function() {
var scrollTop = 0;
$(window).scroll(function() {
scrollTop = $(window).scrollTop();
$('.counter').html(scrollTop);
if (scrollTop >= 100) {
$("#scrl-li").css("marginTop","-20px");
} else if (scrollTop < 100) {
$("#scrl-li").css("marginTop","0px");
}
});
});
The other posters are correct that you should only have one of an ID per page, but you may still be able to work around the problem if you do not have control of the markup by using
$("[id='scrl-li']") to target the elements instead of $("#scrl-li").
Id's should be unique and not repeated across elements. Changing your id's to classes makes this code work:
Change the jquery id references as well as the html id references to classes
<li id="scrl-li">
to...
<li class="scrl-li">
and....
$("#scrl-li")
to...
$(".scrl-li")
jsfiddle: https://jsfiddle.net/xpvt214o/794901/
View the html code as you scroll and you will see the margin attributes appear and change accordingly.
You cannot have more ids in your html template. You can have only one id="scrl-li".
In you html template replace the id with class and in the jquery instead of calling $("#scrl-li"), you will have to use $(".scrl-li").
Hope this will help you.

jquery get the height of the submenu

I have the <ul> tag as below. When clicked on the anchor link it should display a div with the ul list items underneath. On the click function of anchor tag, I need to get the complete height of the div (in fact the height of the ul with li items), the submenu
<ul>
<li>
<a></a>
<div>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</li>
</ul>
The html code is as below:
<ul class="menu level-1 plain" id="header-menu">
#{
var i = 1; //Used for submenu ID
}
#foreach (var menuItem in Model.Header.TopLevelNavigation)
{
if (i < 6)
{
<li #Html.Raw(i > Model.MenuMidPoint ? "class=\"sub-menu-nudge-left\"" : "")>
#if (menuItem.ContentLink.HasChildPages())
{
<a href="#sub-menu-#i" class="menu-link js-ui-header-all-menu-drill-down" aria-haspopup="true">
<span class="icon icon-chevron-left #Model.GetBoxIcon(i)"></span>
<span>#menuItem.Name</span>
</a>
<div id="sub-menu-#i" class="sub-menu" aria-label="submenu" aria-hidden="true">
#Html.DisplayEnumerableIContent("<ul class=\"level-2 plain\">{0}</ul>", "<li>{0}</li>", "menu-link", menuItem.ContentLink.GetChildPages(true, true))
</div>
}
</li>
}
i++;
}
</ul>
I tried the jquery function as below:
I tried as below, but I am unable to get the height of the submenu. It never gets into the foreach loop at all. Could anyone please help
$(".menu-link").click(function () {
var $subnavdev = $(this).parent().sublings('sub-menu').siblings('level-2 plain')
var totalHeight = 0;
$subnavdev.find('li').each(function() {
totalHeight += $(this).outerHeight(true);
});
alert(totalHeight);
});
Some of your class selectors were not specified correctly, plus there was a typographical error (all on Line 2).
Update - It also seems the siblings() methods may not be behaving as you intend them to... - And I got the .level-2 selector wrong still - since you need another . before plain. (See below example)
By using the closest() method you can go up to the nearest parent (for example, <li>), then use find() to pick out all .level-2.plain items nested within that parent.
Remember that your $(this) inside the handler function refers to the handled element, (in this case the .menu-link item being clicked.
$(".menu-link").click(function () {
var $subnavdev = $(this).closest('li').find('.level-2.plain');
// ...
});

Display active tab's name in an span

I would like to show the active tab's name (text) in a span .active-class.
Example:
<ul class="tabs">
<li class="feinleinen active">feinleinen</li>
<li class="glatt">glatt</li>
</ul >
<span class="active-class">*Active_Tab_Name_Here (i.e. feinleinen) *</span>
What you want is either to have a click event each time a link is clicked and put the text in there?
Javascript:
function changeSpan(var newText){
document.getElementByClassName('active-class').innterHTML(newText);
}
When the above you need to initialise the function. this can be done in the anchor within the list item.
<li><a href='#' onclick='changeSpan("new item name!");'>
Don't forget the hash (#) within the href! This stops the default action, in layman's terms.
With jQuery this can be a bit simpler
$('a','ul.tabs>li').click(function(){//a classname would be a better selector
$('.active-class').appendTo($(this).innerHTML());//can also use $(this).text();
return false;//also stops default action
});
FIDDLE:
HTML
<ul class="tabs">
<li class="feinleinen active">feinleinen
</li>
<li class="glatt">glatt
</li>
</ul>
<span class="active-class">active tab name here</span>
SCRIPT
$('.active-class').text($('.tabs .active').find('a').text());
I guess you want this on click , therefore bit updation to my above code here :-
$('.tabs a').click(function () {
$('.tabs li').removeClass('active');
$(this).parent('li').addClass('active');
$('.active-class').text($(this).text());
});
fiddle: http://jsfiddle.net/x97g8sc7/
$(".active-class").text($(".tabs .active").text());

Removing mark-up from unordered list with jquery

In the follow content I need to remove the mark-up tags <div class="sub"> and </div> but not it's content with jquery. This is to adapt the menu to a responsive layout.
<nav id="top">
<ul>
<li class="ti" id="snw"> <a class="mm" href="/snowdepth/">Weather</a>
<div class="sub">
<ul>
<li><h2>Snowline</h2></li>
<li>Nordliche Ostalpen</li>
</ul>
</div>
</li>
<li class="ti" id="blg"> <a class="mm" href="/live/">Weblog</a></li>
</ul>
</nav>
Try unwrap():
​$('.sub').find('ul').unwrap()​;
Essentially, you are looking for all the child elements of .sub, and unwrapping them or removing their parent.
Here's the demo: http://jsfiddle.net/yEseX/
You can do it this way.
Live Demo
$('.sub').parent().html($('.sub').html());
Supposing you may have more than one div with class sub, I'd suggest this :
var container = $('#top');
container.html(
container.html().split('<div class="sub">').join('').split('</div>').join('')
);
Try this,
var content = $(".sub").html(); // stored ".sub" div content
$(".sub").remove(); // remove ".sub" div
$("#top #snw").after(content); // insert content where you want
Try this:
var list = $('#snw');
var html = list.html();
list.html(html.replace('<div class="sub">','').replace('</div>',''));
Demo here
I think #Abhilash's answer is the neatest so far, but I would modify the selector slightly:
$('.sub').contents().unwrap();
This removes all of the .sub elements, leaving their contents in place.
JsFiddle: http://jsfiddle.net/yEseX/2/

Comparing URL to links

I have the following HTML:
<ul class="vertical_menu no_select">
<li class="edge_top"> </li>
<!-- Menu Items Here -->
<li class="not_selected"><a class="selection_link" href="index.htm">Home</a></li>
<li class="not_selected"><a class="selection_link" href="index.htm">Subitem 1</a></li>
<li class="not_selected"><a class="selection_link" href="index.htm">Subitem 2</a></li>
<!-- Menu Items End Here -->
<li class="edge_bottom"> </li>
</ul>
Now, the links with the class "selection_link" need to have the li element (their parent) to have a new class "selected" if the current url matches the href value inside of the anchor tag. I can get the full URL but I don't know how to use that to help seeing as there could be more than one page with the same name at different directory levels.
Thanks if you can help! I'm using jQuery with all of this so feel free to provide me with jQuery examples!
Check out the jsFiddle. This should do the trick:
$("ul.vertical_menu li a").each(function() {
if (this.href == window.location.href) {
$(this).parent().toggleClass("not_selected selected");
}
});
$('.selection_link').each(function() {
if($(this).attr('href') === window.location.pathName.substring(1)) {
$(this).parent().attr("class", "selected");
}
});
not tested, but it'll it should start you off. substring is because pathname starts with '/' you could just put that in your href's too
or this...
$('.vertical_menu a').each(function() {
if (location.href.search(this.attr('href')) != -1) {
$(this).parent().addClass('selected');
}
});

Categories

Resources