Javascript popup? - javascript

So what I'm trying to make is a map of Germany with markers.
and when clicked on a marker a div (content) will show with some things in it
is there a way to let JavaScript know which marker I clicked and it will open the corresponding content div, in total it will be about 200 markers so it must be a decently efficient code and my knowledge about JavaScript is not that great
this is the code I have for now
<div class="map">
<img src="/images/map.jpg">
</div>
<div class="markers" style="top: 60%; left: 35%;">
<div class="content" style="display: none;">
<h1>Test</h1>
<p>test</p>
</div>
</div>
<div class="markers" style="top: 20%; left: 60%;">
<div class="content" style="display: none;">
<h1>Test2</h1>
<p>test2</p>
</div>
</div>

Basic idea is using event delegation and listen to the click on the parent. You can than determine what was clicked and you can toggle a class to show the hidden element. Basic idea:
document.querySelector(".map-wrapper").addEventListener("click", function (e) {
// find if a marker was clicked
var marker = e.target.closest('.marker');
console.log(marker)
// was one clicked?
if (marker) {
// Hide any others that may be showing
var active = document.querySelector('.marker.active');
if(active && active!==marker) {
active.classList.remove('active');
}
// toggle the info so it shows/hides
marker.classList.toggle('active');
}
});
.map-wrapper {
position: relative;
background-color: #CCCCCC;
width: 400px;
height: 400px;
}
.marker {
position: relative;
}
.marker::after {
content: '🚻';
}
.marker .content {
display: none;
opacity: 0;
}
.marker.active .content {
position: absolute;
display: block;
opacity: 1;
transition: opacity 0.3s;
background-color: #CCFF00;
border: 2px solid red;
margin: 20px;
}
<div class="map-wrapper">
<div class="marker" style="left:100px; top: 100px;">
<div class="content">
<h1>Test1</h1>
<p>test1</p>
</div>
</div>
<div class="marker" style="left:150px; top: 270px;">
<div class="content">
<h1>Test2</h1>
<p>test2</p>
</div>
</div>
<div class="marker" style="left: 46px; top: 143px;">
<div class="content">
<h1>Test3</h1>
<p>test3</p>
</div>
</div>
</div>

There is no need to add any IDs or other means to identify the correct .content to show.
Add a click event listener to each marker and toggle a class on the element. The rest can be done with CSS.
// Find all of the .markers elements
const markers = document.querySelectorAll('.markers');
// Loop through the .markers
markers.forEach((marker) => {
// Add event listener to each .marker
marker.addEventListener('click', (e) => {
if (e.currentTarget.classList.contains('active')) {
// If the clicked element is active, deactivate it...
e.currentTarget.classList.remove('active');
} else {
// ...otherwise, deactivate any other active .markers...
removeClass(markers, 'active');
// ...and activate the clicked .marker
e.currentTarget.classList.add('active');
}
})
});
// Helper function to remove a class from a collection of elements
function removeClass(els, className) {
els.forEach((el) => {
el.classList.remove(className);
});
}
.markers {
border: 1px solid #e6e6e6;
}
.markers .content {
display: none;
}
.markers.active .content {
display: block;
}
<div class="markers" style="top: 60%; left: 35%;">
<p>
Marker 1
</p>
<div class="content">
<h1>Test</h1>
<p>test</p>
</div>
</div>
<div class="markers" style="top: 20%; left: 60%;">
<p>
Marker 2
</p>
<div class="content">
<h1>Test2</h1>
<p>test2</p>
</div>
</div>

Related

Close multiple box-dropdowns on outside click

