Hiding and displaying content with jQuery - javascript

I'm trying to change the content on a page depending on which link is clicked. My problem is that once the content for a link is displayed it wont disappear if another link is clicked even if I have set it to display none when the other link is clicked. The display: block is overwriting the display: none.
For those of you suggesting I use .show() and .hide() I appreciate your help but I don't think this method will be best for me as I need to add a class to the elements so I can animate it later. Thanks
jQuery(document).ready(function() {
jQuery('#link_one').click(function() {
jQuery('#about_us').addClass('hide');
jQuery('#why_us').addClass('hide');
jQuery('#our_prods').addClass('hide');
jQuery('#accreditations').addClass('show');
});
jQuery('#link_two').click(function() {
jQuery('#why_us').addClass('hide');
jQuery('#accreditations').addClass('hide');
jQuery('#our_prods').addClass('hide');
jQuery('#about_us').addClass('show');
});
jQuery('#link_three').click(function() {
jQuery('#about_us').addClass('hide');
jQuery('#our_prods').addClass('hide');
jQuery('#accreditations').addClass('hide');
jQuery('#why_us').addClass('show');
});
});
nav {
width: 100%;
text-align: center;
}
nav ul {
list-style-type: none;
}
nav ul li {
display: inline-block;
}
nav ul li a {
font-size: 40px;
margin: 0 10px;
}
p {
font-size: 30px;
font-weight: bold;
}
div {
width: 100%;
text-align: center;
}
.hide {
display: none;
}
.show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul>
<li><a id="link_one" href="#">link 1</a></li>
<li><a id="link_two" href="#">link 2</a></li>
<li><a id="link_three" href="#">link 4</a></li>
</ul>
</nav>
<div id="about_us">
<p>About Us Page - to be displayed by default</p>
</div>
<div id="accreditations">
<p>Accreditations Page Content - Link 1</p>
</div>
<div id="our_prods">
<p>Our products - Link 2</p>
</div>
<div id="why_us">
<p>Why us content - link 3</p>
</div>
https://codepen.io/Reece_Dev/pen/gWdEoJ

