removeClass('active') when clicking outside - javascript

I am using this code to control the display of a sidebar via add/remove class.
The first 2 functions work, however I have also added a 3rd function to try to remove class active when clicking outside of the sidebar.
Now nothing works, it just pushes some body content aside.
jQuery(document).ready(function($){
$(".btn-open-sidecart").click(function(){
$('.sidebar').addClass("active");
$('.overlay').addClass("active");
});
$(".btn-close-sidecart").click(function(){
$('.sidebar').removeClass("active");
$('.overlay').removeClass("active");
});
$('body').click(function(event){
if($(event.target).attr('class') !== "sidebar" && $(event.target).attr('class') !== "btn-close-sidecart") {
$('.sidebar').removeClass('active');
$('.overlay').removeClass('active');
};
});
});
How can I fix this to also removeClass('active') when clicking outside the sidebar?

You are only checking if the element you are clicking on is ".sidebar" or ".btn-close-sidecart" but not if one of their parents has these class.
So even clicking on a button inside ".sidebar" will trigger your method as they are note ".sidebar"
Here is a working example
$(".btn-open-sidecart").click(function(){
$('.sidebar').addClass("active");
$('.overlay').addClass("active");
});
$(".btn-close-sidecart").click(function(){
$('.sidebar').removeClass("active");
$('.overlay').removeClass("active");
});
$('body').click(function(event){
const ignoreElements = ["btn-open-sidecart", "sidebar"];
let pass = true;
$(ignoreElements).each(function(key, value) {
if ($(event.target).hasClass(value) || $(event.target).closest(`.${value}`).length > 0) {
pass = false;
}
});
if (pass) {
$('.sidebar').removeClass('active');
$('.overlay').removeClass('active');
}
});
* {
padding: 0;
margin: 0;
}
.sidebar {
position: fixed;
z-index: 3;
width: 200px;
height: 100%;
background: darkgrey
}
.sidebar:not(.active) {
display: none;
}
.btn-close-sidecart {
position: absolute;
width: 20px;
height: 20px;
top 5px;
right: 5px;
background: grey;
cursor: pointer;
text-align: center;
}
.overlay {
position: fixed;
z-index: 2;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5)
}
.overlay:not(.active) {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="sidebar">
<div class="btn-close-sidecart">
x
</div>
<ul>
<li>
<button onclick="console.log('test')">button 1</button>
</li>
<li>
<button onclick="console.log('test2')">button 2</button>
</li>
</ul>
</div>
<div class="overlay">
</div>
<div class="content">
<button class="btn-open-sidecart">Open sidebar</button>
</div>
</div>

Related

How to make it so when a button is clicked a div shows and when a different button is clicked it hides that div and displays a different one

how to make it so when you click a button it shows a div and hides the one ur on
example: if you have "profile" & "dashboard" and you click "dashboard" it shows the div for dashboard and hides the one for profile
You could use .style to hide the div, but it would be better to use seperate pages (EX: https://example.com/profile and https://example.com/dashboard).
(() => {
window.onload = () => {
const profilediv = document.getElementById(`profile`);
const dashboarddiv = document.getElementById(`dashboard`);
const profilebutton = document.getElementById(`profilebutton`);
const dashboardbutton = document.getElementById(`dashboardbutton`);
var page = 0;
function updatePage() {
profilediv.style.display = `none`;
dashboarddiv.style.display = `none`;
if (page == 0) {
dashboarddiv.style.display = `block`;
} else if (page == 1) {
profilediv.style.display = `block`;
}
return;
}
profilebutton.addEventListener(`click`, e => {
page = 1;
setTimeout(updatePage);
return;
});
dashboardbutton.addEventListener(`click`, e => {
page = 0;
setTimeout(updatePage);
return;
});
}
})();
body {
margin: 0;
}
#profile,
#dashboard {
width: 100%;
height: calc(100% - 20px);
top: 20px;
left: 0px;
padding: 5px;
position: fixed;
}
#topbar {
width: 100%;
height: 26px;
position: fixed;
border-bottom: 1px solid #000;
}
#profilebutton,
#dashboardbutton {
width: 20%;
height: 20px;
top: 3px;
left: 5px;
position: relative;
}
<div id="topbar">
<button id="dashboardbutton">Dashboard</button>
<button id="profilebutton">Profile</button>
</div>
<div id="dashboard" style="display: block;">
<p>Dashboard</p>
</div>
<div id="profile" style="display: none;">
<p>Test Account</p>
<button>Edit Name</button>
</div>

