jQuery switch active class depending on which section is showing - javascript

I have several sections within a document as follows:
<section id="step1">
</section>
<section id="step2" style="display:none">
</section>
<section id="step3" style="display:none">
</section>
I am showing and hiding these depending on user interaction. I wanted to have some kind of circular heading to indicate the user is on section 2 of 3 for example like so:
<div id="indicators" class="clearfix">
<div class="center-div">
<ul>
<li id="step1-circle" class="circle active"></li>
<li id="step2-circle" class="circle"></li>
<li id="step3-circle" class="circle"></li>
</ul>
</div>
</div>
How would I switch the active class depending on which section is showing?

You can use the addClass() method in tandem with the removeClass() method like:
function makeIndicatorCircleActive(id){
// Remove active state of current circle
$('#indicators .active').removeClass('active');
// Add active state to desired element
$(id).addClass('active');
}
// Somewhere else in the code...
makeIndicatorCircleActive('#step2-circle);

I've added a button for the animation. You'd need to show more example code of your implementation, but you may be able to get away with let $section = $('section:visible') and instead of putting this in a click function, create a generic function name, which is triggered whenever your event occurs.
$('button').click(function() {
// context used for jQuery
let $section = $(this).closest('section');
// get next circle, if current circle is last, then get first circle
var $next = $('.circle.active', $section).next('.circle'),
$next = ($next.length && $next) || $('.circle', $section).first();
$('.circle.active', $section).removeClass('active'); // remove all actives
$next.addClass('active'); // add new active
});
.circle {
background: black;
border-radius: 25px;
display: inline-block;
list-style-type: none;
width: 50px;
height: 50px;
-moz-border-radius: 25px;
-webkit-border-radius: 25px;
}
.active {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<div class="clearfix">
<div class="center-div">
<ul>
<li class="circle active"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
</div>
<button>Next</button>
</div>
</section>
<section>
<div class="clearfix">
<div class="center-div">
<ul>
<li class="circle active"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
</div>
<button>Next</button>
</div>
</section>

Related

How can I make all elements work with onmouseover, onmouseout correctly?

My first go at making my own mini webpage from scratch, specifically looking to understand how onmouseover/onmouseout works using .display.opacity. I would like to hover my mouse over each element and it displays text specified text while the rest of the webpage disappears. Hope I gave enough information first time using StackOverflow.
my first element works perfectly with the function created showHilton().
however my second element and function "showInnovel();" does not
I currently have 3 elements and would like this to work with all if possible
<ul>
<li onmouseover="showHilton();" onmouseout="showHilton();"class="hiltonGrand" id="HGV">Hilton Grand Vacations</li>
<li id="hilton" style="opacity:0; background: black; color: white; text-align:right;">hello</li>
<li onmouseover="showInnovel();" onmouseout="showInnovel();"class="in" id="inSol">Innovel Solutions</li>
<li id="iS" style="opacity:0; background: black; color: white; text-align:right;">innovel</li>
<li class="DR" id="Dr">Diamond Resorts</li>
<li id="diamond" style="opacity:0; background: black; color: white; text-align:right;">Diamond</li>
</ul>
</div>
<div>
<!--Back button-->
<!--Home Button-->
<!--Customer Service-->
</div>
<script type="text/javascript">
var hilton = document.getElementById("hilton");
var innovel = document.getElementById("inSol");
var Dr = document.getElementById("Dr");
var hGV = document.getElementById("HGV");
var iS = document.getElementById("iS");
function showHilton() {
if(hilton.style.opacity == 0){
//element.style.display = "block";
hilton.style.opacity= 1;
innovel.style.opacity = 0;
Dr.style.opacity=0;
} else {
//element.style.display = "none";
hilton.style.opacity=0;
innovel.style.opacity=1;
Dr.style.opacity=1;
}
}
function showInnovel() {
if(iS.style.visibility == 0){
//element.style.display = "block";
iS.style.opacity = 1;
hGV.style.opacity = 0;
Dr.style.opacity=0;
} else {
//element.style.display = "none";
iS.style.opacity=0;
hGV.style.opacity=1;
Dr.style.opacity=1;
}
}
Your current setup uses a HTML structure like so:
<ul>
<li>Toggle 1</li>
<li>Content 1</li>
<li>Toggle 2</li>
<li>Content 2</li>
</ul>
This makes it quite hard to toggle the next element, whichc would require some js as you've already stated in your question.
I would re-work the html, to something like:
<ul>
<li>
Toggle 1
<p>Content 1</p>
</li>
<li>
Toggle 2
<p>Content 2</p>
</li>
</ul>
This way we can use native css to toggle the display property on the child elements to get the desired output:
/* Hide */
li > p {
display: none;
background: black;
color: white
}
/* Show on hover */
li:hover > p {
display: block;
}
<div>
<ul>
<li class="hiltonGrand" id="HGV">
Hilton Grand Vacations
<p>hello</p>
</li>
<li class="in" id="inSol">
Hilton Grand Vacations
<p>innovel</p>
</li>
<li class="DR" id="DR">
Hilton Grand Vacations
<p>Diamond</p>
</li>
</ul>
</div>
<div>
<!--Back button-->
<!--Home Button-->
<!--Customer Service-->
</div>

Switching between three classes with different names

I have a header and three different classes defines three different sizes. On click of the different buttons I need to apply the size class to the header and remove the existing heading size class.
JS Fiddle
<div class="row">
<div class="col-sm-12">
<div class="layout-attachments">
<ul class="list-inline layout-components">
<li class="list-inline-item"><a id="smallHeader">S</a></li>
<li class="list-inline-item"><a id="mediumHeader">M</a></li>
<li class="list-inline-item"><a id="largeHeader">L</a></li>
</ul>
<h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
</div>
jQuery:
this.$('.list-inline-item').click(function() {
if ($('.layout-attachments h1').hasClass('w-50-p')) {
$('.layout-attachments h1').removeClass('w-50-p').addClass('w-75-p ');
} else if ($('.layout-attachments h1').hasClass('w-75-p ')) {
$('.layout-attachments h1').removeClass('w-75-p ').addClass('w-100-p');
} else if ($('.layout-attachments h1').hasClass('w-100-p')) {
$('.layout-attachments h1').removeClass('w-100-p').addClass('w-50-p');
}
});
});
This is very easy. Here i made an example.
Make sure to read the comment and also have a look at attribute Size
var sizes= ["w-75-p", "w-100-p", "w-50-p" ]
$('.list-inline-item').click(function() {
sizes.forEach((item)=> $('.layout-attachments h1').removeClass(item) ); // reset the size.
// now Add the right Size
$('.layout-attachments h1').addClass($(this).attr("size"))
});
.w-50-p {
font-size: 18px;
}
.w-75-p {
font-size: 26px;
}
.w-100-p {
font-size: 34px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-12">
<div class="layout-attachments">
<ul class="list-inline layout-components">
<li class="list-inline-item" size="w-50-p"><a id="smallHeader">S</a></li>
<li class="list-inline-item" size="w-75-p"><a id="mediumHeader">M</a></li>
<li class="list-inline-item" size="w-100-p"><a id="largeHeader">L</a></li>
</ul>
<h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
</div>
</div>
There are a couple of issues with your code. For starters, you have a syntax error in your jQuery block. You also don't need spaces after your class names in the removeClass calls. But the biggest issue is you need to be able to determine if the user has clicked "small", "medium", or "large" in order to apply the correct class. Otherwise, if you make the other corrections I mentioned, as it is right now you will basically just be toggling through the three classes.
Here's how I might approach the problem, with click handlers for each of the list elements (small, medium, large):
this.$('.list-inline-item').click(function(e) {
if (e.target.id === "smallHeader") {
// handle small case
$(".layout-attachments h1").removeClass("w-75-p w-100-p").addClass("w-50-p");
} else if (e.target.id === "mediumHeader") {
// handle medium case
$(".layout-attachments h1").removeClass("w-50-p w-100-p").addClass("w-75-p");
} else if (e.target.id === "largeHeader") {
// handle large case
$(".layout-attachments h1").removeClass("w-50-p w-75-p").addClass("w-100-p");
} else {
// unhandled case
}
});
.w-50-p {
font-size: 18px;
}
.w-75-p {
font-size: 26px;
}
.w-100-p {
font-size: 34px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-12">
<div class="layout-attachments">
<ul class="list-inline layout-components">
<li class="list-inline-item"><a id="smallHeader">S</a></li>
<li class="list-inline-item"><a id="mediumHeader">M</a></li>
<li class="list-inline-item"><a id="largeHeader">L</a></li>
</ul>
<h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
</div>
</div>
Another thing you could do, instead of calling removeClass with the other classes you don't want attached to the element, is add a function to jQuery that will remove all classes according to some substring. For example, with this function, you could remove all classes starting with "w-":
$.fn.removeClassStartingWith = function (filter) {
$(this).removeClass(function (index, className) {
return (className.match(new RegExp("\\S*" + filter + "\\S*", 'g')) || []).join(' ')
});
return this;
};
You could invoke it then like this:
$(".layout-attachments h1").removeClassStartingWith("w-").addClass("w-50-p");
This is not absolutely necessary but might be useful.
You had some errors in your jQuery:
$('.list-inline-item').on('click', function() {
if ($('.layout-attachments h1').hasClass('w-50-p')) {
$('.layout-attachments h1').removeClass('w-50-p').addClass('w-75-p');
} else if ($('.layout-attachments h1').hasClass('w-75-p')) {
$('.layout-attachments h1').removeClass('w-75-p ').addClass('w-100-p');
} else if ($('.layout-attachments h1').hasClass('w-100-p')) {
$('.layout-attachments h1').removeClass('w-100-p').addClass('w-50-p');
}
});
But either way the code doesn't make much sense as it is, because it doesn't matter what li item you click.
Edit:
html:
<div class="row">
<div class="col-sm-12">
<div class="layout-attachments">
<ul class="list-inline layout-components">
<li class="list-inline-item" data-size="w-50-p"><a id="smallHeader">S</a></li>
<li class="list-inline-item" data-size="w-75-p"><a id="mediumHeader">M</a></li>
<li class="list-inline-item" data-size="w-100-p"><a id="largeHeader">L</a></li>
</ul>
<h1 id="w-75-p" class="img-responsive img-thumbnail">Change the class of this element</h1>
</div>
</div>
jQuery:
$('.list-inline-item').on('click', function() {
var newSize = $(this).attr("data-size");
$(".layout-attachments h1").removeAttr("id").attr("id", newSize)
});
css:
#w-50-p {font-size: 18px;}
#w-75-p {font-size: 26px;}
#w-100-p {font-size: 34px;}
The easiest was is to use an id on the target element and set a data attribute which refers to the correct id.
You can do this:
<div class="row">
<div class="col-sm-12">
<div class="layout-attachments">
<ul class="list-inline layout-components">
<li class="list-inline-item"><a id="smallHeader" data-new-class="w-50-p">S</a></li>
<li class="list-inline-item"><a id="mediumHeader" class="active" data-new-class="w-75-p">M</a></li>
<li class="list-inline-item"><a id="largeHeader" data-new-class="w-100-p">L</a></li>
</ul>
<h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
</div>
</div>
there is an class="active" and data-new-class="w-75-p" that track what is currently clicked and what class to apply when click. You can find a better name for the data attribute.
For javascript:
$('.list-inline-item a').click(function() {
var $activeSize = $('.list-inline-item a.active');
// removes active from current
$activeSize.removeClass('active');
var $heading = $('.layout-attachments h1')
//removes the class and add class you want
$heading.removeClass($activeSize.data('newClass'));
$heading.addClass($(this).data('newClass'));
//add active to the clicked one
$(this).addClass("active")
});
JS Fiddle
Maintain the class which alters the font size in the list item as a data attribute and add the new class to the target on click event!
Here is the working solution..
var $item = $('.list-inline-item'),
$target = $('.img-responsive.img-thumbnail');
$item.on('click', function() {
var size = $(this).find('a').data('size');
$target
.removeClass('w-50-p w-75-p w-100-p') // remove size classes
.addClass(size);
});
.w-50-p {
font-size: 1em;
}
.w-75-p {
font-size: 1.5em;
}
.w-100-p {
font-size: 2em;
}
.list-inline-item a {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-12">
<div class="layout-attachments">
<ul class="list-inline layout-components">
<li class="list-inline-item"><a data-size="w-50-p">S</a></li>
<li class="list-inline-item"><a data-size="w-75-p">M</a></li>
<li class="list-inline-item"><a data-size="w-100-p">L</a></li>
</ul>
<h1 class="img-responsive img-thumbnail w-75-p">Change the class of this element</h1>
</div>

Div will not automatically close when click inside item

Fiddle: https://jsfiddle.net/scrfbe95/
Right now im using a main div with a list of item with a link once you click a certein list item it will show another div on the right side of the main div.
But what im trying to do is when u click a certein link inside the main div the main div will not close.
<div id="main-div1" class="main-div">
Main div 1
<div class="content">
<ul>
<li> item 1 </li>
<li> item 1 </li>
</ul>
</div>
</div>
<div id="main-div2" class="main-div">
Main div 2
<div class="content">
<ul>
<li> item 1 </li>
<li> item 1 </li>
</ul> </div>
</div>
<div id="main-div3" class="main-div">
Main div 3
<div class="content">
<ul>
<li> item 1 </li>
<li> item 1 </li>
</ul> </div>
</div>
.main-div {
padding: 10px;
margin-top: 5px;
background-color: #000;
color: #fff;
}
.main-div > .content {
display: none;
color: #fff;
}
(function($) {
$(document).on('click','.main-div',function() { showMainDiv($(this)); });
function showMainDiv($el) {
var $elContent = $el.find('.content');
if ($elContent.is(':visible')) {
$elContent.stop(true,true).slideUp(500);
}
else {
$('.main-div').find('.content').stop(true,true).not($elContent).slideUp(500);
$elContent.slideDown(500);
}
}
})(jQuery);
Modify the click listener to only react if the div clicked is the intended div like this
$(document).on('click','.main-div',function(e) {
if (e.target !== this)
return;
showMainDiv($(this)); });
Here is the fiddle;

Menu bar Malfunctioning with AngularJs

I am bit new to AngularJs so I have got stuck into the problem.
Let me explain what I want to achieve.
I have design two div with child and parent relation.
// first parent div
<div>
<div>
child div // show/hide content of this div
</div>
</div>
// second parent div
<div>
<div>
child div // show/hide content of this div
</div>
</div>
When I hover or move the mouse over parent div it should hide/show the respective child div.
But with my code on hover it hides/shows the content of both the child div.What changes do I have to do in code?
See complete code
<body ng-app="app">
<div ng-app="headermain" ng-controller="headerController">
<div class="top-menu col-xs-36 ">
// parent div one
<div class="menu-item col-xs-6" ng-mouseover="hoverIn()" style="background-color:pink">
<span >Parent one</span>
// child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe" ng-mouseleave="hoverOut()" style="background-color:pink">
<ul>
<li>child one details</li>
<li>parent one detail</li>
</ul>
</div>
</div>
// parent div two
<div class="menu-item col-xs-6" ng-mouseover="hoverIn()">
<span >Parent two</span>
// child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe" ng-mouseleave="hoverOut()">
<ul>
<li>child two Details</li>
<li>parent two detail</li>
</ul>
</div>
</div>
</div>
</div>
Controller for this code, see below
var app = angular.module("app", []);
app.controller("headerController",function($scope){
$scope.hoverIn = function(){
this.showMe = true;
};
$scope.hoverOut = function(){
this.showMe = false;
};
});
Css file
.top-menu {
overflow: hidden;
}
.top-menu .drop-down {
position: absolute;
top: 20px;
z-index: 10000;
background-color: white;
box-shadow: 0px 0px 3px rgb(241, 241, 241);
border: 1px solid #d1d1d1;
}
.top-menu .drop-down ul {
padding: 0px;
margin: 0px;
list-style-type: none;
min-width: 180px;
}
You have to change the name of your functions since both div's are using the same function and changing the same attribute showMe.
HTML:
<body ng-app="app">
<div ng-app="headermain" ng-controller="headerController">
<div class="top-menu col-xs-36 ">
// parent div one
<div class="menu-item col-xs-6" ng-mouseover="hoverIn(1)" style="background-color:pink">
<span>Parent one</span> // child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe[1]" ng-mouseleave="hoverOut(1)" style="background-color:pink">
<ul>
<li>child one details</li>
<li>parent one detail</li>
</ul>
</div>
</div>
// parent div two
<div class="menu-item col-xs-6" ng-mouseover="hoverIn(2)">
<span>Parent two</span> // child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe[2]" ng-mouseleave="hoverOut(2)">
<ul>
<li>child two Details</li>
<li>parent two detail</li>
</ul>
</div>
</div>
</div>
</div>
JS:
$scope.showMe=[];
$scope.hoverIn = function(id) {
$scope.showMe[id] = true;
};
$scope.hoverOut = function() {
$scope.showMe[id] = false;
};

How to get a hidden content to show over cursor using html, css, javascript?

There are many words like this:
test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 ...
Each word is associated with multiple example sentences. And I want them to be hidden before the cursor is over the word. Here's my code.
DEMO: https://jsfiddle.net/kyubyong/umxf19vo/
HTML:
<a><b>test1</b></a>
<div class="divs">
<li>This is the first example</li>
<li>This is the second example</li>
<li>This is the third example</li>
</div>
<a><b>test2</b></a>
<div class="divs">
<li>This is the first example</li>
<li>This is the second example</li>
<li>This is the third example</li>
</div>
CSS
a:hover
{
background-color: lightgray;
}
.divs
{
display: none;
}
a:hover + .divs
{
display: block;
position: absolute;
background-color: lightgray;
width: 100%;
padding: 5px;
}
The problem is when the original line is more than one, the block of example sentences covers the words in the bottom line. I want them to go down so the example sentences don't cover them.
Since you're using the Javascript, HTML and CSS tags I'm assuming you don't mind using Javascript to solve the issue. The reason why your problem is happening is because you're using position: absolute on your <div>'s. This means that the position will be positioned in absolute terms relative to it's ancestor element.
What you could do instead is palce all the titles first and then all the lists and then use javasript to select the appropiate element to show/hide. Below you can find an example of how to do it with jQuery.
$('div').hover(function() {
$($(this).attr("target")).toggle();
}, function() {
$($(this).attr("target")).toggle();
});
div {
display: inline;
background: lightgray;
}
div:hover {
background: darkgray;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div target="#test">Test</div>
<div target="#animals">Animals</div>
<div target="#fruits">Fruits</div>
<div target="#vegetables">Vegetables</div>
<div target="#cars">Cars</div>
<div target="#countries">Countries</div>
<div target="#continents">Continents</div>
<div target="#sports">Sports</div>
<div id="test" class="hidden">
<ul>
<li>Test 1</li>
<li>Test 2</li>
<li>Test 3</li>
</ul>
</div>
<div id="animals" class="hidden">
<ul>
<li>Lion</li>
<li>Tiger</li>
<li>Gazzele</li>
</ul>
</div>
<div id="fruits" class="hidden">
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Orange</li>
</ul>
</div>
<div id="vegetables" class="hidden">
<ul>
<li>Potatoe</li>
<li>Tomatoe</li>
<li>Lettuce</li>
</ul>
</div>
<div id="cars" class="hidden">
<ul>
<li>Ferrari</li>
<li>Porsche</li>
<li>Audi</li>
</ul>
</div>
<div id="countries" class="hidden">
<ul>
<li>United States</li>
<li>Canada</li>
<li>Mexico</li>
</ul>
</div>
<div id="continents" class="hidden">
<ul>
<li>America</li>
<li>Europe</li>
<li>Africa</li>
</ul>
</div>
<div id="sports" class="hidden">
<ul>
<li>Tennis</li>
<li>Football</li>
<li>Basketball</li>
</ul>
</div>
If you add a margin-top to the block of example sentences then it will go down
a:hover + .divs
{
display: block;
position: absolute;
background-color: lightgray;
width: 100%;
padding: 5px;
margin-top: 20px;
}
Updated fiddle link https://jsfiddle.net/umxf19vo/1/
Here, i used a jquery mouseover function for this
$(document).ready(function(){
$(".test").mouseover(function(){
if($(".test").find(".divs").hasClass("divs-hover")){
$(".test").find(".divs").removeClass("divs-hover");
$(".test").find("a").css("background-color","transparent");
}
$(this).find(".divs").addClass("divs-hover");
$(this).find("a").css("background-color","lightgray");
})
$(".test").mouseleave(function(){
$(".test").find(".divs").removeClass("divs-hover");
$(".test").find("a").css("background-color","transparent");
})
})
i don`t know if can make this with only css, but u can make with this way
https://jsfiddle.net/umxf19vo/14/

Categories