Counting Sub-Menu Items jQuery without CSS Classes - javascript

The great Google and SO didn't render search results regarding this. Some were similar but didn't quite get me there.
I am in need of making a classless submenu that will attach a style attribute to each individual <li> in the sub <ul> in order to set a min-width property based on the number of sub list items.
The HTML
<nav>
<ul>
<li>HOME</li>
<li>ABOUT COMPANY</li>
<li>
ABOUT PRODUCT
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li>GETTING STARTED</li>
<li>
PATIENT SUPPORT
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>CONTACT</li>
<li>eUPDATES</li>
</ul>
</nav>
The JavaScript
$('.sub').text(function() {
var count = $(this).next().find('li').length;
var totalwidth = count * 115;
$(this).next().find('li').parent('ul').attr('style','min-width:'+totalwidth+'px');
});
I need to be able to do this without searching based off the class "sub". I've tried a few times, but none of it seems as powerful as the code I'm currently using. The backend developer I'm working with is requiring it to all be simple <ul><li></li></ul> structure with no classes.
If anyone can help point me in the right direction on this, I'd greatly appreciate your time and help!

Target all LI items that contain UL's, find the number of LI's in those UL's, and multiply for width :
$('ul', 'li').css('min-width', function() {
return ( $(this).find('li').length * 115 ) + 'px';
});

Related

Universal method of dealing with mobile multi-level navigation menus using HTML, CSS and JavaScript

I have my html as follows:
<button id="hamburger-nav"></button>
<nav>
<ul>
<li>
<button>Sub Nav Item 1</button>
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
</ul>
</li>
<li>
<button>Sub Nav Item 2</button>
<ul>
<li>Link 6</li>
<li>Link 7</li>
<li>Link 8</li>
<li>Link 9</li>
<li>Link 10</li>
</ul>
</li>
<ul>
</nav>
This is a mobile menu that has a hamburger button that activates the "nav" on click. How do I get the index of the sub nav buttons so I can active their sibling "ul" sub sub menu? Granted all of this has to be done on the onclick method since it is a mobile menu.
I was hoping to have a universal method that could find the index of (this), i.e., the item that is clicked, and then get the corresponding "ul", instead of individually naming these and creating a massive, duplication of code for each menu section.
I would like to use plain old JavaScript as I am trying to cut down on the dependencies of jQuery, etc. Something along the lines of:
var menuButtons = document.querySelectorAll("nav > ul > li > button");
var submenu = document.querySelectorAll("nav > ul > li > ul");
menuButtons.onclick = myFunction(this);
function myFunction(v) {
submenu[v].classList.add("open");
}
While I know this JavaScript doesn't work, accessing the index of the clicked button and opening its accompanying nav was my thought process. But perhaps I'm way of going about this.
Thank you in advance!

Adding class to menu item in Wordpress

I have menu with items. I want to add to tag class with name "name". I try to use:
var element = document.getElementById('myElement');
element.classList.add('myClass');
But the tag doesn't have any ID or class.
It's even possible with Javascript?
<ul id="menu-main">
<li id="menu-item">
ODKAZ
</li>
</ul>
If you really want to add the class with javascript, you can do:
var element = document.getElementById('menu-item');
element.getElementsByTagName("a")[0].classList.add('js-target-scroll');
<ul id="menu-main">
<li id="menu-item">
ODKAZ
</li>
</ul>
But beware that the "onemenu" you are talking about is looking for this css-class and if your own script is not run before that, this won't work since the class is not yet added.
If it's your own theme you are developing, you can add the css-class server side with custom walker.
If you want to add the class for all menu item anchor tags, you can use the code below. If not, use what Esko has suggested in his answer and comments.
var menuItemLinks = document.querySelectorAll("#menu-main li a");
menuItemLinks.forEach(function(element) {
element.classList.add("myClass");
});
<ul id="menu-main">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>

Is there a way to determine if a keyup elem -is not- a particular parent or that parents children?