what I'd do and recommend doing:
HTML
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
<div class="pageContainer" id="uniqueID">
<!-- content -->
</div>
jQuery
$(document).ready(function()
{
$('.link').on('click', function()
{
$('.pageContainer').addClass('hide');
$('#'+ $(this).data('target')).removeClass('hide');
});
});
what this will do is, when anything with class .link is clicked, add a class ('hide') to all elements that have the class .pageContainer. Then it will remove the class from the div with the id that matches the target (a console.log of the $('#'+ $(this).data('target')) should result in $('#why_us') - if the why_us link was clicked
data is an attribute you can attach to elements, data-* - * can be anything you want, but makes more sense to call it something related. calling .data() will get an array of all available data tags on the element, doing .data('string') will get the data element that matches data-string.
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/data-*

With your actual code you are not toggling the hide and show classes correctly.
You can just use jQuery .hide() and .show() methods, instead of adding and removing classes:
$(document).ready(function() {
$('#link_one').click(function() {
$('#about_us').hide();
$('#why_us').hide();
$('#our_prods').hide();
$('#accreditations').show();
});
$('#link_two').click(function() {
$('#why_us').hide();
$('#accreditations').hide();
$('#our_prods').hide();
$('#about_us').show();
});
$('#link_three').click(function() {
$('#about_us').hide();
$('#our_prods').hide();
$('#accreditations').hide();
$('#why_us').show();
});
});
Demo:
$(document).ready(function() {
$('#link_one').click(function() {
$('#about_us').hide();
$('#why_us').hide();
$('#our_prods').hide();
$('#accreditations').show();
});
$('#link_two').click(function() {
$('#why_us').hide();
$('#accreditations').hide();
$('#our_prods').hide();
$('#about_us').show();
});
$('#link_three').click(function() {
$('#about_us').hide();
$('#our_prods').hide();
$('#accreditations').hide();
$('#why_us').show();
});
});
nav {
width: 100%;
text-align: center;
}
nav ul {
list-style-type: none;
}
nav ul li {
display: inline-block;
}
nav ul li a {
font-size: 40px;
margin: 0 10px;
}
p {
font-size: 30px;
font-weight: bold;
}
div {
width: 100%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul>
<li><a id="link_one" href="#">link 1</a></li>
<li><a id="link_two" href="#">link 2</a></li>
<li><a id="link_three" href="#">link 4</a></li>
</ul>
</nav>
<div id="about_us">
<p>About Us Page - to be displayed by default</p>
</div>
<div id="accreditations">
<p>Accreditations Page Content - Link 1</p>
</div>
<div id="our_prods">
<p>Our products - Link 2</p>
</div>
<div id="why_us">
<p>Why us content - link 3</p>
</div>

use jquery show hide function instead of addClass. as when you add hide class to already added show element, display block will override display none. instead use this.
jQuery('#link_one').click(function() {
jQuery('#about_us').hide();
jQuery('#why_us').hide();
jQuery('#our_prods').hide();
jQuery('#accreditations').show();
});
jQuery('#link_two').click(function() {
jQuery('#why_us').hide();
jQuery('#accreditations').hide();
jQuery('#our_prods').hide();
jQuery('#about_us').show();
});
jQuery('#link_three').click(function() {
jQuery('#about_us').hide();
jQuery('#our_prods').hide();
jQuery('#accreditations').hide();
jQuery('#why_us').show();
});

Your problem is that you're never removing the class, so once you click a link it has both the hide and show classes. And because the show class is later in your css, it overrides the hide class.
You can add .removeClass('show') at the end of your changes. Like
jQuery('#our_prods').addClass('hide').removeClass('show');
An easier method might be to use the show() and hide() jQuery methods, and not worry about swapping the classes.
jQuery('#link_two').click(function() {
jQuery('#why_us').hide();
jQuery('#accreditations').hide();
jQuery('#our_prods').hide();
jQuery('#about_us').show();
});

The issue is that you're now removing the class show when you're trying to hide the content.
Also, the better way to that is by using the jquery hide and show functions.
The script changes to this :
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('#link_one').click(function() {
jQuery('.content').hide()
jQuery('#accreditations').show()
});
jQuery('#link_two').click(function() {
jQuery('.content').hide()
jQuery('#our_prods').show()
});
jQuery('#link_three').click(function() {
jQuery('.content').hide()
jQuery('#why_us').show()
});
});
</script>
And we added a class content to the page containers.
<nav>
<ul>
<li><a id="link_one" href="#">link 1</a></li>
<li><a id="link_two" href="#">link 2</a></li>
<li><a id="link_three" href="#">link 4</a></li>
</ul>
</nav>
<div id="about_us" class="content show">
<p>About Us Page - to be displayed by default</p>
</div>
<div id="accreditations" class="content">
<p>Accreditations Page Content - Link 1</p>
</div>
<div id="our_prods" class="content">
<p>Our products - Link 2</p>
</div>
<div id="why_us" class="content">
<p>Why us content - link 3</p>
</div>
The updated Css :
<style type="text/css">
nav {
width: 100%;
text-align: center;
}
nav ul {
list-style-type: none;
}
nav ul li {
display: inline-block;
}
nav ul li a {
font-size: 40px;
margin: 0 10px;
}
p {
font-size: 30px;
font-weight: bold;
}
div {
width: 100%;
text-align: center;
}
.content{
display: none;
}
.show{
display: block;
}
</style>

Related

Read More Function for unordered list using jQuery with Paragraph

