There are a bunch of div elements on the page.
I have a nested div inside of them.
I want to be able to add a class to the clicked element, and .show() the child div.
$('.container').on('click', function(){
$(this).toggleClass('red').children('.insideItem').slideToggle();
});
I can click on it, it drops down.
Click again, it goes away.
So, now I need some method to removeClass() and slideUp() all of the other ones in the event of a click anywhere except the open div. Naturally, I tried something like this:
$('html').on('click', function(){
$('.container').removeClass('red').children('div').slideUp();
});
Well, that just stops the effect from staying in the first place. I've read around on event.Propagation() but I've read that should be avoided if possible.
I'm trying to avoid using any more prebuilt plugins like accordion, as this should be a pretty straightforward thing to accomplish and I'd like to know a simple way to make it work.
Would anyone be able to show a quick example on this fiddle how to resolve this?
Show only one active div, and collapse all others if clicked off
https://jsfiddle.net/4x1Lsryp/
One way to go about it is to update your code with the following:
1) prevent the click on a square from bubbling up to the parent elements
2) make sure to reset the status of all the squares when a new click is made anywhere.
$('.container').on('click', function(){
$this = $(this);
$('.container').not($this).removeClass('red').children('div').slideUp();
$this.toggleClass('red').children('div').slideToggle();
return false;
});
See the updated JSfiddle here: https://jsfiddle.net/pdL0y0xz/
You need to combine your two approaches:
for (var i = 0; i < 10; i++) {
$('#wrap').append("<div class='container'>" + i + "<div class='insideDiv'>Inside Stuff</div></div>");
}
$('.container').on('click', function() {
var hadClassRed = $(this).hasClass('red');
$('.container').removeClass('red').children('div').slideUp();
if (!hadClassRed) {
$(this).toggleClass('red').children('div').slideToggle();
}
});
.container {
width: 200px;
height: 200px;
float: left;
background: gray;
margin: 1em;
}
.insideDiv {
display: none;
}
.red {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap"></div>
Related
I'm implementing slide div for creating theme color. It works fine but when I click the outside it's not closing that div and I tried a lot but not working my code so help me out for this..and I research many resources from the internet I got, but don't know how to implement this. here is my code
function clickedThemebtn() {
var ele = document.getElementsByClassName("theme-colors")[0];
if (ele.classList.contains("shown")) {
ele.classList.remove("shown");
} else {
ele.classList.add("shown");
}
}
Here is my fiddle you can Check Here
Please check this fiddle out.
My approach here was to add an fixed positioned div which will occupy the entire screen and it will handle clicking outside.
HTML Outline
<div class='toggleclickoutside' onClick="handleOutsideClick()"></div>
<div id="toggleshown" class="theme-colors">...</div>
JS handler for outside click
function handleOutsideClick() {
var ele = document.getElementsByClassName("theme-colors")[0];
if (ele.classList.contains("shown")) {
ele.classList.remove("shown");
}
}
Css for new div
.toggleclickoutside{
position: fixed;
width: 100vw;
height: 100vh;
top: 0px;
left: 0px;
}
You can attach an event listener to the document, that it triggers the close event. Keep in mind that the following will hide the menu when you click anywhere inside the menu. You need further checks to prevent it.
function clickedThemebtn(e) {
var ele = document.getElementsByClassName("theme-colors")[0];
// If the click is outside of the button, remove the class
if (e.target.id === "slideBtn") {
if (ele.classList.contains("shown")) {
ele.classList.remove("shown");
} else {
ele.classList.add("shown");
}
return;
}
// all other cases: outside the button
ele.classList.remove("shown");
}
document.addEventListener('click', clickedThemebtn);
Updated fiddle
Here's a jQuery solution since the fiddle had jQuery fiddle
You'd have to listen for the click event on the document object, then check if the click was within the theme selector before closing it.
document.addEventListener('click', handleDocumentClick);
function handleDocumentClick(event) {
const themeSelector = getThemeSelector();
if (!themeSelector.contains(event.target)) {
hideThemeSelector();
}
}
function getThemeSelector() {
return document.getElementsByClassName("theme-colors")[0];
}
function hideThemeSelector() {
const themeSelector = getThemeSelector();
themeSelector.classList.remove("shown");
}
function showThemeSelector() {
const themeSelector = getThemeSelector();
themeSelector.classList.add("shown");
}
Note that I added a few handy functions for convenience sake.
I updated your fiddle and now it looks like this: https://jsfiddle.net/0nqzpyko/
I have a sidebar and I want to close it when someone clicks on a link. In my code, the sidebar just closes for a millisecond when I click on an anchor element. How can I fix this without using jQuery?
The a tags are linking to a html page
JS:
var elem = document.getElementById('slidebar').getElementsByClassName('button')[0]
element.addEventListener("click", slide);
function slide() {
document.getElementById('slidebar').classList.toggle('active');
}
var slidebar = document.getElementById('slidebar');
slidebar.addEventListener('click', handleMenuClick);
function handleMenuClick(event) {
if (event.target instanceof HTMLAnchorElement) {
document.getElementById('slidebar').classList.add('close');
}
}
CSS:
#slidebar.active {
left: 0px;
}
#slidebar.close {
display: none;
}
First, make sure you prevent the default event when clicking the anchor tag. Otherwise, it might be re-rendering the page.
But based on your code, it looks like you're adding two functions onto the slidebar. One that closes and one that opens. Since the anchor tag that closes the slidebar is inside the slidebar - when you click it you first fire off the handleMenuClick function and then it bubbles up and fires off the slide function. So it closes and opens quickly.
Instead, add a third element that is used to open the slidebar and attach the slide function there.
Also, you don't need two classes for managing the state of hidden/not hidden. You can just provide a class that sets the display to none and toggle that class list. If you want transition effects you can do that in CSS
Maybe something like this:
window.addEventListener('DOMContentLoaded', e => {
let slidebar = document.getElementById('slidebar')
let collapseButton = slidebar.getElementById('close-button')
let openButton = slidebar.getElementById('open-button')
collapseButton.on('click', toggleClassList)
openButton.on('click', toggleClassList)
const toggleClassList = e => {
e.preventDefault()
slidebar.classList.toggle('hidden')
}
})
#slide-bar.hidden {
display: none;
}
#slide-bar.hidden #close-button {
display: none;
}
#slide-bar #open-button {
display: none;
}
Obviously, it depends a bit on the code you have already written. But this is a basic example that would work. Just need to add the transitions for the sliding effect in CSS
So I have a javascript function that inserts a span on clicking a button. But the problem is when I insert it, it overlaps the other elements. How can I move the other elements down when the button is clicked to make room for the inserted element? And then move them back up when the element is removed? Here is my code:
$(".top-button").on("click", function() {
if (this.nextElementSibling) {
$(this.nextElementSibling).slideToggle(600);
};
});
$(".bottom-button").on("click", function() {
$(this.nextElementSibling).slideToggle(600);
});
And a working demo here http://codepen.io/andrewcockerham/pen/xjgkL/
Basically, when I click on the yellow and green 'buttons' on Entry 1, the MP and IP boxes toggle, but they overlap the other elements (When Entry 1 is collapsed, {click on it}). How can I make the other elements move out to make room when the MP and IP appear, then return to their normal place when the MP or IP disappear?
I've tried appendChild(), insertAfter(), insertBefore(), all without success.
Please forgive the ugly demo and ugly code - its a WIP! Thanks!
So I figured out how to do it, so I'll answer my own question.
Basically I just inserted a blank or empty div 'behind' the inserted span, thus moving the DOM down or up. Here's the JS code:
$(".top-button").on("click", function() {
if (this.nextElementSibling) {
if ($(this.nextElementSibling).css('display') == "none") {
// insert blank element to move the DOM down
$("<div class='top-blank'><span></span></div>").insertBefore($(this).parent());
} else {
// remove blank element when collapse dropdown
$(this).parent().siblings('.top-blank').slideUp(600);
}
$(this.nextElementSibling).slideToggle(600);
};
});
$(".bottom-button").on("click", function() {
if ($(this.nextElementSibling).css('display') == "none") {
$("<div class='blank'><span></span></div>").insertAfter($(this).parent());
} else {
// remove inserted stuff
$('.blank').slideUp(500);
}
$(this.nextElementSibling).slideToggle(600);
});
and the CSS:
.blank {
position: relative;
min-height: 60px;
border-left: 2px solid white;
left: -50px;
}
.top-blank {
position: relative;
min-height: 60px;
}
updated Codepen working example: http://codepen.io/andrewcockerham/pen/xjgkL/
Not sure if this is the best or most proper way, but it works in my case. Interested to hear if there are other better solutions for this.
I was hoping to get some help. I set up a JSfiddle below:
http://jsfiddle.net/y7mEY/102/
I was looking to have the grey div box that appears when the input box is clicked (that will have the search options in it) to close when I click anywhere outside it.
I would like to not load jquery and therefore keep everything in javascript.
Any help?
code below:
HTML
<div id = "searchHousing">
<input type="text" name="value" id="fillIn">
</div>
CSS
.searchBox {
position: absolute;
font-family:Arial;
font-size: 10pt;
color:black;
height: 200px;
width: 200px;
padding-left: 3px;
padding-top: 1px;
border: 1px solid white;
background-color: grey;
}
#fillIn {
width: 200px;
height: 28px;
border-radius: 4px;
font-size: 16px;
margin-bottom: 2px;
#searchHousing {
float: left;
}
Javascript:
var inputSearch = document.getElementById('fillIn');
inputSearch.onclick = function() {
var searchBox = document.createElement("div");
searchBox.className = "searchBox";
document.getElementById('searchHousing').appendChild(searchBox);
};
Thanks,
Ewan
I would suggest to not create new 'div' on click event. This will result in multiple "searchBox" divs when the input box is clicked multiple times. Needless to say, it will require cleanup effort to remove duplicated divs.
Rather, create the searchBox div in HTML and toggle it's visibility on javascript events.
Updated JSFiddle: http://jsfiddle.net/y7mEY/109/
[
var inputSearch = document.getElementById('fillIn');
inputSearch.onclick = function() {
document.getElementById('searchBox').style.display = 'block';
};
inputSearch.onblur = function() {
document.getElementById('searchBox').style.display = 'none';
};
]
If you want to use your current approach, simply use the "onblur" event to remove the element when the element loses focus.
inputSearch.onblur = function() {
document.getElementById('searchHousing').removeChild(document.getElementsByClassName("searchBox")[0]);
}
But as CVG mentions, creating/deleting elements live is a fairly bad idea.
The problem with onBlur as the other answers suggest is that you will then hide the search options div every time you click anything in it (since the input field will lose focus). This is probably not what you're looking for. Instead, you can add a click handler for the document to hide the search options, and then add a click handler for the search housing to prevent event propagation (which keeps the document click handler from hiding the options).
If you click the input box, the handler shows the options
If you click the input box or the options, the event propagation stops
If you click anywhere in the document besides the input box or options, the options are hidden
Updated JSFiddle
var inputSearch = document.getElementById('fillIn');
var searchHousing = document.getElementById('searchHousing')
inputSearch.onclick = function(event) {
document.getElementById('searchBox').style.display = 'block';
};
searchHousing.onclick = function(event) {
event.stopPropagation(); // won't be passed to document.onclick
};
document.onclick = function() {
document.getElementById('searchBox').style.display = 'none';
};
You'll be creating div elements all the time, which isn't any good. You could something along the lines of toggling the display attribute.
Just to make sure, if you want the searchBox to stay open and only close if you're clicking outside the searchBox and fillin elements, then you can just follow the click events and only toggle the display if you're clicking outside both. The other methods will just close it out as long as you're not typing in the input, and if you want to place tools or something within the div, then that would be useless.
document.addEventListener('click', function(e) {
if(e.target.id != "searchBox" && e.target.id != "fillIn")
document.getElementById("searchBox").style.display="none";
});
Full demonstration: JSFiddle
I'm trying to make a blue div that turns red when clicking on it and the red div turns back to blue ( so I can add more events on the click after clicking, so .css isn't really an option)
When clicking on the div when it's blue, it turns red. But when I click the red div it doesn't respond, even when I add a simple alert()
Does anyone know what I'm doing wrong?
This is my current code and a JSFiddle
code:
$("#Blue").click(function(){
$("#Blue").attr("id","Red");
});
$("#Red").click(function(){
$("Red").attr("id","Blue");
});
If anyone could tell me what Exactly I'm doing wrong that would be great, thank you in advance
You need to use event delegation -- your click handlers are bound to the matching elements at the time the code is first run, and only then. Since there's no #Red element at that point in time, that second click handler isn't bound to anything.
$(document).on('click',"#Blue", function(){
$("#Blue").attr("id","Red");
});
$(document).on('click',"#Red", function(){
$("#Red").attr("id","Blue");
});
http://jsfiddle.net/mblase75/HDFyn/
http://api.jquery.com/on
That said, the "proper" way to do this would be to add and remove a class, not change the ID:
$('#btn').on('click', function(){
$(this).toggleClass("red blue");
});
http://jsfiddle.net/mblase75/mKMW6/
.click() binds only to existing elements at the time you call it; it will not bind to a later-created element or an element to which you assign the id later.
The fix is to use event delegation. See here and here for more information.
Also, use classes, instead -- much more flexible.
HTML
<div class="Test blue">Test</div>
jQuery
$(".blue, .red").click(function(){
$(this).toggleClass('red blue')
});
CSS
.Test{
width: 50px;
height: 50px;
}
.blue{
background-color: blue;
}
.red{
background-color: red;
}
Fiddle: http://jsfiddle.net/8FmSt/3/
You could use the class and update the ID like below instead of having 2 function to do that action,
$('.Test').on('click', function () {
this.id = (this.id == 'Blue')?'Red':'Blue';
});
DEMO: http://jsfiddle.net/8FmSt/2/
If it is all about changing color, then use a css to change to color like below,
$('.Test').on('click', function () {
$(this).toggleClass('Red Blue');
});
http://jsfiddle.net/8FmSt/5/
Try:
$(".Test").click(function(){
var id = $(this).attr("id");
if(id == "Red"){
$(this).attr("id","Blue");
}
else{
$(this).attr("id","Red");
}
});
Updated fiddle here.
Let's uncomplicate
HTML
<div class="Test">Test</div>
JQUERY
$(".Test").on('click', function () {
$(this).toggleClass("red");
});
CSS
.Test {
width: 50px;
height: 50px;
background: blue;
}
.red {
background: red;
}