Dropdown mobile menu sliding in from top by pressing the Icon

I want my mobile dropdown menu to slide in from top when the user clicks the "header-downbar-menu" icon and slide out to the top when the user clicks it again. For now the button can only show the menu but I don't know how to properly write JS for this part...
var DropdownMenuDown = false;
function OpenDropdownMenu() {
if (DropdownMenuDown == false) {
document.getElementById("header-dropdown-menu").style.top = "0px";
}
}
.header-dropdown {
width: 100%;
position: relative;
}
.header-dropdown-menu {
width: 100%;
height: 80vh;
background-color: white;
position: absolute;
top: -80vh;
}
<div class="header-downbar-menu" onclick="OpenDropdownMenu()">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</div>
<div class="header-dropdown">
<div id="header-dropdown-menu" class="header-dropdown-menu">
</div>
</div>
I can't make the var "DropdownMenuDown" work
I'd recommend you using toggle for this.
Look here:
function showMenu() {
var topmenu = document.querySelector('.topmenu');
topmenu.classList.toggle('show-me');
}
body {
margin: 0;
}
#bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #AEAEAE;
}
.topmenu {
position: absolute;
height: 60px;
top: -60px;
width: 100%;
background-color: red;
z-index: 99;
}
.show-me {
top: 0 !important;
}
button {
position: absolute;
top: 60px;
left: 0;
}
<div id="bg">
<div class="topmenu">
</div>
<button onclick="showMenu()">Menu pls!</button>
</div>
i just have read your question. i think you are not aware of the selector of document. in your case, the code should be like this.
var DropdownMenuDown = false;
function OpenDropdownMenu() {
if (DropdownMenuDown == false) {
document.getElementByClassName("header-dropdown-menu").style.top = "0px";
}
}
"header-dropdown-menu "is not id, but classname!

jQuery: Finish dragging without triggering click event

I am trying to set up the following page where:
If you click the button, you can see a div.
If you click the div, you can see the next div.
If you move the button, there is no »click« (desired behaviour)
The problem I am having is that if you move the div, the next div appears - this is not what I want. The "next div" should not be displayed after a drag event finishes on it.
Here is my code:
$(function() {
$("#button").draggable({
stack: 'div',
containment: "body"
});
});
$('#button').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
// click function
$("#content").toggle();
}
});
$(function() {
$("#content").draggable({
stack: 'div',
containment: "body"
});
});
let containers = $('.trip').hide();
let firstContainer = containers.first().show();
containers.on('click', function() {
//Get current element and next sibling
let elem = $(this);
let next = elem.next('.trip');
//Does sibling exist?
if (next.length) {
next.show();
} else {
firstContainer.show();
}
elem.hide();
});
body {
width: 100vw;
height: 100vh;
padding: 0;
margin: 0;
left: 0;
top: 0;
background-color: grey;
}
#button {
width: 100px;
height: 100px;
background-color: cyan;
}
#content {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
<div id="button">Button</div>
<div id="content">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
Is there a way to solve this? :)
(a possible problem is also that pure JavaScript is mixed with jQuery)
Thanks
The main problem to solve here is in distinguishing a regular click event on #content, from other "click like events" that are also triggered during completion of the element being dragged.
You're code currently has a method of doing that which you could re purpose for the desired behaviour:
if (! $(this).hasClass('ui-draggable-dragging')) {
/* This was a "regular click event"
}
So in the case of your code, you could revise it as follows:
$(function() {
/* Combine on ready logic into one place */
$("#button").draggable({
stack: 'div',
containment: "body"
});
$("#content").draggable({
stack: 'div',
containment: "body"
});
/* Hide all trip elements except for first */
$('.trip', '#content').not(':first').hide();
});
$('#button').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
$("#content").toggle();
}
});
$('#content').on('mouseup', function() {
/* Reuse same logic in #button mouseup handler */
if (!$(this).hasClass('ui-draggable-dragging')) {
/*
If content element if not dragging, treat mouse up as conclusion
of click event and rotate visibility of trip elements like this
*/
let trip = $('.trip:visible', '#content');
let next = trip.next().length === 0 ?
$('.trip:first', '#content') : trip.next();
trip.hide();
next.show();
}
});
body {
width: 100vw;
height: 100vh;
padding: 0;
margin: 0;
left: 0;
top: 0;
background-color: grey;
}
#button {
width: 100px;
height: 100px;
background-color: cyan;
}
#content {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
<div id="button">Button</div>
<div id="content">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
Actually, all you need is this bit of readable code,
Assign a class .draggable to all your draggable elements
Use the new class as stack: '.draggable'
Register click to your '#container', not on your .trip elements
Use only one Event, the "click" one:
Hide all .trip but first using CSS .trip~.trip {display:none;}
jQuery( $ => {
const $cont = $('#content');
const $bttn = $('#button');
const $trip = $('.trip');
const tripL = $trip.length;
let i = 0;
$('.draggable').draggable({stack:'div', containment:'body'});
$bttn.on('click', function() {
if (!$(this).hasClass('ui-draggable-dragging')) $cont.toggle();
});
$cont.on('click', function() {
$trip.eq(++i % tripL).show().siblings($trip).hide();
});
});
html, body { height:100%; margin:0;}
body {
background-color: grey;
}
#button {
width: 100px;
height: 100px;
background-color: cyan;
}
#content {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
.trip ~ .trip {display: none;}
<!-- PS: Add class="draggable" to draggable elements -->
<div id="button" class="draggable">Button</div>
<div id="content" class="draggable">
<div class="trip" id="a">div 1</div>
<div class="trip" id="b">div 2</div>
<div class="trip" id="c">div 3</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
EDIT
For more contents see this answer: https://stackoverflow.com/a/57351517/383904