I'm a beginner, and trying to understand everything. I tried using <p> and it works smoothly but when I insert a text like a ul and li it wont show up
I also tried using a div but only the <a> part is working not the ul and li. I hope someone can help me.
$(document).ready(function() {
$(".more-less").click(function() {
$(this).parent().prev('ul.more').toggleClass("main");
if ($(this).parent().prev('ul.more').hasClass('main')) {
$(this).text('Read Less');
} else {
$(this).text('Read More');
}
});
});
.more {
text-align: left !important;
display: none;
}
.more-less {
/* position: absolute; */
/* right: -30px; */
/* top: -34px; */
color: #e43330 !important;
text-align: center;
float: left;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<p style="text-align: left;">First paragraph then cuts...
<p class="more">Second paragraph.</p>
<p><strong>Header key roles</strong></p>
<ul class="more">
<li>trait 1</li>
<li>trait 2</li>
<li>trait 3</li>
<li>trait 4</li>
<li>trait 5</li>
</ul>
<a class="more-less">Read More</a>
<p> end paragraph</p>
strong text
There's two main issues in your code. Firstly the ul.more is not a parent element of the clicked p, so parents().next() isn't the correct traversal logic to use. As the target element is a sibling of the one which raised the event, use siblings().
Secondly, you need to set display: block on the hidden ul. You can do this through CSS, on the .main class which you toggle.
Also note that you cannot nest p elements. I corrected this in the example below by converting the containing element to a div.
jQuery($ => {
$(".more-less").click(function() {
let $more = $(this).siblings('ul.more').toggleClass("main");
if ($more.hasClass('main')) {
$(this).text('Read Less');
} else {
$(this).text('Read More');
}
});
});
.more {
text-align: left !important;
display: none;
}
.more.main {
display: block;
}
.more-less {
color: #e43330 !important;
text-align: center;
float: left;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div>
First paragraph then cuts...
<p class="more">Second paragraph.</p>
<p><strong>Header key roles</strong></p>
<ul class="more">
<li>trait 1</li>
<li>trait 2</li>
<li>trait 3</li>
<li>trait 4</li>
<li>trait 5</li>
</ul>
<a class="more-less">Read More</a>
<p> end paragraph</p>
</div>
Try delete display: none; from more class

<nav> element moves out of parent when having <a> element as a child

So I was modifying HTML to make drop down panels in order to minimize use of JavaScript.
.nav-link {
border: 1px solid black;
margin: 10px;
text-decoration: none;
}
.panel-link {
display: none;
position: absolute;
}
.nav-link:hover .panel-link {
display: block;
}
<nav class="nav">
<a href="withoutchild.html" class="nav-link">
<span>Without Child</span>
<nav class="panel-link">
<h1>Works</h1>
</nav>
</a>
<a href="withchild.html" class="nav-link">
<span>With Child</span>
<nav class="panel-link">
<a>Not Works</a>
</nav>
</a>
</nav>
When you hover both of them, you notice that only the first link opens its drop down panel when you hover it. However, with the second link (Which was layed out exactly the same), it did not because it had a link element as the child. When I view the inspector of Chrome, I realized the '.panel-link' element moved out of the '.nav-link' element, and is now a sibling of '.nav-link'. which looked just like this:
<nav class="nav">
<a href="withoutchild.html" class="nav-link">
<span>Without Child</span>
<nav class="panel-link">
<h1>Works</h1>
</nav>
</a>
<a href="withchild.html" class="nav-link">
<span>With Child</span>
</a>
<!-- This element is moved outside its parent -->
<nav class="panel-link">
<a>Not Works</a>
</nav>
</nav>
Nested <a> (anchor tags) are illegal and result in unrecoverable errors.
In plain English, browsers ignore all contents of the nested <a>, until they meet the end of this tag (</a>), which they use to close the parent <a> tag.
Use the HTML validator of your choice for more details. I use nu.
I think the issue is that you have an <a> tag within a parent <a> tag.
I'm not sure what you wanted the <h1> text/link to look like so kept it in anyway. Using CSS, hovering a div can reveal another div.
.panel-link {
border: 1px solid black;
margin: 10px;
text-decoration: none;
}
.nav-link {
position: relative;
display: inline-block;
}
.nav-link-content {
display: none;
position: absolute;
z-index: 1;
}
.nav-link-content a {
color: black;
padding: 2px 16px;
display: block;
}
.nav-link-content a:hover {
background-color: #fff000
}
.nav-link:hover .nav-link-content {
display: block;
}
<nav class="nav">
<div class="nav-link">
<span>Without Child</span>
<div class="nav-link-content">
<h1>Works</h1>
</div>
</div>
<div class="nav-link">
<span>With Child</span>
<div class="nav-link-content">
Child 1
Child 2
Child 3
</div>
</div>
</nav>

How can i make my jQuery code work on all elements

I have this accordion menu but it only works on the first ul. How do I get it to work on all ul like this? If you could explain what I'm doing wrong so I know in the future that would be great.
Also, how do I get it so that the link toggles between two classes, right and down each time it is clicked? It also has the class turq-font on it. I want the right to be removed and replaced with down when the link is clicked and the menu is showing. Heres my code:
$(function() {
$("#show-menu").click(function() {
$("#sub-menu-acc").toggleClass("active-menu", 1000);
});
});
.active-menu {
display: block !important;
}
.admin-area ul li {
margin: 6px 0px;
}
.admin-right-menu ul li a {
color: black;
text-decoration: none;
}
.admin-area ul {
list-style: none;
margin-bottom: 20px;
}
.admin-area ul li ul {
display: none;
padding-left: 20px;
margin-bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="admin-area">
<div class="admin-right-menu">
<ul>
<li>Stats >
<ul id="sub-menu-acc">
<li>Business Stats
</li>
<li>Affiliate stats
</li>
</ul>
</li>
<li>Reports >
<ul id="sub-menu-acc">
<li>Global
</li>
<li>Sales
</li>
<li>Sales trends
</li>
</ul>
</li>
</ul>
</div></div>
The issue is due to your use of repeated id attributes; they should be unique within a document. Convert your code to use classes instead.
Also note that you should use the this keyword to traverse the DOM to find the ul related to the clicked a element, and the addition of right down in a toggleClass() call. Try this:
$(function() {
$(".show-menu").click(function(e) {
e.preventDefault(); // stop the '#' of the clicked a appearing in the URL
$(this).toggleClass('right down').next(".sub-menu-acc").toggleClass("active-menu");
});
});
.active-menu {
display: block !important;
}
.admin-area ul li {
margin: 6px 0px;
}
.admin-right-menu ul li a {
color: black;
text-decoration: none;
}
.admin-area ul {
list-style: none;
margin-bottom: 20px;
}
.admin-area ul li ul {
display: none;
padding-left: 20px;
margin-bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="admin-area">
<ul>
<li>
Stats >
<ul class="sub-menu-acc">
<li>
Business Stats
</li>
<li>
Affiliate stats
</li>
</ul>
</li>
<li>
Reports >
<ul class="sub-menu-acc">
<li>
Global
</li>
<li>
Sales
</li>
<li>
Sales trends
</li>
</ul>
</li>
</ul>
</div>

Div toggle animation

Complete js newbie here, so sorry if im asking a stupid question :)
I have a navigation that toggles several divs, each link opens its own div, like this:
<div class="drawer" id="link1" style="display: none">First link content</div>
<div class="drawer" id="link2" style="display: none">Second link content</div>
<div class="drawer" id="link3" style="display: none">Third link content</div>
<nav>
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>External link</li>
</ul>
</nav>
And the code that runs it:
$(document).ready(function () {
$('.menu').click(function () {
var $clicked = $(this)
$('.menu').each(function () {
var $menu = $(this);
if (!$menu.is($clicked)) {
$($menu.attr('data-item')).hide();
}
});
$($clicked.attr('data-item')).toggle();
});
});
It works well, but instead of simple showing/disappearing, i would wish to have slide up/down toggle effect on the divs when they are triggered.
I know there are slideUp and slideDown effects, but like i said, i am very new to all this and i cant make it work.
Fiddle is at http://jsfiddle.net/15kene5v/ and if anybody can help, that would be great.
Use slideUp and slideToggle instead of hide and toggle.
Updated Fiddle
$(document).ready(function() {
$('.menu').click(function() {
var $clicked = $(this)
$('.menu').each(function() {
var $menu = $(this);
if (!$menu.is($clicked)) {
// Use slideUp here
$($menu.attr('data-item')).slideUp('slow');
}
});
// Use sildeToggle here
$($clicked.attr('data-item')).slideToggle('slow');
});
});
nav ul {
margin: 0;
padding: 0;
background-color: #6DB4F3;
text-align: center;
}
nav ul li {
display: inline-block;
margin: 10px;
}
nav ul li a {
color: white;
text-decoration: none;
}
.drawer {
height: 100px;
background-color: darkorange;
color: white;
text-align: center;
position: relative;
}
.drawer:after {
content: 'close';
left: 0;
top: 0;
position: absolute;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="drawer" id="link1" style="display: none">First link content</div>
<div class="drawer" id="link2" style="display: none">Second link content</div>
<div class="drawer" id="link3" style="display: none">Third link content</div>
<nav>
<ul>
<li>Link 1
</li>
<li>Link 2
</li>
<li>Link 3
</li>
<li>External link
</li>
</ul>
</nav>
<div style="display:block">Content that gets pushed down</div>

CSS Menu disappear

I created a menu in html/css but where I wanted the subitems to be shown on parent item hover. The problem is when I hover on it in IE it only shows it's subitems when I hover on the text in the menu item, If I hover over the element and not the text the subitems disappear again. So if I hover and want to move my mouse to my submenu the submenu disappears unless I'm fast enough. This is very annoying, does anyone know how I can solve this?
MY menu code is like so:
<ul id="leftnav">
<li><a>Item1</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
<li><a>Item2</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</ul>
The menu should be a left sided menu which shows it's subitems only on hover, so I used css to achieve this with the following code:
#leftnav, #leftnav ul
{
padding: 0;
margin: 0;
}
#leftnav ul li
{
margin-left: 102px;
position: relative;
top: -19px; /*sets the childitems on the same height as the parent item*/
}
#leftnav li
{
float: left;
width: 100px;
}
#leftnav ul
{
position: absolute;
width: 100px;
left: -1000px; /*makes it disappear*/
}
#leftnav li:hover ul, #leftnav li.ie_does_hover ul
{
left: auto;
}
#leftnav a
{
display: block;
height: 15px;
margin-top: 2px;
margin-bottom: 2px;
}
Since this only works with firefox I also had to insert a javascript to get this to work in IE using code:
<script language="JavaScript">
sfHover = function()
{
var sfElsE = document.getElementById("leftnav").getElementsByTagName("LI");
for (var i=0; i<sfElsE.length; i++)
{
sfElsE[i].onmouseover=function()
{
this.className+=" ie_does_hover";
}
sfElsE[i].onmouseout=function()
{
this.className=this.className.replace(new RegExp(" ie_does_hover\\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
</script>
Many many many thanks for replies
In your CSS you have:
#leftnav li:hover ul
Which would mean the rule is applied to ul elements that are children of li elements when that parent li is hovered.
But in your HTML, you have:
<li><a>Item2</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
</ul>
So the sub item ul is not a child of the item ul, so that rule never comes true. You need to make the sub-items nested to the items. Like this:
<ul id="leftnav">
<li><a>Item1</a>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</li>
<li><a>Item2</a>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</li>
</ul>
Notice how I don't close the list item until after the sub-list.
Reinventing the wheel: http://www.htmldog.com/articles/suckerfish/ teaches you about it. They even have a great example.

Categories