Hiding subsections of a timeline based on current slide? - javascript

I have a timeline for my product tour that has 4 main sections, with 4-5 subsections in between, it is set up like this:
<ul class="slideshow-timeline">
<li class="active-target-main main-section">Target
<ul class="current-section target-sub">
<li>Donor Profiles</li>
<li>Segmentation</li>
<li>Custom Lists</li>
<li>RFM Analysis</li>
<li>Wealth Screening</li>
</ul>
</li>
<li class="main-section">Connect
<ul class="current-section connect-sub">
<li>Email Marketing</li>
<li>Social Media</li>
<li>Direct Mail</li>
<li>Welcome Series</li>
</ul>
</li>
<li class="main-section">Convert
<ul class="current-section convert-sub">
<li>Donation Forms</li>
<li>Automated Receipts</li>
<li>Events</li>
<li>Member Mgmt</li>
<li>Moves Mgmt</li>
</ul>
</li>
<li class="main-section">Optimize
<ul class="current-section optimize-sub">
<li>Analytics</li>
<li>Campaigns/Funds/Appeals</li>
<li>A/B Testing</li>
<li>Task Management</li>
</ul>
</li>
</ul>
I am looking for a JS solution to allow me to hide the connect-sub, convert-sub, and optimize-sub while the .active-tour div has a class of target-panel.
I attempted this by using .css but was wondering if there would be a more-elegant solution?
$(function() {
if($('.active-tour').hasClass('target-panel')) {
$(".connect-sub").css("display", "none");
$(".convert-sub").css("display", "none");
$(".optimize-sub").css("display", "none");
}
});
Since the timeline and slides are set as position:absolute and position:fixed it is not sitting in the page flow, so I can't just target it in css.
In theory, this JS should work, but for some reason, it doesn't want to hide the 3 sub sections. No errors are being thrown either. Here is my working page.
I will continue looking into a solution, but if any of you could point me in the right direction, I'd really appreciate it!
Updated to hide all subnavs and show with javascript:
$(function() {
if($('.active-tour').hasClass('target-panel')) {
$(".target-sub").css("display", "block");
}
});

Updated answer:
Use a containing div for both the main content and the footer timeline. Set the class on this outer div using jQuery and use css selectors to show the correct submenu items accordingly.
updated fiddle here
original answer:
Here's a quick and dirty way to do it:
$('.main-section').on('click',function(){
$('.main-section').removeClass('active-tour');
$(this).addClass('active-tour');
});
.current-section{
display:none;
}
li.active-tour .current-section{
display:block;
}
fiddle here

Related

Link 'active' state on two separate HTML elements