How to make a popup disappear only when clicked anywhere outside of it

I'm trying to toggle a popup when click on a specific link and then remove class ".open" from it when clicked anywhere other than the popup box.
Using below methods I was able to get the popup disappear when clicked outside of it but it's now also getting disappear when clicked inside the popup area.
$(".onclick-dropdown-link, .user-message-center-link").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var id = $this.attr('href');
$('.onclick-dropdown').not(id).removeClass('open');
$(id).toggleClass('open');
});
$('body:not(.onclick-dropdown.open)').click(function(e) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
});
.onclick-dropdown {
opacity: 0;
visibility: hidden;
background: #f3f3f3;
width: 390px;
height: 390px;
position: absolute;
top: 128px;
right: 28px;
height: auto;
padding: 0;
z-index: 999;
}
.onclick-dropdown.open {
opacity: 1;
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="alert-center-link">
<a class="onclick-dropdown-link" href="#alert-center">The Link</a>
</li>
</ul>
<div id="alert-center" class="onclick-dropdown">
<p>Lorem Ipusm</p>
</div>
Change your .click() function to the following:
$(document).click(function(e) {
if( !$('.onclick-dropdown').is(e.target) && !$('.onclick-dropdown').children().is(e.target)) {
if( $('.onclick-dropdown').hasClass('open') ) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
}
}
});
Change your Popup HTML to :
<div id="alert-center-outer" class="onclick-dropdown">
<div id="alert-center">
//CONTENT HERE...
<p>Lorem Ipusm</p>
</div>
</div>
#alert-center-outer{
position: fixed;
left; 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0.5;
background-color: black;
}
#alert-center{
width: 200px;
height: 300px;
margin: 0 auto;/*This will center align it.*/
}
Clicking the #alert-center-outer should hide the popup.
Clicking the #alert-center should stopPropagation so that it doesn't bubble to its parent.
try below code
$(document).ready(function(){
$(".onclick-dropdown-link, .user-message-center-link").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var id = $this.attr('href');
$('.onclick-dropdown').not(id).removeClass('open');
$(id).toggleClass('open');
});
$(document).click(function(e) {
if (!$(e.target).closest('.onclick-dropdown').length)
$("#alert-center, #message-center, #user-message-center").removeClass('open');
});
})
.onclick-dropdown {
opacity: 0;
visibility: hidden;
background: #f3f3f3;
width: 390px;
height: 390px;
position: absolute;
top: 128px;
right: 28px;
height: auto;
padding: 0;
z-index: 999;
}
.onclick-dropdown.open {
opacity: 1;
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="alert-center" class="onclick-dropdown">
<p>Lorem Ipusm</p>
</div>
<li class="alert-center-link"><a class="onclick-dropdown-link" href="#alert-center">asdfsdfsdfds</a></li>
// only trigger once
$('body').one('click', function(e) {
var $target = $(e.target);
// the $target which trigger click event is not the popup dom itself
// and also is not the children dom of the popup
if (!$target.is('#alert-center') && $target.parents('#alert-center').length === 0) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
}
})
Is that what you want?
Now you can add any tags in the popup, and click inside the popup area where not hide it.