There are multiple dropdowns, in this case three (but could be any number), which have toggleable dropdowns. However, if you click on all of them, they will all remain opened. How could I make it close when the other one is activated, and when there's an outside click?
Fiddle: https://jsfiddle.net/pcm2w3ov/1/
for (const button of document.querySelectorAll('button')) {
button.addEventListener('click', (e) => {
button.nextElementSibling.classList.toggle("dropdown-visible");
});
}
.container {
display: flex;
}
.box {
height: 100px;
width: 100px;
position: relative;
margin-right: 20px;
}
.dropdown {
height: 100px;
width: 100%;
position: absolute;
background: red;
top: 100%;
right: 0;
display: none;
}
.dropdown-visible {
display: block;
}
<div class="container">
<div class="box">
box 1
<button>toggle</button>
<div class="dropdown">dropdown content</div>
</div>
<div class="box">
box 2
<button>toggle</button>
<div class="dropdown">dropdown content</div>
</div>
<div class="box">
box 3
<button>toggle</button>
<div class="dropdown">dropdown content</div>
</div>
</div>
There's two parts to the problem. To toggle the current dropdown whilst hiding the others you can select them all and use filter() to exclude the current dropdown whilst hiding all the others.
To hide all the dropdowns when the click occurs outside the button or .dropdown elements you can bind an event handler to the document which checks the event to see from where it originated. Then you can either ignore the event, if the user clicked on a button or dropdown, or hide all dropdowns if the user clicked outside of those elements.
let buttons = document.querySelectorAll('button');
let dropdowns = document.querySelectorAll('.dropdown');
// toggle dropdowns
buttons.forEach(button => button.addEventListener('click', e => {
let targetDropdown = e.target.nextElementSibling;
Array.from(dropdowns).filter(dd => dd != targetDropdown).forEach(dd => dd.classList.remove('dropdown-visible'));
targetDropdown.classList.toggle('dropdown-visible');
}));
// hide dropdowns when click occurs on external element
document.addEventListener('click', e => {
if (e.target.classList.contains('dropdown') || e.target.tagName === 'BUTTON')
return;
dropdowns.forEach(dd => dd.classList.remove('dropdown-visible'));
});
.container {
display: flex;
}
.box {
height: 100px;
width: 100px;
position: relative;
margin-right: 20px;
}
.dropdown {
height: 100px;
width: 100%;
position: absolute;
background: red;
top: 100%;
right: 0;
display: none;
}
.dropdown-visible {
display: block;
}
<div class="container">
<div class="box">
box 1
<button>toggle</button>
<div class="dropdown">dropdown content</div>
</div>
<div class="box">
box 2
<button>toggle</button>
<div class="dropdown">dropdown content</div>
</div>
<div class="box">
box 3
<button>toggle</button>
<div class="dropdown">dropdown content</div>
</div>
</div>

JS: Iterate through divs

