Reputation: 149
I have an overlay effect for a single page website. I have two links for two overlays. After I click the second link, the first overlay doesn't close and two overlays are shown. How can I have the initial overlay close?
HTML:
<nav id="menuheader">
<ul style="display:block;">
<li>
<div class="about link" data-link="overlay-about"> About </div>
</li>
<li>
<div class="service link" data-link="overlay-service"> Services </div>
</li>
<li>
<div class="contact link"> Contact </div>
</li>
</ul>
</nav>
<aside class=" overlay overlay-about overlay-contentscale">
<div class="overlay_close"></div>
</aside>
<aside class="overlay overlay-service overlay-contentscale ">
<div class="overlay_close"></div>
</aside>
Javascript:
$(".link").on('click', function(e) {
e.preventDefault();
var currentClass = $(this).data("link");
$("aside." + currentClass).addClass("open");
})
$('.overlay_close').on('click', function() {
if ($('.overlay').hasClass('open')) {
$("aside.overlay").removeClass("open");
$(".overlay").addClass('close');
$('.overlay').removeClass('close');
}
});
If you can please use Javascript, not JQuery.
Upvotes: 5
Views: 2219
Reputation: 91
Hidding all overlays upfront should do the job:
$(".link").on('click', function(e) {
e.preventDefault();
$('.overlay').hide(); // <----- new line
var currentClass = $(this).data("link");
$("aside." + currentClass).addClass("open");
});
$('.overlay_close').on('click', function() {
$('.overlay').removeClass('open');
});
Upvotes: 2
Reputation: 36
Try:
CSS rule:
.overlay { display: none; }
.active { display: block; }
Javascript Solution:
function getAllelements(selector) {
return document.querySelectorAll(selector);
}
function addEventHandler(element,eventType,handler) {
if (element.addEventListener)
element.addEventListener (eventType,handler,false);
else if (element.attachEvent)
element.attachEvent ('on'+eventType,handler);
}
function clickOnlink(event){
var curTarget = event.target;
closeAlloverlay();
var curOverlayobj = document.querySelector("."+curTarget.dataset.link);
curOverlayobj.classList.add("active");
}
function closeAlloverlay(){
var overLayelelist = getAllelements(".overlay");
for(var i=0; i<overLayelelist.length; i++){
overLayelelist[i].classList.remove("active");
}
}
function linkObjinit(linkObj){
if(linkObj.length > 0){
for (i = 0; i < linkObj.length; i++) {
var curObj = linkObj[i];
if(curObj.dataset.link){
addEventHandler(linkObj[i],'click',clickOnlink);
}
else{
addEventHandler(linkObj[i],'click',closeAlloverlay);
}
}
}
}
linkObjinit(getAllelements("#menuheader .link"));
/*
* For nth number of Menu
* Call "linkObjinit(getAllelements("#NAVTAGID .link"))" function
*/
Upvotes: 1
Reputation: 8181
So, as you asked, in plain javascript, you could do the following. I have put in description of each line of code as inline comments.
function get(selector) { return document.querySelector(selector); }
function getAll(selector) { return document.querySelectorAll(selector); }
//Loop thru all the links
[].forEach.call(getAll(".link"), function(div) {
//Add click event to each them
div.addEventListener("click", function(event) {
//Cross browser event object
event = event || window.event;
//Get the data attribute of the clicked link
var currentClass = div.getAttribute("data-link") || false;
//Loop thru all the overlays, remove the open class
[].forEach.call(getAll(".overlay"), function(ol) {
ol.className = ol.className.replace(/open/, "").replace(/\s{2,}/, " ");
});
//If no data attribute on the link elem, return
if (!currentClass) return;
//Get the element with the link data attr class
var classes = get("." + currentClass).className;
//And add open class to it
get("." + currentClass).className = classes + " open";
});
});
.overlay { display: none; }
.open { display: block; }
<nav id="menuheader">
<ul style="display:block;">
<li>
<div class="about link" data-link="overlay-about"> About </div>
</li>
<li>
<div class="service link" data-link="overlay-service"> Services </div>
</li>
<li>
<div class="contact link"> Contact </div>
</li>
</ul>
</nav>
<aside class="overlay overlay-about overlay-contentscale">
<div>Some content ovl about</div>
<div class="overlay_close"></div>
</aside>
<aside class="overlay overlay-service overlay-contentscale">
<div>Some content ovl service</div>
<div class="overlay_close"></div>
</aside>
Follow the above code and do the same for the close overlay as well. If you need help let me know.
jQuery version: --Demo--
$(".link").on('click', function(e) {
e.preventDefault();
var currentClass = $(this).data("link");
$("aside." + currentClass).addClass("open").siblings().removeClass("open");
})
$('.overlay_close').on('click', function() {
var $overlay = $(this).closest(".overlay");
$overlay.is(".open") && $overlay.removeClass("open");
});
Hope that helps.
Upvotes: 1
Reputation: 559
First of all this code does not mean anyting
$(".overlay").addClass('close');
$('.overlay').removeClass('close');
You need to update the code in javascript like this
var currentClass;
$(".link").on('click', function(e) {
e.preventDefault();
currentClass = $(this).data("link");
$("aside." + currentClass).addClass("open");
})
$('.overlay_close').on('click', function() {
$("aside." + currentClass).removeClass("open");
});
EDIT: Javascript solution
var link = document.getElementsByClassName('link')
var overlay_close = document.getElementsByClassName('overlay_close');
var currentClass;
link.onclick = function(e){
e.preventDefault();
currentClass = this.getAttribute('data-link');
this.classList.add("open")
}
overlay_close.onclick = function(e){
var currentElement = document.querySelector("aside."+currentClass);
currentElement.classList.remove("open");
}
Upvotes: 2
Reputation: 965
You might want to create a function that closes all overlays
function closeAllOverlays () {
$('.overlay').removeClass('open');
}
and call it before opening one:
$(".link").on('click', function(e) {
e.preventDefault();
closeAllOverlays();
var currentClass = $(this).data("link");
$("aside." + currentClass).addClass("open");
});
And I am using jQuery, since you seem to already use it your self.
Upvotes: 1