Create a simple jQuery content slider

Im trying to create a simple content slider with jQuery and css.
The slider has two columns :
the right one acts as a slider pager
the left one contains current content
I've managed to create html, css and jQuery function which changes active tab and related content. but I want function to repeat itslef and by hovering to pagers slider stop paging, then by mouseout slider continue.
HTML
<div id="slider">
<div id="rightcol">
<div class="content" id="content1">
</div>
<div class="content" id="content2">
</div>
<div class="content" id="content3">
</div>
</div>
<div id="leftcol">
<ul>
<li id="1" class="active">a</li>
<li id="2">b</li>
<li id="3">c</li>
</ul>
</div>
</div>
CSS
#slider
{
width: 600px;
height: 300px;
}
#leftcol
{
width: 300px;
height: 300px;
float: left;
}
#rightcol
{
width: 300px;
height: 300px;
float: right;
background-color: #F0F0F0;
}
#leftcol ul li
{
width: 300px;
height: 100px;
}
#leftcol ul li.active
{
background-color: #F0F0F0;
}
.content
{
width: 300px;
height: 300px;
display: none;
}
jQuery
$(document).ready(function () {
sd(3);
});
function sd(currentId) {
var currentcontent = "content";
s = "#" + String(currentcontent) + String(currentId);
$("#leftcol ul li").removeClass("active");
$(".content").hide();
$("#" + String(currentId)).addClass("active");
$(s).show();
}
What should be added to js?
jsfiddle demo
I have tried in simple jQuery content slider in the below way & its working even in responsive.
Demo link: jsfiddle.net/b54c38hj/1/
<div class="container">
<div class="slider">
<ul>
<li>Slider-1</li>
<li>Slider-2</li>
<li>Slider-3</li>
</ul>
</div>
<a class="prev" href="javascript:void(0)">Prev</a>
<a class="next" href="javascript:void(0)">Next</a>
body{
margin:0;
padding:0;
}
.container{
width: 100%;
height: 300px;
background: rgba(0,0,0,.45);
margin: 0 auto;
}
.container .slider{
overflow: hidden;
height: 300px;
}
.container .slider ul{
position: relative;
padding:0;
margin:0;
list-style-type: none;
height: 300px;
}
.container .slider ul li{
background: #efefef;
float: left;
color: #000;
font-size: 22px;
text-align: center;
height: 300px;
line-height: 300px;
}
.container a{
text-decoration: none;
position: absolute;
}
.container a.prev{
left: 0;
}
.container a.next{
right: 0;
}
var Slider = {};
Slider = {
_globalvar: function(){
var self = this;
self.Ele = $('.slider');
self.EleList = this.Ele.find('li');
self.Elelength = this.EleList.length;
self.Elewidth = this.Ele.outerWidth(true);
self.EleSetUl = this.Elelength * this.Elewidth;
self.current = 0;
},
_assignvar: function(){
Slider.Ele.find('ul').width(Slider.EleSetUl);
Slider.EleList.width(Slider.Elewidth);
Slider.Ele.find('li:first-child').addClass('active');
},
_prev: function(){
var prevlength = Slider.Ele.find('li.active').prev().length;
console.log(prevlength)
if(prevlength != 1){
Slider.current = null;
}
else{
Slider.Ele.find('li.active').removeClass('active').prev().addClass('active');
Slider.current = "+="+Slider.Elewidth;
}
Slider.Ele.find('ul').animate({
left: Slider.current
});
return false;
},
_next: function(){
var nextlength = Slider.Ele.find('li.active').next().length;
if(nextlength){
Slider.Ele.find('li.active').removeClass('active').next().addClass('active');
Slider.current = "-="+Slider.Elewidth;
}
else{
Slider.current = null;
Slider.Ele.find('li.active').removeClass('active').parent().find('li:first-child').addClass('active');
}
Slider.Ele.find('ul').animate({
left: Slider.current
});
return false;
},
_bind: function(){
$('.prev').on('click', function(){
Slider._prev();
});
$('.next').on('click', function(){
Slider._next();
});
},
_init: function(){
var self = this;
self._globalvar();
self._assignvar();
self._bind();
}
};
$(document).ready(function(){
Slider._init();
});
https://jsfiddle.net/b54c38hj/1/
To make it to reapeat you can use the setTimeout() and to make it stop whenever your mouse goes over the content you can use the hover() jquery event! Here's a Demo

Categories