Click through full height element to empty space to add class - javascript

I want to remove .visible class when I click inside of the unfilled space of a full-height header.
Inside of the header I have .container that doesn't have full height.
When I click on the container or its links, it shouldn't remove the class but when I click on remaining space below container it should remove the class.
Is this possible with the given HTML and CSS?
https://codepen.io/rKaiser/pen/EeNoqR
$('body').on('click', '.button', function(){
$('body').toggleClass('visible');
});
$('.visible *:not(.container)').click(function() {
alert('clicked the outside');
$('body').removeClass('visible');
return false;
});

You can bind a click event to the <header>, another click event to its inner <div>, and stop the propagation of the event so that only the more specific one (the div) will be executed:
$( document ).ready(function() {
$('body').on('click', '.button', function(){
$('body').toggleClass('visible');
});
$('header').click(function() {
alert('clicked outside the container');
$('body').removeClass('visible');
return false;
});
$('.container').click(function(e){
alert ('clicked inside the container');
e.stopPropagation();
})
});
* {
padding:0;
margin:0;
}
body.visible header {
display:block;
}
header {
top: 0;
bottom: 0;
position: fixed;
overflow-y: scroll;
overflow-x: hidden;
background-color: rgba(0,0,0,.5);
display: none;
z-index: 999;
width: 100%;
overflow: visible;
}
.container {
background: #ccc;
padding:30px;
}
ul {
padding:0;
margin:0;
}
a {
display:block;
}
.button {
position:absolute;
top:0;
z-index:9999;
background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<div class="button">Button</div>
<header>
<div class="container">
<ul>
<li>asd</li>
<li>asdas</li>
<li>asdsa</li>
<li>asdasda</li>
</ul>
</div>
</header>
</body>
</html>

You should bind click to all elements and check if body has class in it:
$('body *:not(.container)').click(function() {
if($('body').hasClass('visible')){
alert('clicked the outside');
$('body').removeClass('visible');
return false;
}
});

Related

Open a div by clicking and close by clicking outside of it

A div is initially hidden, I want to display it when clicking a button. And once it is visible, I want to hide it when clicking anywhere outside that div.
I'm trying following code, it displays the div, but the problem is in the second part (clicking outside) the box. The second part conflicts with first one so it hides it before displaying.
How can I fix that?
$('button').on('click', function(e){
e.preventDefault();
$('.box').addClass('active');
});
//hide is by clicking outside .box
$(document).on('click', function (e) {
if ($('.box').is(':visible') && !$('.box').is(e.target) && !$('.box').has(e.target).length) {
$('.box').hide();
}
});
button {
margin-bottom: 20px;
}
.box {
width: 200px;
height: 120px;
background: #fab1a0;
display: none;
}
.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click</button>
<div class="box"></div>
You can stop the propagation of your event so that when button is clicked the event doesn't bubble up to the document. Also instead of hide(), just using removeClass(...) should work for you.
Also that event propagation doesn't stop in this button listener itself but from the next event listener which in your case is on the document and that is what we require.
$('button').on('click', function(e){
e.stopPropagation();
$('.box').addClass('active');
});
//hide is by clicking outside .box
$(document).on('click', function (e) {
if ($('.box').is(':visible') && !$('.box').is(e.target) && !$('.box').has(e.target).length) {
$('.box').removeClass('active');
}
});
button {
margin-bottom: 20px;
}
.box {
width: 200px;
height: 120px;
background: #fab1a0;
display: none;
}
.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click</button>
<div class="box"></div>

Toggle won't stay open

I have images (.rv_button) that are acting as buttons to toggle the div's below (#reveal). I want to hover over the button to open the div but right now I can't get the div to stay open. Can someone help me with this?
jQuery(document).ready(function() {
// Hide the div
jQuery('#reveal').hide();
jQuery('.rv_button').on('mouseenter mouseleave', function(e) {
e.preventDefault();
jQuery("#reveal").fadeToggle()(slow, swing, callback);
jQuery('.rv_button').toggleClass('open');
});
});
Rather than using toggleClass(), on mousenter, remove the open class from all of the buttons and add it to e.target or $(this). And on mouseout just remove it from all the buttons.
Also, remove (slow, swing, callback) or use them as arguments in fadeToggle().
e.g.
jQuery("#reveal").fadeToggle('slow');
And to keep the div to stay open, just wrap the buttons and div in a container and listen for the mouseout event on it instead of the buttons themselves.
$(document).ready(function() {
// Hide the div
$('#reveal').hide();
$('.rv_button').on('mouseenter', function(e) {
e.preventDefault();
$('.rv_button').removeClass('open');
$(e.target).addClass('open');
$("#reveal").fadeIn();
});
$('.container').on('mouseleave', function(e) {
e.preventDefault();
$('.rv_button').removeClass('open');
$("#reveal").fadeOut();
});
});
.container {
width: 400px;
}
#reveal {
width: 400px;
height: 400px;
background-color: beige;
text-align: center;
font-size: 2em;
}
.rv_button {
padding: 1em;
background-color: brown;
width: 400px;
box-sizing: border-box;
}
.open {
background-color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="rv_button">Button 1</div>
<div class="rv_button">Button 2</div>
<div class="rv_button">Button 3</div>
<div id="reveal">Reveal</div>
</div>

close overlay except if "special" Div is clicked with jQuery/Javascript

I have a div called "MyDiv". When this div is clicked an overlay is shown with a "MyDiv_subDiv" appended. When user clicks on the overlay the view should disappear but NOT if iser clicks on "MyDiv_subDiv".
I've found a similar question here and tried it out, here is my code:
var $MyDiv = $('#MyDiv');
var $overlay = $('<div id="overlay"></div>');
var $MyDiv_subDiv = $('<div id="MyDiv_subDiv" class="subDiv">\n\
<div class="subDivContent">\n\
<div class="subDivContent">\n\
<p>some content</p>\n\
</div>\n\
</div>\n\
</div>');
//Add overlay
$("body").append($overlay);
//When overlay is clicked
$overlay.click(function () {
//Hide the overlay
$overlay.hide();
$overlay.empty();
});
$MyDiv.click(function (event) {
event.preventDefault();
$overlay.show();
$overlay.append($MyDiv_subDiv);
});
$MyDiv_subDiv.click(function (event) {
event.stopPropagation();
});
#overlay {
background:rgba(0,0,0,0.7);
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
display:none;
text-align:center;
}
.subDiv{
width: 400px;
height: 125px;
margin: 0 auto;
}
#MyDiv_subDiv{
background-color: lightgreen;
}
#MyDiv{
width: 185px;
height: 80px;
background-color: lightgray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="MyDiv">
Click to show MyDiv_SubDiv
</div>
The problem is: It only works when "MyDiv" is clicked first time. When overlay is closed and "MyDiv" is clicked second time and then click on "MyDiv_subDiv" it disappears - and it shouldn't!
Any help is appreciated!
From jquery.empty
To avoid memory leaks, jQuery removes other constructs such as data
and event handlers from the child elements before removing the
elements themselves.
If you want to remove elements without destroying their data or event
handlers (so they can be re-added later), use .detach() instead.
So you have to use .detach to keep the event.
And as .detach is apply on self, not on child, you have to change
$overlay.empty(); to $MyDiv_subDiv.detach(); or $overlay.children().detach();
or you can rebind the event everytime you append it to $overlay.
var $MyDiv = $('#MyDiv');
var $overlay = $('<div id="overlay"></div>');
var $MyDiv_subDiv = $('<div id="MyDiv_subDiv" class="subDiv">\n\
<div class="subDivContent">\n\
<div class="subDivContent">\n\
<p>some content</p>\n\
</div>\n\
</div>\n\
</div>');
//Add overlay
$("body").append($overlay);
//When overlay is clicked
$overlay.click(function () {
//Hide the overlay
$overlay.hide();
$overlay.children().detach();
});
$MyDiv.click(function (event) {
event.preventDefault();
$overlay.show();
$overlay.append($MyDiv_subDiv);
});
$MyDiv_subDiv.click(function (event) {
event.stopPropagation();
});
#overlay {
background:rgba(0,0,0,0.7);
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
display:none;
text-align:center;
}
.subDiv{
width: 400px;
height: 125px;
margin: 0 auto;
}
#MyDiv_subDiv{
background-color: lightgreen;
}
#MyDiv{
width: 185px;
height: 80px;
background-color: lightgray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="MyDiv">
Click to show MyDiv_SubDiv
</div>

