Jquery Menu icon changes only works after reload - javascript

I'm trying to implement a 'slide toggle menu' and I would like that the menu icon changes to 'close' every time the menu icon is clicked to open, and goes back to normal every time the menu icon is clicked to close. But it works only when I reload the page. After that, the icon is always the same: normal (not X).
Can you help me to find the problem?
/* Mobile navigation */
$(function() {
if ($(window).width() < 980) {
var nav = $('.js--mobile-nav');
nav.hide();
}
});
$('.js--mobile-nav-icon').click(function() {
var nav = $('.js--mobile-nav');
var icon = $('.js--mobile-nav-icon i');
nav.slideToggle(200);
if (icon.hasClass('icon ion-md-rainy')) {
icon.addClass('icon ion-md-restaurant');
icon.removeClass('icon ion-md-rainy');
} else {
icon.addClass('icon ion-md-rainy');
icon.removeClass('icon ion-md-restaurant');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sec1" id="sec1">
<div class="header">
<div class="logo-img"><img src="img/logo_small.png" alt="Logo Thais Fachini" class="logo-img"></div>
<!-- Sticky Navigation -->
<div class="logo-img-sticky">
<img src="img/logo_small.png" alt="Logo Thais Fachini" class="logo-img-sticky">
</div>
<div class="logo-name">
<h1>THAÍS FACHINI</h1>
<p>Nutrition for Life</p>
</div>
<!-- Sticky Navigation -->
<div class="logo-name-sticky">
<h1>THAÍS FACHINI</h1>
<p>Nutrition for Life</p>
</div>
<div class="links">
<!-- Mobile Navigation --><a class="mobile-nav-icon js--mobile-nav-icon"><i class="icon ion-ios-menu"></i></a>
<nav class="js--mobile-nav">
Sobre
Como funciona
Assinar
Cliente
</nav>
</div>
</div>

I end up changing the code like this (I thought it was because of hasClass wasn't recognized). The code works.
$(function() {
var menu = false;
if ($(window).width() < 980){
var nav = $('.js--mobile-nav');
nav.hide();
}
$('.js--mobile-nav-icon').click(function() {
var nav = $('.js--mobile-nav');
var icon = $('.js--mobile-nav-icon i');
nav.slideToggle(200);
if (menu) {
icon.removeClass('icon ion-ios-close');
icon.addClass('icon ion-ios-menu');
} else {
icon.removeClass('icon ion-ios-menu');
icon.addClass('icon ion-ios-close');
}
menu = !menu;
});
});

Related

Adaptive vanilla JS pagebrowser for dynamically generated content

as a JS noob I'm stuck right now and would highly appreciate some help. My goal is to have a JS pagebrowser that works with content generated by my CMS (TYPO3). Content of different pages is rendered in divs with speaking ids; below you have links to these anchors plus a "show all" link. When you klick on a link to a "page" the respective page content div is shown and the others are hidden; if you click on "show all" all the page content divs are shown. However, if I click a page link after having clicked "show all" not all of the other page content divs are hidden as they should. I guess it has something to do with JS processing order but couldn't find out so far.
window.onload = function () {
var pagelinks = document.querySelectorAll("a.subpage-toggle");
for (var i = 0; i < pagelinks.length; i++) {
pagelinks[i].onclick = function () {
// Finding all elements of class 'active' (creates an array of results)
let x = document.getElementsByClassName("active");
// If class 'active' exists, remove it.
if (x.length > 0) {
x[0].classList.remove("active");
}
if ((this.href.split("#")[1]) !== "show-all") {
// add class 'active' if ID matches href of link
document.querySelector("#" + this.href.split("#")[1]).classList.add("active");
} else {
var subpagecontents = document.getElementsByClassName("subpage-content"),
len = subpagecontents !== null ? subpagecontents.length : 0,
j = 0;
for (j; j < len; j++) {
subpagecontents[j].classList.add("active");
}
}
};
}
};
.subpage-toggle {
display: block;
}
.subpage-content {
display: none;
}
.subpage-content.active {
display: block;
}
<div class="main">
<div id="name-of-page-one" class="subpage-content active">
<p>
Content Page 1
</p>
</div>
<div id="page-two-is-cool" class="subpage-content">
<p>
Content Page 2
</p>
</div>
<div id="nickname-of-page-three" class="subpage-content">
<p>
Content Page 3
</p>
</div>
<div class="pageoverview">
<ul>
<li><a class="subpage-toggle" href="#name-of-page-one">Name of page one</a></li>
<li><a class="subpage-toggle" href="#page-two-is-cool">Page two is cool</a></li>
<li><a class="subpage-toggle" href="#nickname-of-page-three">Nickname of page three</a></li>
</ul>
<a class="subpage-toggle" href="#show-all">Show all</a>
</div>
</div>
JSFiddle: https://jsfiddle.net/Jaydot/62cx5sh0/14/
You need to hide all the previous showing instead of just the first one:
Instead of
x[0].classList.remove("active");
do:
Array.from(x).forEach((element) => element.classList.remove("active"));
https://jsfiddle.net/nvg2aojb/

I have a page with a non-scrollabe left side-bar and a scrollable right container. I want to add a "go to top" button in the container

I have written the code so that it will show up after the page is scrolled 20px. But with this code the button does not show up. The problem here is that when the side-bar and container both are scrolled, the button works fine. I want it to work when only the right container is scrolled
//go to top button
var topBtn = document.getElementById('top');
var contain = document.getElementsByClassName('container').scrollTop;
window.onscroll = function(){
scrollFunction()
};
function scrollFunction(){
if (document.contain > 20){
topBtn.style.display = 'block';
}
else{
topBtn.style.display = 'none';
}
}
function goToTop(){
document.contain = 0;
document.documentElement.scrollTop = 0;
}
topBtn.addEventListener('click', goToTop);
<div class="wrapper">
<nav role="navigation" id="nav">
<img class="profile-img" src="images/profile-photo-new.jpg" alt="" />
About
Experience
Education
Skills
Interests
Certificates
</nav>
<div class="container">
<div id="about" class="mtb about-fixed-nav">
<h1 class="heading about-head">
<span>Pratit</span>
Bangdiwala
</h1>
Top
</div>
</div>
<script src="custom.js"></script>
</body>
</html>
No need Javascript
Use this
Top
Use the Id of top element of your page as "href" value
Like "nav"

Javascript Hide div on page load toggle between buttons

I know this has been asked, but I cannot figure out how to fix my issue. I have 2 buttons a drink menu and a food menu. I'm able to correctly show the different menus show when their button is clicked. However when the page loads the drink menu appears below the food menu. Once I click food menu buttons the drink menu disappears,and the buttons function as you would expect ie. one menu is shown while the other one is not. I'm not sure what the best method is to hide the drink menu. Any help would be much appreciated.
<button onclick="javascript:toggle('foodMenu')" class="btnMenu">Food</button>
<button onclick="javascript:toggle('drinkMenu')" class="btnMenu">Drink</button>
<div id="foodMenu">
<h1 class="menuHD">Food Menu</h1>
</div>
<div id="drinkMenu">
<h1>Drink Menu</h1>
</div>
var divs = [ "foodMenu", "drinkMenu" ];
function toggle(layer) {
var d
for(var i = 0; i < divs.length; i += 1) {
d = document.getElementById(divs[i]);
d.style.display = 'none';
}
}
I rewrote your script some. I used a class of menu to reference the divs and to set them default to be hidden.
Its also setup to hide any div not selected but only show the selected div.
var divs = [ "foodMenu", "drinkMenu" ];
function toggle(layer) {
var _menus = document.getElementsByClassName("menu");
for(var i = 0; i < _menus.length; i++) {
_menu = _menus[i];
_menu.style.display = 'none';
}
var _menu = document.getElementById(layer);
_menu.style.display = 'block';
}
.menu{
display:none;
}
<button onclick="javascript:toggle('foodMenu')" class="btnMenu">Food</button>
<button onclick="javascript:toggle('drinkMenu')" class="btnMenu">Drink</button>
<div class="menu" id="foodMenu">
<h1 class="menuHD">Food Menu</h1>
</div>
<div class="menu" id="drinkMenu">
<h1>Drink Menu</h1>
</div>
You can toggle by default the food menu, so every time you click a button, you color its text with red, so you know it is selected: its corresponding menu block will show.
Your HTML code:
<button onclick="javascript:toggle('foodMenu')" class="btnMenu" id="foodMenu-btn">Food</button>
<button onclick="javascript:toggle('drinkMenu')" class="btnMenu" id="drinkMenu-btn">Drink</button>
<div id="foodMenu">
<h1 class="menuHD">Food Menu</h1>
</div>
<div id="drinkMenu">
<h1>Drink Menu</h1>
</div>
Your JavaScript code:
// available menu divs
let divs = ["foodMenu", "drinkMenu"];
function toggle(layer) {
// reset all buttons and divs
for (let i = 0; i < divs.length; i += 1) {
let d = document.getElementById(divs[i]);
d.style.display = 'none';
// reset all buttons text colors
let b = document.getElementById(divs[i] + '-btn');
b.style.color = 'black';
}
// set current menu visible
let menu = document.getElementById(layer);
menu.style.display = 'block';
// set current menu button colored "red"
let btn = document.getElementById(layer + '-btn');
btn.style.color = 'red';
}
// select food menu by default
toggle('foodMenu')
I added style="display:none" to the second div in your first block of code. So when the page loads it will display the food Menu.
<button onclick="javascript:toggle('foodMenu')" class="btnMenu">Food</button>
<button onclick="javascript:toggle('drinkMenu')" class="btnMenu">Drink</button>
<div id="foodMenu">
<h1 class="menuHD">Food Menu</h1>
</div>
<div id="drinkMenu" style="display:none">
<h1>Drink Menu</h1>
</div>
For the javascript part use the following code. It will toggle between displaying the food and drink menu.
function toggle(layer) {
const hidingDiv = (layer == 'foodMenu') ? 'drinkMenu' : 'foodMenu';
document.getElementById(layer).style.display = 'block';
document.getElementById(hidingDiv).style.display = 'none';
}

JS PopUp windows from different sources

I need make a simple JS popup to view specific content of each link (team stats). For that I've got basic HTML set up which should popup mentioned content.
<!-- Start Team-Players -->
<div class="team-players">
<div class="player-profile">
<img data-js="open" src="img/team-ico/team-srsne.jpg" alt="" class="thumbnail">
<span class="number">#1</span>
<span class="name">HK Sršňe Košice</span>
</div>
<div class="player-profile">
<img data-js="open" src="img/team-ico/team-kvp.jpg" alt="" class="thumbnail">
<span class="number">#2</span>
<span class="name">HK KVP Represent</span>
</div>
<div class="player-profile">
<img data-js="open" src="img/team-ico/team-warriors.jpg" alt="" class="thumbnail" >
<span class="number">#3</span>
<span class="name">HK Spartan Warriors</span>
</div>
etc...
at the end there is popup opening code:
<div class="container">
<button data-js="open">Open popup</button>
<div class="popup">
<h2>$team_name (team name, which was selected for links above should be displayed)</h2>
<button name="close">Close popup</button>
JavaScript code:
function popupOpenClose(popup) {
/* Add div inside popup for layout if one doesn't exist */
if ($(".wrapper").length == 0){
$(popup).wrapInner("<div class='wrapper'></div>");
}
/* Open popup */
$(popup).show().this;
/* Close popup if user clicks on background */
$(popup).click(function(e) {
if ( e.target == this ) {
if ($(popup).is(':visible')) {
$(popup).hide();
}
}
});
/* Close popup and remove errors if user clicks on cancel or close buttons */
$(popup).find("button[name=close]").on("click", function() {
if ($(".formElementError").is(':visible')) {
$(".formElementError").remove();
}
$(popup).hide();
});
}
$(document).ready(function () {
$("[data-js=open]").on("click", function() {
popupOpenClose($(".popup"));
});
});
Could someone help me and advise how can I sort those links to open popup window related to each link? Maybe sort it with some ID or so?
Appreciate
I have 2 solutions:
in html create hidden popups for all teams with id="popup-team-1", and in your link add additional attribute <a data-id="1".. , in javascript do something like this:
var id = $(this).attr("data-id");
$("#popup-team-"+id).show();
load content of popup from server
$.get(url).done(function (content) {
$(".popup").html(content).show();
})

jQuery.trigger => Selector:toggle on Cloned Element = Loop

On Cloned menu (.original / .cloned ) i have problem getting 1 of the 2 toggle functions to work correctly.
Part #1 Cloned Menu Toggle
$('.mobile-nav-toggle').click(function(e) {
e.preventDefault();
var $this = $('a');
if ($this.hasClass('open')) {
$this.trigger('mobilenav:close', [$this, 'close']);
} else {
$this.trigger('mobilenav:close', [$this, 'open']);
}
// Guess this one get executed twice
$this.trigger('mobilenav:toggle', [$this]);
});
Part #2 Cloned Menu Toggle
$(document).on('mobilenav:toggle', function(e, $obj) {
$('.original>div>nav').toggleClass('open').slideToggle(300);
$('.cloned>div>nav').toggleClass('open').slideToggle(300);
$obj.toggleClass('close');
});
I understand the issue is that am using $('a') as my selector make mobilenav:toggle trigger twice and then it will loop around opening and closing the two menus.
On the other hand the mobile-nav-toggle icon don't loop and syncs correctly, menu drawer is in sync but looping.
If i change
$this = $('a');
// To
$this = $(this);
Everything will work except toggle icon that will not be in sync.
Have given this a couple of hours now and my macro level of Javascript / jQuery is just to weak as probably can be seen on my half ass solution on Part #2.
Watch my masterpiece in action!
Help me do this as a pro !
Edit: Adding rest of code from Sticky / cloning function after request
$('.menu').addClass('original').clone().insertAfter('.menu').addClass('cloned').css('position', 'fixed').css('top', '0').css('margin-top', '0').css('z-index', '100').removeClass('original').hide();
scrollIntervalID = setInterval(stickIt, 10);
function stickMenu() {
var orgElementPos = $('.original').offset();
orgElementTop = orgElementPos.top;
if ($(window).scrollTop() >= (orgElementTop)) {
orgElement = $('.original');
coordsOrgElement = orgElement.offset();
leftOrgElement = coordsOrgElement.left;
widthOrgElement = orgElement.css('width');
$('.cloned').css('left', leftOrgElement + 'px').css('top', 0).css('width', widthOrgElement).show();
$('.original').css('visibility', 'hidden');
$('.original>div>nav').removeAttr("id", "off-nav");
} else {
$('.cloned').hide();
$('.original>div>nav').attr("id", "off-nav");
$('.original').css('visibility', 'visible');
}
}
Edit: Added Markup
<header class="menu" id="main-header-wrap"">
<div class="" id="main-header">
<div class="toptop"></div>
<div class="container">
<div class="row">
<div id="logotype">
</div>
<div id="menu-container" class="clearfix">
<a class="mobile-nav-toggle lines-button x skiplink">
<span class="lines"></span>
</a>
<nav>
</nav>
</div>
</div>
</div>
<nav id="off-nav">
<ul><li class=""></li></ul>
</nav>
</div>
</header>

Categories

Resources