I'm trying to mirror the 'active' state on two unordered lists using jquery/javascript. The first list is a slider/carousel and the 2nd list will be navigation links.
E.g.
<ul class="carousel">
<li class="active">Slider 1</li>
<li>Slider 2</li>
<li>Slider 3</li>
<li>Slider 4</li>
</ul>
<ul class="nav">
<li class="active"><a href'#">Link 1</a></li>
<li><a href'#">Link 2</a></li>
<li><a href'#">Link 3</a></li>
<li><a href'#">Link 4</a></li>
</ul>
So, the idea is that when the active state of the <li> in the carousel changes, so does the corresponding <li> in the 'nav' list.
Any help would be greatly appreciated.
I've created a working example here: https://jsfiddle.net/aj68mogk/14/
It was not working for you on JSFiddle because the script does not change the carousels .active class, thats done by the wp plugin.
I've put in a link to "fake" the action the plugin does (changing the carousel state).
There was a mistake in the part of code wich gets the index of the active carousel li.
So please ignore the code of my first answer and take the one of the JSFiddle. But dont forget to remove the fake link and its click function when using this on your page
Next thing is you have to select a Jquery version on JSFiddle, otherwise the $(document).ready() function is never entered, because its not pure js.
Hope this helps, if there are questions left, just leave a comment
I worked something out from several SO posts:
$(document).ready(function() {
$('.carousel').bind('DOMSubtreeModified', function(e) {
$(".nav>li.active").removeClass("active");
$(".nav>li").eq($(".carousel").index($("active"))).addClass("active");
});
});
Just add this to your Javascript and its done.
What it does: First you bind any DOM-Changes (you've said it's changed by a wp plugin or so) in the .carousel element to a new function. Inside the function you remove the active li tag, then you pick the index of the active carousel element and add the .active tag to the nav element with the index from the .carousel
Hope this helps
EDIT: There was a mistake in the code, some unneccesary line i kept in from testing. Please take the updated code
If you don't have access to the code of Wordpress plugin you have no direct way to do it , but can use a setTimeOut function. This is not the cleanest of the approaches , but I guess there is no other option.
setInterval(function() {
if ($(".carousel li").hasClass("active")) {
var active = $(".carousel").find(".active");
var index = $(active).index();
index = index + 1;
$(".nav li:nth-child(" + index + ")").addClass("active");
}
}, 1000);
.active {
color: red;
}
.active a {
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="carousel">
<li class="">Slider 1</li>
<li class="active">Slider 2</li>
<li>Slider 3</li>
<li>Slider 4</li>
</ul>
<ul class="nav">
<li class="">
Link 1
</li>
<li>Link 2
</li>
<li>Link 3
</li>
<li>Link 4
</li>
</ul>

Hover an element, add class to another div with same class

I already found a part of my problem but it still needs work.
What i want to achieve is when i hover over a div, others divs should have class added to them if the original class is the same.
So let's start.
I have a menu:
<ul id="listz"><li class='has-sub'><a href='/produse/trape-de-fum-si-ventilatie/'><span>Smoke vents</span></a>
<ul>
<li class='has-sub'><a href='/produse/trape-de-fum-si-ventilatie/trape-de-fum/'><span>Trape de fum</span></a>
<ul>
<li><a href='/rokvent-simplu-canat'>RokVent Simplu canat</a></li>
<li><a href='/pheonix-dublu-canat'>Phönix Dublu canat</a></li>
<li><a href='/megaphonix'>Megaphönix</a></li>
<li><a href='/megastar'>MegaStar</a></li>
<li><a href='/firefighter'>Firefighter</a></li>
<li><a href='/smokejet'>SmokeJet</a></li>
<li class='last'><a href='/multijet'>MultiJet</a></li>
</ul>
</li>
<li class='has-sub'><a href='/produse/trape-de-fum-si-ventilatie/trape-de-ventilatie-si-vizitare/'><span>Trape de ventilatie si vizitare</span></a>
<ul>
<li><a href='/rokvent-luminatoare-fixe'>RokVent(luminatoare fixe)</a></li>
<li class='last'><a href='/rokpas-luminatoare-acces'>RokPas(luminatoare acces)</a></li>
</ul>
</li>
</ul>
</li></ul>
As you can see i have Parent "Smoke vents" that has children.
The menu is on the left side. On the right side i will have a picture with a warehouse that has smoke vent elements. When you hover over them, they change color.
At that moment the menu needs to open and show the associated product that is in the menu. So when you hover over the element of the warehouse it should add class to the menu so i can change the background and show that that element is that product or products.
One problem is that i need it to match them by class (wich i will make unique by each element).
The second problem is that the menu does not open when i hover over a part of the image. If i have the menu open i can see the highlighted item in the menu.
This is the code that i got now and does the hovering part but only by matching in order.(what i mean is that if i add only to the parents the class it shows right but if i add to a child also then the last parent will not have a addClass):
<script type="text/javascript">
$("#listz1 li,#listz2 li").hover(function() {
var index = $(this).index();
$("#listz1, #listz2").each(function() {
$(".link1",this).eq(index).toggleClass("hoverz");
});
});
</script>

HTMl CSS Dropdown Nav

I have a navigation menu that works well and looks good.
The HTML for the menu is:
<div id="menubar">
<div id="welcome">
<h1>Cedars Hair <span>Academy</span></h1>
</div><!--close welcome-->
<div id="menu_items">
<ul id="menu">
<li class="current">Home</li>
<li>The Salon</li>
<li>Testimonials</li>
<li>Courses</li>
<li>The Staff</li>
<li>Contact Us</li>
</ul>
</div><!--close menu-->
</div><!--close menubar-->
But I want to change it so it is something like:
<li>The Salon
<ul>
<li>Hair Cut</li>
</ul>
</li>
So under the salon, a drop down menu would come up with 'Hair Cut'.
I know this is possible with CSS, but the problem is I have a lot of CSS with the divs shown above (menubar, welcome, menu_items etc). Do you know the most simplest way to make a simple dropdown?
The simplest way in a nutshell:
https://jsfiddle.net/svArtist/2jd9uvx0/
hide lists inside other lists
upon hovering list elements, show the child lists
ul ul {
display:none;
display:absolute;
bottom:-100%;
}
li{
position:relative;
}
li:hover>ul {
display:table;
}
<ul>
<li>The Salon
<ul>
<li>Hair Cut
</li>
</ul>
</li>
</ul>
Why don't you use Jquery UI?
https://jqueryui.com/menu/
<script>
$(function() {
$( "#menu" ).menu();
});
</script>
Added the sub menu using li:hover
Here is the fiddle - https://jsfiddle.net/gkdj6y5x/

Cufon (jQuery?) selector not to select children

I have a very basic and usual list menu with a submenu:
<ul>
<li>Home</li>
<li>
About
<ul id="sub-menu">
<li>Child1</li>
<li>Child2</li>
</ul>
</li>
</ul>
And then I have a Cufon selector applying a font to the menu:
Cufon.replace('ul li a');
Is there any way to select only the first level of the menu and disregard the other? Right now both levels get the font, but I would like to use something else for submenu.
I am very much a beginner with Javascript, Cufon and jQuery, I tried using child selectors but I had no luck with that. How can I achieve this?
It appears that your JavaScript library uses CSS-style selectors; you can just use
<ul class='containingMenu'>
<li>Home</li>
<li>
About
<ul id="sub-menu">
<li>Child1</li>
<li>Child2</li>
</ul>
</li>
</ul>
with this selector
ul.containingMenu > li > a
where the > causes the selector to apply only to a's that are direct children of li's that are direct children of the ul.containingMenu.
↪ See this example in action at JSFiddle.

How can I stop a JavaScript function from affecting a child element?

I have looked around for a solution to this problem, but it's so wonky that I doubt many people have considered it. A web application that I've recently inherited as a web administrator runs on Drupal (version 6). Unfortunately, I am unable to edit the Drupal install or create a custom theme until May due to other obligations that must be tended to first.
First off, I realize and whole-heartedly agree that there are more efficient (and elegant) ways of solving this problem, but for the time being, this is what the client wants and is comfortable with implementing.
Anyways, the old administrator was using Drupal to develop the site's navigation. The code that Drupal spits out on the HTML page is:
<ul class="menu">
<li class="expanded first">Housing
<ul class="menu">
<li class="leaf first">Housing Roster</li>
<li class="leaf">My Floor</li>
<li class="leaf">Photo Viewer</li>
<li class="leaf last">Building Maintenance</li>
</ul>
</li>
<li class="expanded">Reports
<ul class="menu">
<li class="leaf first">Build Floor Report</li>
<li class="leaf">Submit Incident Report</li>
<li class="leaf last">Submit Lockout</li>
</ul>
</li>
<li class="expanded">Office
<ul class="menu">
<li class="leaf first">Check In Package</li>
<li class="leaf">Check Out Building Package</li>
<li class="leaf">Check Out Campus Package</li>
<li class="leaf last">Check Equipment Out</li>
</ul>
</li>
<li class="expanded">Staff
<ul class="menu">
<li class="leaf first">Pre Programs</li>
<li class="leaf">Post Program</li>
<li class="leaf">Programming Database</li>
<li class="leaf last">Staff Downloads</li>
</ul>
</li>
<li class="leaf">My account</li>
<li class="leaf last">Log out</li>
The biggest concern I have with this output is that there is a ul element with the class attribute of "menu" nested inside of another ul element with the class attribute of "menu."
The goal of the JavaScript function that I am writing is to
Allow for jQuery to expand and collapse the child ul element whenever the respective li element with a class of "expanded" is clicked
Change the href attribute of ONLY the li elements with a class of "expanded" to "javascript:void(null)" so that they don't redirect the user to any page
Here is the JavaScript function that I've got going so far:
<script type="text/javascript">
$(function() {
//Hide the nested lists
$('ul.menu li.expanded ul.menu').hide();
//Change the destination of the header links
$('ul.menu li.expanded a').attr("href", "javascript:void(null)");
//Toggle the display of the nested lists
$('ul.menu li.expanded a').click(function() {
$(this).next().slideToggle('normal');
});
});
</script>
This works just fine, except it changes the href attribute of the nested li elements to "javascript:void(null)" as well. Is there a way that I can alter my JavaScript function to make sure that it applies the new href attribute ONLY to the li elements with a class of "expanded" and not to the li elements with a class of "leaf?"
At this point, I'm really only interested in an alteration of my JavaScript function. Like I said, I know and agree that there are better methods (such as altering the html output of the Drupal theme to begin with), but if I can get a quick fix in as a temporary solution while I rebuild the entire application, that would be awesome!
Please let me know if you have any suggestions!!!
THANKS!!!
Use a more specific selector:
$('ul.menu > li.expanded > a').attr( ...
The > matches only immediate children instead of all children.
If you're just trying to prevent the browser from following the href, you don't need the "javascript:void(null)". What you want to do instead is to stop the event from propagating:
$("ul.menu li.expanded > a").click(function(event) {
event.stopPropagation();
...
});
You could try
$('ul.menu li.expanded>ul.menu').hide();
This makes it apply only to the next element.
Another way would be to use
$('ul.menu li.expanded ul.menu:first').hide();
You can use the direct child selector ">".
e.g:
<script type="text/javascript">
$(function() {
//Hide the nested lists
$('ul.menu li.expanded ul.menu').hide();
//Change the destination of the header links
$('ul.menu li.expanded > a').attr("href", "javascript:void(null)");
//Toggle the display of the nested lists
$('ul.menu li.expanded > a').click(function() {
$(this).next().slideToggle('normal');
});
});
</script>

Categories