Control jQuery resizeable handles when clicked on and out of relevant DIV

I create a bunch of DIVs dynamically. I'm using jQuery resizeable handles on them.
My question is how do I make the handles appear on click/hover and make them disappear when clicked out of the relevant div?
jsFiddle
$('.resizable').on('click', function() {
$(this).addClass('focus');
});
$(document).on('click', function() {
if (!$(e.target).closest('.resizable').length) {
$('.resizable').removeClass('focus');
}
});
You can bind it with a click or a hover.
Click:
$('.resizable').resizable({
handles: 'se'
});
////////////////////////////////////////////////////////////////////////////////////
//how do I get the below working? These $('.resizable') DIV are created dynamically
$('.resizable').on('click', function() {
$(this).addClass('focus');
});
$(document).on('click', function(e) {
if (!$(e.target).closest('.resizable').length) {
$('.resizable').removeClass('focus');
}
});
.resizable{
width: 100px;
height: 100px;
background-color: red;
display: inline-block;
}
.resizable.focus {
background: #f0f;
}
.resizable .ui-resizable-handle {
background-color: black;
display: none !important;
}
.resizable.focus .ui-resizable-handle {
display: block !important;
}
<div id="dragDiv1" class="resizable"></div>
<div id="dragDiv2" class="resizable"></div>
<div id="dragDiv3" class="resizable"></div>
Or, if you want the hover, just replace the .resizable.focus with .resizable:hover. http://jsfiddle.net/sjchn0L8/2/

