I'm pretty new to the javaScript and it would be very helpful for me if somebody could be so glad to give me some directions how to perform that. I'm creating website in Joomla 3 and I need to stylize the menu in a way that when a child menu item is active the parent item should change the background colour. I included the .js link into the head of the index.php file of my template. But I'm struggling second day with the desired script.
Here is my HTML:
<ul class="gf-menu l1">
<li class="item128 parent">
<a class="item" href"services">Services<span class="border-fixer"></span>::after</a>
<div class="dropdown columns-1">
<div class="column col1">
<ul class="l2">
<li class ="item1"><a class="item" href="submenu-01">Submenu1</a></li>
<li class ="item2"><a class="item" href="submenu-02">Submenu2</a></li>
<li class ="item3"><a class="item" href="submenu-03">Submenu3</a></li>
</ul>
</div>
</div>
</li>
</ul>
And that's it my CSS for it:
.gf-menu .dropdown{
border: 1px solid transparent;
border-radius:0;
background-color:#a9a9a9;
padding:10% 0;
width:100%;
text-shadow:none;
font-size:85%;
}
.gf-menu.l1 li.item1.active.last {background-color:#abcf39;}
.gf-menu.l1 li.item2.active.last {background-color:#f39512;}
.gf-menu.l1 li.item3.active.last {background-color:#f16e68;}
If you click on the <li> element and want to affect the parent you can use the .parent() method to target the parent element. The question is which one do you want to target. If it's the div which contains the <ul> you will have to access the parent of a parent. For example if the <li> has a class item as you stated in your question, you can do
$('.item').on('click', function(){
var clickedLiElement = $(this);
var parentHoldingUl = clickedLiElement.parent().parent();
//now you can do whatever you want with both of them, for example
clickedLiElement.addClass('active');
parentHoldingUl.css('background-color', 'green');
});
Update based on comments:
A slightly shorter version, which does what you specified in the comments
$('.item').on('click', function(){
$(this).css('background-color', '#5512F3');
$(this).parent().parent().css('background-color', '#5512F3');
$(this).siblings().css('background-color', '#AB99D5');
});
This should turn the clicked LI element and it's parent DIV dark blue and the clicked elemnent's siblings light blue.
Related
I'm trying to get the company I'm at a Help Centre set up, using Zendesk.
I've managed to implement a sidenav, but I'm struggling to make it show different anchor links depending on the category of the Help Centre the user is on. Zendesk only allows you to edit the HTML of the category page template, and I'm unable to dynamically load in the links.
Can anyone please advise on how to show DIV_1, only if the page contains <li title="Using ProductName">? I've searched but can't seem to find anything relevant.
From there I'll do the same for the other sections in the same way (e.g. only show DIV_2 if the page contains <li title="Developer Portal".
For reference, I have access to the category's HTML template, the CSS and JS.
Thanks in advance!
<div class="container">
<nav class="sub-nav">
<ol class="breadcrumbs">
<li title="Help Centre">
Help Centre
</li>
<li title="Using ProductName">
Using ProductName
</li>
</ol>
<div id="DIV_1">
<ul id="UL_2">
<li id="LI_1">
Admin and Settings
</li>
<li id="LI_1">
Getting Started
</li>
<li id="LI_1">
Content Types and Sources
</li>
<li id="LI_1">
Content Management
</li>
<li id="LI_1">
Content Publishing
</li>
<li id="LI_1">
Apps
</li>
<li id="LI_1">
Analytics
</li>
<li id="LI_1">
Troubleshooting
</li>
</ul>
</div>
</div>
</div>
You can use the built-in DOM query methods to accomplish this. In this case, you'd want to combine an if condition with the query, something like so:
if (document.querySelector('li[title="Using ProductName"]')) {
// make #DIV_1 visible however you please here
document.querySelector('#DIV_1').display = 'block';
}
If the li with the title Using ProductName does not exist, #DIV_1 will stay invisible; if it does, it will be shown.
You can do a quick for loop check:
var items = document.getElementsByTagName('li');
for (var i = 0; i < items.length; i++) {
if (items[i].title == titleToCheckFor) { showElement(); }
}
You can fill in titleToCheckFor with the title you're looking for ("Using _____") and the showElement function would display the div, or you could just show the div right in the loop.
Using DOM query method querySelector you can search the target element, by default we set all div's hidden, and then we show only the required.
<style>
.module {
display:none;
}
</style>
<script>
// by default we show MODULE A else show module B
var module = "DIV_1";
if (document.querySelector('li[title="Developer Portal"]')) {
module = "DIV_2";
}
// we show the respective DIV
document.querySelector('.' + module).display = 'block';
</script>
<div class="module DIV_1" id="DIV_1">
...
</div>
<div class="module DIV_2" id="DIV_2">
....
</div>
You can achieve this via CSS classes.
SOLUTION 1:
This being the sample HTML:
<div id="Div_1" class="menu-div using-productname">
</div>
<div id="Div_2" class="menu-div help-centre">
</div>
<div id="Div_3" class="menu-div other-tab">
</div>
Now you should setup your css like:
.menu-div {
display: none;
}
So all menu divs are hidden by default when the page loads
Now when you move to some tab suppose "Using ProductName", all you need to do is
var title = "Using ProductName"; //Get the title
var className = title.split(" ").join("-").toLowerCase(); //Convert it to the correct class which matches with your Divs in the menu
document.querySelector(".menu-div").style.display = "none"; //Set all menu divs to hidden
document.querySelector("." + className).style.display = "block"; //Show the desired menu div
SOLUTION 2:
This being the sample HTML:
<div class="parent-div">
<div id="Div_1" class="menu-div">
</div>
<div id="Div_2" class="menu-div">
</div>
<div id="Div_3" class="menu-div">
</div>
Now you should setup your css like:
.parent-div .menu-div {
display: none;
}
.parent-div.using-productname #Div_1 {
display: block;
}
.parent-div.help-centre #Div_2 {
display: block;
}
.parent-div.other-tab #Div_3 {
display: block;
}
Now when you move to some tab suppose "Using ProductName", all you need to do is
var title = "Using ProductName"; //Get the title
var className = title.split(" ").join("-").toLowerCase(); //Convert it to the correct class which you will add to the parent
document.querySelector(".parent-div").className = "parent-div " + className; //Set the parent div class to the className - the css will take care of the rest!
NOTE - Also you should use different ids on your different LIs and A tags.
You can use jQuery in Zendesk Help Centers so
var test = $('.breadcrumbs').children(':contains(amy)')
if(test.length > 0) {
do something here like
$('#LI_1').hide();
}
It's kind of simple brute force, but it works.
I need to add a class to the closest div with a given id after I click the div above it. My example below should make more sense of what I need.
<style>
.menuContent {display:none;}
.expandMenu {display:inherit;}
</style>
<ul>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent');">+</div>
<div id="menuContent" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent');">+</div>
<div id="menuContent" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
</ul>
This is the script I have so far that searches the class names of the given element and adds or removes the 'expandMenu' class when clicked.
<script>
function expandMenu(x) {
var d = document.getElementById(x);
var c = d.className;
if (c.search("expandMenu") === -1) {
d.className += " expandMenu";
} else {
d.className = c.replace(" expandMenu","");
}
}
</script>
This is all working fine, the issue is when clicking the 'menuIcon' in the second 'li', it's the first 'li' element that the script is applied too - it's obviously just finding the first 'menuContent' and applying the className function to it.
How can I limit the function to only apply to the 'menuContent' div that is directly after it.
I don't want to use jQuery either - good ol' fashioned plain Javascript would be great.
Give the menu icons unique ids, and pass that id to the function. Toggle based on the id, instead of the class. You are right, it is choosing the first one because it has found it when running through the code.
You should not have the same id on multiple elements. Try changing one of the id's and passing the new id to the function.
<style>
.menuContent {display:none;}
.expandMenu {display:inherit;}
</style>
<ul>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent1');">+</div>
<div id="menuContent1" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent2');">+</div>
<div id="menuContent2" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
</ul>
I have this html code
<div id="left-container" class="w3-container w3-left">
<div class="wordDiv w3-container w3-pale-green w3-leftbar w3-border-green w3-hover-border-red">
<h1>Give</h1>
<h3>Selected Definition:</h3>
<ul style="display:none;">
<li> offer in good faith </li>
<li> inflict as a punishment </li>
<li> afford access to </li>
</ul>
</div>
<div class="wordDiv w3-container w3-pale-green w3-leftbar w3-border-green w3-hover-border-red">
<h1>Up</h1>
<h3>Selected Definition:</h3>
<ul style="display:none;">
<li> to a higher intensity </li>
<li> to a later time </li>
<li> used up </li>
</ul>
</div>
</div>
<div id="right-container" class="w3-container w3-right"></div>
I want the user, once he click on one of the wordDiv's, to be able to see the potential definitions of that word in the right container (which are found in the "ul" element of each "wordDiv"), select one of the definitions, then I want to display the selected definition in the original wordDiv in the left-container.
You can found Jsfiddle Demo Here
A solution using jQuery. Updated Fiddle
$(function() {
$('.wordDiv').click(function() {
var txt = $(this).find('ul').html();
$('#right-container').html('<ul>' + txt + '</ul>')
})
})
Please check this fiddle
I have added li elements to another div based on the div which you are selected.
You can use the jQuery this variable in the click function, here is a working jQuery example of your request Updated Fiddle
It puts the li elements in the right div AND adds the onclick listener, which has the knowlege of its origin ;)
$('h1').click(function(){
var origin=$(this);
$(this).siblings('ul').children().click(function(){
$(this).parent().hide();
$(origin).parent().append(this);
$(this).replaceWith($('<div>' + this.innerHTML + '</div>'))
})
$(this).siblings('ul').show();
$("#right-container").append($(this).siblings('ul'));
})
$('ldi').click(function(){
$(this).parent().hide();
$(this).parent().parent().append(this);
$(this).replaceWith($('<div>' + this.innerHTML + '</div>'))
})
I'm writting a dropdown menu and I wanted to have the dropdown being controlled by javascript.
My dropdown has the sub menu hidden of sight max-height: 0px; and when the correspondent anchor tag is clicked, I change its max-height parameter to 400px, using the following function:
function drop_down(name) {
document.getElementById(name).style.maxHeight = "400px";
}
So far so good. The problem is that the element's max-height, stays at 400px and the sub menu does not hide. So I thought that I should target the click of the mouse and when this happens check if there is any element with 400px and change it back to 0.
$('html').click(function() {
var max_h = document.getElementsByClassName("nav_content");
var i;
for(i = 0 ; i < max_h.length ; i++)
{
if(max_h[i].style.maxHeight == "400px")
{
max_h[i].style.maxHeight = "0px";
}
}
});
What happens is that this function tracks every click, even the one used to display the sub menu. So my question is: is there a way to only activate the second function after I clicked my sub-menu? Because I always want the click that comes after the menu is displayed to close the sub menu.
HTML:
<body>
<div class="nav_container">
<nav class="nav_main">
<div class="logo">
<a href="#">
<img src="../majo.png" alt="logo">
</a>
</div>
<ul class="nav" id="nav">
<li>
Home
</li>
<li>
Consultas
<div id="nav_consul" class="nav_content">
<div class="nav_sub">
<ul>
<li>
Informação Dia a Dia
</li>
<li>
Totais Mensais
</li>
<li>
Tarifário Atual da Rede
</li>
<li>
Data específica
</li>
<li>
Atividade do Sistema
</li>
<li>
Coimas
</li>
</ul>
</div>
</div>
</li>
<li>
Simulações
<div id="nav_simul" class="nav_content">
<div class="nav_sub">
<ul>
<li>
Criar tarifa Simples
</li>
<li>
Criar tarifa Complexa
</li>
<li>
Simular com Nova Tarifa
</li>
</ul>
</div>
</div>
</li>
<li>
Preferências
<div id="nav_prefs" class="nav_content">
<div class="nav_sub">
<ul>
<li>
Lista de acessos
</li>
<li>
Alterar Password
</li>
<li>
Alterar Dados de Conta
</li>
</ul>
</div>
</div>
</li>
<li>
Log Out
</li>
</ul>
</nav>
</div>
<div id="content_main">
</div>
<footer></footer>
<script src="../js/jQuery.js"></script>
<script src="../js/user_menu.js"></script>
<script src="../js/user_nav.js"></script>
<script src="../js/user_clear_sub_menu.js"></script>
</body>
Here is an easy solution:
Create the following CSS-Styles:
.nav_content.visible {
max-height: 400px;
}
.nav_content.invisible {
max-height: 0px;
}
Set the overflow property for your nav_content to hidden:
.nav_content{
overflow: hidden;
}
Now add the class invisible to your submenus, if you want them to be invisible by default (you can do this manually in the markup or by js code):
Manually e.g.:
<div id="nav_prefs" class="nav_content invisible">
or by code (after the elements have been loaded):
$(".nav_content").addClass("invisible);
Now, if you just need to adjust your drop_down function to toggle the element's invisible/visible class:
function drop_down(dropdownID){
$('#'+dropdownID).toggleClass("visible invisible");
}
UPDATE: To make all visible submenus disappear when clicked elsewhere use this piece of code, when the window is loaded:
$(document).on('click', function (e) {
if (!$(e.target).is('.nav_item') && !$(".nav_item").has(e.target).length !== 0) {
$('.nav_content.visible').toggleClass("visible invisible");
}
});
If you only want to have one submenu visible at a time, you can use this version of your drop_down function:
function drop_down(dropdownID) {
$('.nav_content.visible').toggleClass("visible invisible");
$('#' + dropdownID).toggleClass("visible invisible");
}
A working fiddle can be found here
EDIT: Since you used jQuery in your original code, I assumed the answer can use jQuery too
You'll want to create a click handler on your document, then check the target of the click. If the target of the click has a certain class, use the menu behavior. If not, or if it's a sub-menu, close the menu.
Here's a question with multiple examples:
How do I close menu on click and when the user clicks away?
Also, I'd recommend not using max-height to hide and show. Since you're using jquery already, you could just use hide() and show().
One more thing: since you're using jquery already, you don't need to use these calls: document.getElementById(name). You can do a $("#yourId") or for document.getElementsByClassName("nav_content"); you can use $(".your-class")
It looks like you attached click event to entire document. I think you need to change only $('html').click(function() { to something like $('sub-menu-selector').click(function() { to
only activate the second function after I clicked my sub-menu
Aside to that, since it's only piece of jQuery and if you're not using it elsewhere, I would replace this with addEventListener and attachEvent, but maybe that's just me :)
In that case you can use jQuery.not() method to exclude the dropdown menu from your jQuery selection, here's what you need :
$('html').not(document.getElementsByClassName("nav_container")[0]).click(function() {
//As you can pass an element to it
You can also use the :not in your first selector like this:
$('html:not(div.nav_container))
I have several items in a list and want to highlight the one a user clicks on by applying some css style, maybe a background color etc.
My HTML looks like this:
<ul class="thumbnails">
<li>
<a href="#" class="thumbnail">
<img class="giftthumb" src='thumb1.jpg' alt="">
<span class="gifttitle">Thumb1</span>
</a>
</li>
<li>
<a href="#" class="thumbnail">
<img class="giftthumb" src='thumb2.jpg' alt="">
<span class="gifttitle">Thumb3</span>
</a>
</li>
<li>
<a href="#" class="thumbnail">
<img class="giftthumb" src='thumb3.jpg' alt="">
<span class="gifttitle">Thumb3</span>
</a>
</li>
</ul>
jQUery to retrieve selected item:
$('.thumbnail').click(function(e) {
e.preventDefault();
???
})
You could use jQuery's class management methods (namely addClass() and removeClass() in this case) to add a class on the selected item and remove the same class from all the other items (if you want only one selected at a time).
//save class name so it can be reused easily
//if I want to change it, I have to change it one place
var classHighlight = 'highlight';
//.click() will return the result of $('.thumbnail')
//I save it for future reference so I don't have to query the DOM again
var $thumbs = $('.thumbnail').click(function(e) {
e.preventDefault();
//run removeClass on every element
//if the elements are not static, you might want to rerun $('.thumbnail')
//instead of the saved $thumbs
$thumbs.removeClass(classHighlight);
//add the class to the currently clicked element (this)
$(this).addClass(classHighlight);
});
Then in your CSS just add:
.highlight {
background-color: cyan;
font-weight: bold;
}
jsFiddle Demo
This is a better solution than changing CSS properties directly from jQuery/Javascript (with the .css() method for example), because separation of concerns will make your code more manageable and readable.
$('.thumbnail').click(function(e) {
e.preventDefault();
$(this).css('background-color', 'red');
})
Your ??? would be:
$('.thumbnail').removeClass('selected');
$(this).addClass('selected');
Then all you have to do is define your 'selected' css class.
If you don't need the active to be persistent here's a CSS way:
li:focus{
background: red;
}
li:active{
background: gold;
}
<ul>
<li tabindex="1">Item 1</li>
<li tabindex="1">Item 2</li>
<li tabindex="1">Item 3</li>
</ul>
Now click <b>here</b> and see why it's not persistent.
in some situations the above might be useful - to only highlight the currently "click-active" item…