I have 5 div elements, all with class='item'.
Im catching them with: var x = document.getElementsByClassName("item");
Now I want to make disappear that div, which was mouseovered.
https://jsfiddle.net/LqsLbrco/1/
But it doesn't work as it supposed to do. Because all elements are disappearing, not only this which was hovered.
Edit: My point is that the modal div appear (the pink box) when the item div is hovered. Check out the new jsfiddle: https://jsfiddle.net/LqsLbrco/10/
There's a div behind the blue boxes, I want him to appear when the user hovers the blue box.
If you do it in jQuery, you could just do this.
Modified the markup to accommodate the requirements.
$(function() {
$(".container .item").bind("mouseover", function(event) {
$(event.target).find(".modal").show();
});
$(".container .modal").bind("mouseleave", function(event) {
$(event.target).hide();
})
});
.item {
height: 100px;
width: 100px;
background-color: blue;
display: inline-block;
margin: 5px;
}
.container {
display: inline-block;
}
.modal {
height: 100px;
width: 100px;
background-color: pink;
display: inline-block;
margin: 0px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">
<div class="modal"></div>
</div>
</div>
<div class="container">
<div class="item">
<div class="modal"></div>
</div>
</div>
<div class="container">
<div class="item">
<div class="modal"></div>
</div>
</div>
<div class="container">
<div class="item">
<div class="modal"></div>
</div>
</div>
<div class="container">
<div class="item">
<div class="modal"></div>
</div>

playing fadein/fadeout slider on tab button click

I have created a Fadein/Fadeout slider. Left button and right button are working fine but I want to play slider by clicking on tab buttons.
JSfiddle
HTML
<p id="slide1_controls">
<div class="block-icon icon-s1">
<img class="block-img icon-s1" src="../_images/building_icon1.png" data-hover-image="../_images/building_icon1_hover.png" data-selected="false" />
</div>
<div class="block-icon icon-s2">
<img class="block-img icon-s2" src="../_images/building_icon2.png" data-hover-image="../_images/building_icon2_hover.png" data-selected="false" />
</div>
<div class="block-icon icon-s3">
<img class="block-img icon-s3" src="../_images/building_icon3.png" data-hover-image="../_images/building_icon3_hover.png" data-selected="false" />
</div>
<div class="block-icon icon-s4">
<img class="block-img icon-s4" src="../_images/building_icon4.png" data-hover-image="../_images/building_icon4_hover.png" data-selected="false" />
</div>
</p>
<div class="slider-text-context" id="target">
<div class="slide-01 fade-texts active">tab1</div>
<div class="slide-02 fade-texts">tab2</div>
<div class="slide-03 fade-texts">tab3</div>
<div class="slide-04 fade-texts">tab4</div>
</div>
CSS
.fade-texts {
width: 100%;
height: 259px;
left: 0px;
position: absolute;
}
.slider-btn-area {
position: absolute;
z-index: 8;
margin-left: auto;
margin-right: auto;
left: 25%;
top: 54%;
width: 50%;
}
#target > div {
display:none;
}
#target div:nth-child(1) {
display:block;
}
.tab-area {
position: absolute;
left: 25%;
top: 30%;
}
Javascript
$(".icon-s2").click(function() {
activeElem = $("#target .slide-02");
activeElem.removeClass('active').fadeOut(0);
if (!activeElem.is(':first-child')) {
activeElem.removeClass('active').fadeOut(0).prev().addClass('active').fadeIn(400);
}
}
$(".icon-s3").click(function() {
activeElem = $("#target .slide-03");
activeElem.removeClass('active').fadeOut(0);
if (!activeElem.is(':first-child')) {
activeElem.removeClass('active').fadeOut(0).prev().addClass('active').fadeIn(400);
}
}
When I press the tab it does not work to try to appear a DIV.
Your code made no sense. The way it looked was that the images had to be clicked in order to fadeIn/Out the tabs. I believe it should be the other way. I cleaned up the markup, and simplified the classes, ids, styles, etc...
Here's the DEMO
HTML
<div id="slides">
<div id="slide1" class="slide active">
<img class="img" src="http://placehold.it/150x50/000/Fff.png&text=FIRST" />
</div>
<div id="slide2" class="slide">
<img class="img" src="http://placehold.it/150X50/048/Fee.png&text=SECOND" />
</div>
<div id="slide3" class="slide">
<img class="img" src="http://placehold.it/150X50/fa8/375.png&text=THIRD" />
</div>
<div id="slide4" class="slide">
<img class="img" src="http://placehold.it/150X50/9a7/a10.png&text=FOURTH" />
</div>
</div>
<div class="tab-area" id="controls">
<div id="tab1" class="tab">1</div>
<div id="tab2" class="tab">2</div>
<div id="tab3" class="tab">3</div>
<div id="tab4" class="tab">4</div>
</div>
CSS
.slide {
display:none;
}
.active {
display: block;
}
.tab {
width: 16px;
height: 16px;
display: inline-block;
margin: 0 10px;
outline: 1px solid black;
text-align: center;
cursor: pointer;
}
jQuery/JavaScript
$(function () {
$('.tab').on('click', function (event) {
var tabID = event.target.id;
//console.log('tabID: '+tabID);
var order = tabID.split('b').pop();
//console.log('order: '+order);
var pos = parseInt(order, 10);
var slideID = 'slide'+pos;
//console.log('slideID: '+slideID);
var act = document.getElementById(slideID);
//console.log('act: '+act.id);
$('.slide').fadeOut(0).removeClass('active');
$(act).addClass('active').fadeIn(750);
});
});

toggle class of multiple elements based on clicked element

My code looks something like :-
<div id="boxgallery" class="boxgallery" data-effect="effect-3">
<div class="panel"><img src="img/2.jpg" alt="Image 2" />
<button class="button overlay-launcher" id="pop2">
link
</button>
<div id="pop2" class="overlay-background"></div>
<div id="pop2" class="overlay-content">
<button id="pop2" class="overlay-close">Close overlay Window</button>
</div>
</div>
<div class="panel"><img src="img/3.jpg" alt="Image 3" />
<button class="button overlay-launcher" id="pop3">
link
</button>>
<div id="pop3" class="overlay-background"></div>
<div id="pop3" class="overlay-content">
<button id="pop3" class="overlay-close">Close overlay Window</button>
</div>
</div>
<div class="panel"><img src="img/1.jpg" alt="Image 1" />
<button class="button overlay-launcher" id="pop1">
link
</button>>
<div id="pop1" class="overlay-background"></div>
<div id="pop1" class="overlay-content">
<button id="pop1" class="overlay-close">Close overlay Window</button>
</div>
</div>
<div class="panel"><img src="img/4.jpg" alt="Image 4" />
<button class="button overlay-launcher" id="pop4">
link
</button>>
<div id="pop4" class="overlay-background"></div>
<div id="pop4" class="overlay-content">
<button id="pop4" class="overlay-close">Close overlay Window</button>
</div>
</div>
</div>
I was trying :-
$(function() {
$(".overlay-launcher").click(function() {
$(".overlay-content,.overlay-background").toggleClass("active");
});
});
but it would work only if i have only one of those
or if i write the jquery for each one separately
what i want to achieve is if i click on the launcher for the pop1 then the content and background of the 1st overlay should appear
same for the rest
the nearest I found was this Single function to toggle multiple divs inside other divs individually
but it doesn't really solve the problem in my specific case I,
I ahve to toggle the active class based on the class of the element
EDIT:
CSS goes like this:-
.overlay-background {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: white;
opacity: .50;
z-index: 1000;
}
.overlay-content {
background-color: white;
border-radius: 10px;
box-shadow: 0 0 20px 0 #222;
display: none;
height: 240px;
left: 50%;
margin: -120px 0 0 -160px;
padding: 10px;
position: absolute;
top: 50%;
width: 320px;
z-index: 1000;
}
.overlay-background .active,
.overlay-content .active {
display: block;
}
Below are the 2 things that needs to be done to make it work
In css,
.overlay-background.active, .overlay-content.active {
display: block;
}
In Javascript,
$(".overlay-launcher").click(function () {
$('.overlay-content,.overlay-background').removeClass("active");
$(this).siblings('.overlay-content,.overlay-background').addClass("active");
});
$('.overlay-close').on('click', function(){
$('.overlay-content,.overlay-background').removeClass("active");
});
Working fiddle https://jsfiddle.net/sachin_puthran/ssmstjvu/7/
You should not have multiple elements in your page with the same id like that. id values should be unique within a particular page.
Also note other syntax errors:
</button>>
</button>>
$(".overlay-launcher,")

Minify code for same divs for same effect

i have the following jquery code:
$('#menu1').click(function(e){
$('#menu1').addClass('fullscreen');
if($('#menu1').hasClass('fullscreen')){
$('.barra').removeClass('hidden');
}
});
$('#close').click(function(e){
$('#menu1').removeClass('fullscreen').animate({
width: '200px',
height: '200px'
}, 2500);
});
HTML
<section>
<div class="content">
<div id="menu1">
<div class="blackbar hidden">
<img src="img/cross.png" width="40" height="40" alt="fechar"/>
</div>
</div>
<div id="menu2">
<!-- quadrado 2 -->
</div>
<div id="menu3">
<!-- quadrado 3 -->
</div>
<div id="menu4">
<!-- quadrado 4 -->
</div>
</div>
</section>
I want the same for all divs, called "menu" (from 1 to 4), without having to copy the same code and having too many lines, for the same procedure.
All div's will have "$('#menu').addClass('fullscreen');" and "$('.barra').removeClass('hidden');". Any help or guidance?
How to achieve this?
CSS
section{ //"menu" alignment center
position: absolute;
width: 100%;
height: 100%;
top: 50%;
bottom: 50%;
text-align: center;
}
.content{
position: relative;
display: inline-block;
width: 420px;
height: 200px;
margin-top: 9%;
}
#menu1, #menu2, #menu3, #menu4{
width: 200px;
height: 200px;
}
#menu1.fullscreen{
top: 0;
left: 0;
z-index: 9;
position: fixed;
width: 100%;
height: 100%;
background: #131313;
color: #fff;
}
I usually do this by using a class selector.
Add a class "menu" to echo menu element:
<div id="menu2" class="menu">
<!-- quadrado 2 -->
</div>
Then Select it like so:
$('.menu').click(function(e){
$(this).addClass('fullscreen');
if($(this).hasClass('fullscreen')){
$('.barra').removeClass('hidden');
}
});
The jQuery selector $(this) refers to the clicked element.
Just finished your code, I improved it a bit by adding one or two things. So here it goes .. while you did not provide a css or anything I styled it fast to be able to get the job done.
CSS
<style>
div[id^="menu"]{
background: #333;
margin: 30px;
float: left;
width: 100px;
height: 80px;
}
.close {
display: none;
color: #fff;
width: 100%;
height: 15px;
background: #4779ff;
}
.ThisElementIsClicked .close {
display: block;
}
</style>
HTML
<div class="content">
<div id="menu1" class="menu-box">
<div class="blackbar hidden">
<img src="img/cross.png" width="40" height="40" alt="fechar"/>
</div>
</div>
<div id="menu2" class="menu-box">
<div class="blackbar hidden">
<img src="img/cross.png" width="40" height="40" alt="fechar"/>
</div>
</div>
<div id="menu3" class="menu-box">
<div class="blackbar hidden">
<img src="img/cross.png" width="40" height="40" alt="fechar"/>
</div>
</div>
<div id="menu4" class="menu-box">
<div class="blackbar hidden">
<img src="img/cross.png" width="40" height="40" alt="fechar"/>
</div>
</div>
</div>
jQuery WITH COMMENTS - go below for the no comments version
$(document).ready(function(){
//focus on all elements that have an ID starting with the string 'menu'
//you do that adding '^' before the '=' sign.
var targetThis = $('div[id^="menu"]');
//test it yourself to see it's working
//uncomment this line below to display the info into your console
//console.log(targetThis);
targetThis.on('click', function(){
//set a variable with the element you clicked on
var thisEl = $(this),
thisID = thisEl.attr('id').substr(4);
if(!thisEl.hasClass('ThisElementIsClicked'))
{
//if you want all other menu boxes to close while
//the current clicked menu box is clicked just remove the class for
//all elements that have the ID starting with the string 'menu'
//that is the first variable we created before the click event occured
//uncomment the line below to see the results
//targetThis.removeClass('ThisElementIsClicked');
//add the class to the current clicked menu box
thisEl.addClass('ThisElementIsClicked');
//remove the hidden class
//but this should not be made with jQuery but with CSS
//just style the 'hidden' class based on the parent class that we added on click 'ThisElementIsClicked'
$('#menu' + thisID).children('.blackbar').removeClass('hidden');
//now while this box is opened
//add inside this block of code the script for
//the closing button
var closeBtn = thisEl.find('.close');
closeBtn.on('click', function(e){
e.stopPropagation();
$(this).parents('#menu' + thisID).removeClass('ThisElementIsClicked');
$(this).parents('#menu' + thisID).children('.blackbar').addClass('hidden');
});
}
});
});
jQuery NO COMMENTS
$(document).ready(function(){
var targetThis = $('div[id^="menu"]');
targetThis.on('click', function(){
var thisEl = $(this),
thisID = thisEl.attr('id').substr(4);
if(!thisEl.hasClass('ThisElementIsClicked'))
{
//targetThis.removeClass('ThisElementIsClicked');
thisEl.addClass('ThisElementIsClicked');
$('#menu' + thisID).children('.blackbar').removeClass('hidden');
var closeBtn = thisEl.find('.close');
closeBtn.on('click', function(e){
e.stopPropagation();
$(this).parents('#menu' + thisID).removeClass('ThisElementIsClicked');
$(this).parents('#menu' + thisID).children('.blackbar').addClass('hidden');
});
}
});
});
Hope this helps you ... and by the way, you have the option to only display one box at the time, when you click a box all other boxes close. Read the comments.

Categories

Resources