Removing the selected LI from a UL

I am trying to remove the selected item who class has "selected" but instead of just deleting the LI item, the entire list is being cleared out. I am using jQuery for this.
I've put together a quick fiddle:
http://jsfiddle.net/6QvvC/4/
<!DOCTYPE html>
<html>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="jquery.min.js"></script>
<head>
<style type="text/css">
* {
font-size: 9pt;
font-family: Segoe UI;
}
#refdocs {
border: 0;
padding: 2px;
}
#box1 {
border: 1px solid rgb(170,170,170);
width: 200px;
}
#box2 {
width: 100%;
display: block;
position: relative;
border-bottom: 1px solid rgb(170,170,170);
}
#container {
height: 100px;
overflow-y: scroll;
overflow-x: hidden;
}
#list1 {
width: 100%;
}
#list1 ul {
margin: 0;
padding: 0px;
list-style-type: none;
}
#list1 li {
cursor: default;
padding: 2px;
}
.selected {
background: rgb(228,228,228);
}
</style>
<script type="text/javascript">
window.onload = function() {
refresh_list()
}
function remove_selected_item() {
if ( $('#list1 ul li').hasClass("selected") ) {
alert("yup")
$('#list1 ul li').remove()
}
else {
alert("nope")
}
}
function refresh_list() {
$('#list1 ul li').click(function () {
$('#list1 ul li').removeClass('selected');
$(this).addClass('selected');
document.getElementById('refdocs').value = $(this).text()
});
}
</script>
</head>
<body>
<div id="box1">
<div id="box2"><input type="text" id="refdocs"></div>
<div id="container">
<div id="list1">
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
</div>
</div>
<input type="button" value="delete" onclick="remove_selected_item()">
</body>
</html>
Function can be simplified:
function remove_selected_item() {
$('#list1 ul li.selected').remove()
}
You need to removed selected item - so you select the li with class .selected and just remove it.
Demo: http://jsfiddle.net/6QvvC/3/
The jQuery selector #list1 ul li matches ALL li elements inside an ul inside an element with id list1.
hasClass returns true if ANY of the matched elements contains the given class.
remove removes all matched elements, which in the given case is all list elements. That is why the list is cleared.
Maybe dive into the power of jQuery selectors a bit: http://codylindley.com/jqueryselectors/
You can not only select elements based on their type or ID, but also on their class, their attributes, their position in the DOM (parents, siblings, children) and their state (e.g. hover).
When installing click handlers on list elements, the event delegation pattern is also pretty useful: https://learn.jquery.com/events/event-delegation/ It might help you to get a better understanding of how events and handler installation work with jQuery. It at least was some kind of revelation for me.

Categories

Resources