I can't seem to find a solution for this after hours of searching :-(
I've tried to no avail:
jQuery('#someGlobalNav').delegate('*','keyup', function(){
if(!(jQuery('#itemsForSale').find(jQuery(this))){// do something}
jQuery("#itemsForSale, #itemsForSale > * ").focusout(function(){}
Tried using :not, and :contains.
Basically, I have a grouping of links. Lets use this below:
<div id="someGlobalNav">
<ul id='siteNavigation'>
<li id="itemsForSale">
<div id="items">
<ul id='itemNav'>
<li>
<div id="menu1">
<ul>
<li>menu 1 item 1</li>
<li>menu 1 item 2</li>
</ul>
</div>
</li>
<li>
<div id="menu2">
<ul>
<li>menu 2 item 1</li>
<li>menu 2 item 2</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li>Link that Might exist</li>
<li>AnotherLink that Might exist</li>
</ul>
<div>Arbitrary link</div>
</div>
everything is captured fine etc.. the only issue is, I want to ONLY act on elems that are NOT "itemsForSale" or its children. So, as a user keyups thru links, all is fine UNTIL they keyup on somethign outside of itemsForSale --
I figured to use :not - but I won't know the selectors as the nav is dynamic. I tried all sorts of other things no luck.
Any ideas
An over simplified solution to your problem would be like this:
$('a:not(#itemsForSale *)');
Demo on jsbin: http://jsbin.com/idijos/1/edit

Can CSS drop-down behave like Windows7 drop-downs?

Let's say that menu has the following structure:
<li class="parent-of-all">Parent
<ul class="sub-menu level-0">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4
<ul class="sub-menu level-1">
<li>Item 1.1</li>
<li>Item 1.2</li>
<li>Item 1.3
<ul class="sub-menu level-2">
<li>Item 2.1</li>
<li>Item 2.2
<ul class="sub-menu level-3">
<li>Item 3.1</li>
<li>Item 3.2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
And this is how it looks like when styled (please note that nested sub-menus are position: absolute; left: 100%;).
Now the questions is - can I avoid it being pushed off the screen? I'm looking for a solution that Windows7 menus use (they never go off the screen). Is there some simple Javascript check? I think that doing just left: -100%; would work but under what conditions? I just need some idea and I can code that in Javascript :)
As far as i know, there is no way to do this check with CSS only. You will have to use javascript. The most straight forward approach would be binding mouseover/mouseout (or hover if you use jquery) to the items, then comparing the elements x-offset + width with window width.
With a pure CSS solution you could always alternate the position of the submenus. When the first was left positioned to appear right to its parent, the following (third) submenu could be positioned on the left and so on. Maybe you could even use the :nth-child-selector to do so.
Afterwards you can create exceptions for wider screens, just alternating the left position starting off the nth child submenu (using CSS media queries).
No, you need to use JavaScript in order to calculate positions

Adding auto increment value to li element

im a css/designer guy so please excuse my lameness in not knowing any .js
basically i want to know how to add an auto incremental id to a list item with javascript / jquery for something that i am trying to add some css to.
before
<li id="">Item number 1</li>
<li id="">Item number 2</li>
<li id="">Item number 3</li>
after
<li id="1">Item number 1</li>
<li id="2">Item number 2</li>
<li id="3">Item number 3</li>
thanks in advance and especially just for reading this
tried all the responses, nothing has worked on a plain html page with nothing but the ul/li items.
thanks to all that tried, i have failed in a big way.....im not a coder
I'm going to give your li tags an encompassing ul with an id in case there are other li tags on the page that you don't want to order, but in jQuery this is pretty easy for:
<ul id="ordered">
<li>Item number 1</li>
<li>Item number 2</li>
<li>Item number 3</li>
</ul>
You would simply use the each method:
$('#ordered li').each(function(i,el){
el.id = i+1;
});
I would recommend using something other than just a plain integer for an id though, so maybe something like 'ordered' + (i+1) instead of just i+1 above.
Your tags say jQuery, so:
$("li").each(function(i){this.id = i})
So you can learn: you make a collection of HTML nodes with the $('foo') syntax. You use CSS selectors, so li will get -every- <li> on the page.
.each loops over those collected HTML elements, and does something to them. The 'something' is in the code function(i){this.id = i}. jQuery passes which loop you're on to the function as i, and the code inside the curly braces sets the id of that particular element to i.
If you need id's for styling, that's a bad idea. What you should do is use css 3 pseudo class :nth-child(n) which is in your area of css.
I'm going to wrap your code in a div so it's easier to code for
<div id="increment">
<li>Item number 1</li>
<li>Item number 2</li>
<li>Item number 3</li>
</div>
And js would be:
function loadcode(){
var increments = document.getElementById("increment");
var li = increments.getElementsByTagName("li");
for (i=0;i<li.length;i++) li[i].setAttribute("id", i+1);
}
and in your HTML:
<body onload="loadcode()">

Categories

Resources