clicking for show div but hide again + make body position stay - javascript

i make profile form, i clicked this, form is show but hidden instally
I want to click the link if the form appears without disappearing again, and if clicked outside in the form, from hidden and the web position stay without scrolling to up
i code used
$('.profile-link').click(function(e) {
$(".profile-frm").addClass("show-prfrm");
});
$(document).mouseup(function(e) {
var container = $(".profile-frm");
var clickfuncion = $('.profile-link').click;
if (container.is(':visible')) {
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0) {
e.preventDefault();
$('body').width($('body').width());
container.removeClass("show-prfrm");
}
}
});

I think the only tricky part is to put a click handler on the document and do different things when the target element is the button, the menu, or anything else.
const button = document.querySelector('button');
const menu = document.querySelector('#menu');
document.addEventListener('click', event => {
menu.classList.add('hide');
if (event.target == button || event.target == menu)
menu.classList.remove('hide');
});
#menu {
position: absolute;
top: 50;
border: 1px solid #555;
background-color: #555;
border-radius: 10px;
height: 175px;
width: 100px;
}
.hide {
display: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<button>Menu</button>
<div id="menu" class="hide"></div>

Related

Detect if element clicked is a pseudo element

I have the same situation here, but it's not answered well. I have this code for a workaround:
window.addEventListener('load', () => {
// sticky profile notes
const notes = document.querySelector('#textarea-notes'); // Get textarea element
const headerDiv = document.createElement("div"); // Create a <div> element
headerDiv.id = 'div-header';
headerDiv.innerHTML = 'Add Notes'; // Insert instructions
// add header on top
notes.parentNode.insertBefore(headerDiv, notes);
// minimize sticky
headerDiv.addEventListener('click', e => {
// detect if cursor type is pointer
console.log(e.target.style.cursor);
});
});
#div-header {
padding: 10px;
cursor: move;
background-color: #ffffcc;
}
#div-header:after {
margin-left: 10px;
cursor: pointer;
content: 'button';
}
#textarea-notes {
background-color: #ffffcc;
width: 100%;
}
<textarea id="textarea-notes">
</textarea>
wherein I aim to check what type of mouse pointer the user has when clicking the div with the div element.
The problem is when I log the cursor type, it shows an empty space. How do I know the cursor type? And is there a better way to identify if the clicked element is a pseudo-element?
Since you can't detect events on pseudo elements you can insert separate elements into the headerDiv and check the target of the click event to accomplish the same objective. (Or only apply events to the new child elements)
Here I created two spans for "add notes" and "button" texts which get appended to the new div. A new css rule for the button span applies the margin and pointer cursor
window.addEventListener('load', () => {
// sticky profile notes
const notes = document.querySelector('#textarea-notes'); // Get textarea element
const headerDiv = document.createElement("div"); // Create a <div> element
headerDiv.id = 'div-header';
// Create two spans to insert in headerDiv
const notesTitle = document.createElement('span')
notesTitle.innerHTML = 'Add Notes'; // Insert instructions
// this span could also be a real <button>
const notesBtn = document.createElement('span');
notesBtn.textContent = 'button';
notesBtn.className = 'notes-btn'
headerDiv.append(notesTitle)
headerDiv.append(notesBtn)
// add header on top
notes.parentNode.insertBefore(headerDiv, notes);
// minimize sticky
headerDiv.addEventListener('click', e => {
let msg = 'Parent clicked';
if(e.target.matches('.notes-btn')){
msg = 'Button clicked';
}
console.log(msg)
});
});
#div-header {
padding: 10px;
cursor: move;
background-color: #ffffcc;
}
/*#div-header:after {
margin-left: 10px;
cursor: pointer;
content: 'button';
}*/
#div-header .notes-btn{
margin-left: 10px;
cursor: pointer;
}
#textarea-notes {
background-color: #ffffcc;
width: 100%;
}
<textarea id="textarea-notes">
</textarea>

Hide an expanded menu when clicking outside of the container: how to use code snipet

I have a menu that open a sub-menu section onclick (let's name the container: "sub-menu").
I would like "sub-menu" to disapear if the user click outside of it / on the rest of the page.
It seems to be solved on How do I detect a click outside an element?
But I can't get how to use the code snipet from the second most popular answer:
export function hideOnClickOutside(selector) {
const outsideClickListener = (event) => {
const $target = $(event.target);
if (!$target.closest(selector).length && $(selector).is(':visible')) {
$(selector).hide();
removeClickListener();
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
Could you please guide me on how to use it?
I edited, and included a basic example. -> I want sub menu to also close when clicking on the "white" space. But not on the parent "main menu" element.
document.getElementById("main-menu").addEventListener("click", function() {bouttonexpand('sub-menu-class')});
function bouttonexpand(id) {
var elemeacacher = document.getElementsByClassName(id);
if (elemeacacher[0].style.display != "none"){
for(var y=0;y<elemeacacher.length;y++)
elemeacacher[y].style.display = "none";
}
else {
for(var y=0;y<elemeacacher.length;y++)
elemeacacher[y].style.display = "block";
}
}
#main-menu {
display:inline-block;
height:20px;
width:100px;
background: blue;
padding: 5%;
}
#sub-menu {
display:inline-block;
height:50px;
width:50px;
background: red;
display: none;
}
<div><div id="main-menu">Main menu</div></div>
<div><div id="sub-menu" class="sub-menu-class">Sub menu</div></div>
Thanks
By using jQuery, you can bind to the document click event and hides the div container when the clicked element isn’t the container itself or descendant of the div element.
var container = $("#sub-menu");
if (!container.is(event.target) && !container.has(event.target).length) {
container.hide();
}
If you want to hide that container without being tested the container itself or descendant of the div element just remove the condition and simply use container.hide();.
Also, rather than setting display: none; on sub-menu in the CSS, set it manually so that you can toggle the sub-menu from the very first click.
Have a look at the snippet below:
var x = document.getElementById("sub-menu");
x.style.display = "none";
$(document).click(function (evt) {
if ($(evt.target).is('#main-menu')) { // control click event if it's main-menu
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
else {
var container = $("#sub-menu");
if (!container.is(event.target) && !container.has(event.target).length) { // if you don't want that remove the condition and write container.hide(); only
container.hide();
}
}
});
#main-menu {
display: inline-block;
height: 20px;
width: 100px;
background: blue;
padding: 5%;
}
#sub-menu {
display: inline-block;
height: 50px;
width: 50px;
background: red;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<div id="main-menu">Main menu</div>
<div id="sub-menu" class="sub-menu-class">Sub menu</div>

fadeToggle on body click

I have this div which shows/hides with display:none/block by clicking on an id #cart. The div opens and closes by clicking on element with the id but I want to close the div on body click too. How can I do it please?
Code I am using is below:
jQuery("#cart").on("click", function() {
jQuery(".shopping-cart").fadeToggle( "fast");
});
jQuery("#cart, body").on("click", function() {
jQuery(".shopping-cart").fadeToggle("fast");
});
What you can do is add a listener to the entire window and check for clicks. When there is a click, we check which element has been clicked and check on whether it's the element. We repeat this for the parent element as well.
<!DOCTYPE html>
<html>
<head>
<script>
function checkClickOutsiteElement(clickedElement, elementToCheck){
var iterator = clickedElement;
while(true){
// The click was in the element.
if( iterator === elementToCheck )
return;
// Go to the parent.
if( !iterator.parentElement ){
alert('outside menu');
return;
}
iterator = iterator.parentElement;
}
}
window.addEventListener('click', function(event){
checkClickOutsiteElement(event.target, document.getElementById('menu'));
});
</script>
</head>
<body>
<div class="wrapper">
<div id="menu" style="width: 100px; height: 100px; background-color: red;"></div>
</div>
<div class="wrapper">
<div id="not_menu" style="width: 100px; height: 100px; background-color: green;"></div>
</div>
</body>
</html>
You probably want two separate functions, since your cart button should toggle both ways, but the body click handler should only toggle out.
Protip: on() isn't doing anything for you that click() wouldn't, the way you're using it. The latter is a bit cleaner.
jQuery("#cart").click(function() {
jQuery(".shopping-cart").fadeToggle("fast");
});
jQuery("body").click(function() {
jQuery(".shopping-cart").fadeOut("fast");
});
Protip 2: Easily and safely alias jQuery to $ like so:
jQuery(function($) { // document ready with dollar alias
$("#cart").click(function() {
...
});
I have this div which shows/hides with display:none/block by clicking
on an id #cart. The div opens and closes by clicking on element with
the id but I want to close the div on body click too.
In vanilla javascript, you can:
write a function to show / hide the div
add a click event listener to #cart
add a click event listener to body
Working Example:
// Grab #cart
const cart = document.getElementById('cart');
// Grab .myDiv
const myDiv = document.getElementsByClassName('div')[0];
// Function to toggle .myDiv
const toggleMyDiv = (e) => {
if (e.target === e.currentTarget) {
myDiv.dataset.display = (myDiv.dataset.display === 'show') ? 'hide' : 'show';
}
}
// Add Click Event Listener to #cart
cart.addEventListener('click', toggleMyDiv, false);
document.body.addEventListener('click', toggleMyDiv, false);
body,
#cart {
cursor: pointer;
}
div {
display: inline-block;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
font-weight: bold;
}
#cart {
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
}
.div {
color: rgb(255, 0, 0);
background-color: rgb(255, 255, 0);
}
.div[data-display="show"] {
opacity: 1;
}
.div[data-display="hide"] {
opacity: 0;
}
<div id="cart">Cart</div>
<div class="div show" data-display="show">myDiv</div>

Handle dropdown's focus state

I am currently making a dropdown component in pure JavaScript. When the user click on the dropdown toggle, the content gain focus and its content is being displayed. When the user click outside of it, then the content loses its focus and it gets hidden.
So far, it works great. However, I am encountering two problems.
The first one is that when an element inside the dropdown is clicked (eg: anchor tags), the dropdown loses focus, which it shouldn't.
The second one is that when the dropdown toggle is clicked while the dropdown content is being displayed, the dropdown should close instead of closing then re-opening due to the click registered on the dropdown toggle.
HTML:
<div class="dropdown">
Dropdown toggle
<div class="dropdown-content" tabindex="0">
<ul>
<li>
My profile
</li>
<li>
Log out
</li>
</ul>
</div>
</div>
CSS:
.dropdown {
position: relative;
}
.dropdown.is-open .dropdown-content {
display: block;
}
.dropdown-content {
display: none;
position: absolute;
top: 100%;
width: 100%;
padding: 0.5rem 0;
background: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
JS:
class Dropdown {
constructor(element) {
this.element = element;
this.toggle = this.element.querySelector('.dropdown-toggle');
this.content = this.element.querySelector('.dropdown-content');
this.bindings();
}
bindings() {
this.toggle.addEventListener('click', this.open.bind(this));
this.content.addEventListener('keydown', this.handleKeyDown.bind(this));
this.content.addEventListener('focusout', this.close.bind(this));
}
open(e) {
e.preventDefault();
this.element.classList.add('is-open');
this.content.focus();
}
close(e) {
this.element.classList.remove('is-open');
}
handleKeyDown(e) {
if (e.keyCode === 27) {
this.close(e);
}
}
}
document.querySelectorAll('.dropdown').forEach(dropdown => new Dropdown(dropdown));
I have been trying to get my head around on how I would solve these issues without any luck. Any idea on how to solve these issues?
After some testing I found a solution that works. Try the code below
class Dropdown {
constructor(element) {
this.element = element;
this.toggle = this.element.querySelector('.dropdown-toggle');
this.content = this.element.querySelector('.dropdown-content');
this.bindings();
}
bindings() {
this.toggle.addEventListener('click', this.open.bind(this));
this.content.addEventListener('keydown', this.handleKeyDown.bind(this));
this.element.addEventListener('focusout', this.onFocusOut.bind(this),true);
}
onFocusOut(e) {
if (!this.element.contains(e.relatedTarget)) {
this.close(e)
}
}
open(e) {
e.preventDefault();
this.element.classList.toggle('is-open');
this.content.focus();
}
close(e) {
e.preventDefault();
this.element.classList.remove('is-open');
}
handleKeyDown(e) {
if (e.keyCode === 27) {
this.close(e);
}
}
}

Div containing input disapears on mouseout

I would like to keep a div visible while the mouse is in the bounds of the div, the code works until it hovers over the input. I would like a sign up form appear onmouseover and when the sign in is complete and the mouse moves off the div is no longer visible. jsFiddle Demo
HTML
<div class="members">
Members
<div id="sign-up-form" class="sign-up-form">
<input type="text" name="firstName">
</div>
</div>
JS
var signUp = document.getElementById('signUp');
var signUpForm = document.getElementById('sign-up-form');
signUp.onmouseover = function(){
signUpForm.style.display = 'block';
}
signUpForm.onmouseout = function(){
signUpForm.style.display = 'none';
}
CSS
#signUp{
position: relative;
background-color: red;
color: white;
padding: 6px;
}
#sign-up-form{
display: none;
position:absolute;
top: 32px;
left: 8px;
background-color: rgba(0,83,159,0.6);
padding: 15px;
}
I would do it this only with CSS:
#sign-up-form {
display: none;
}
.members:hover #sign-up-form {
display: block;
}
This example uses mouseover and mouseout event listeners and a function that will listen to all children elements before changing the display of the signUpForm element.
function outVis(event) {
var e = event.toElement || event.relatedTarget;
if (e.parentNode == this || e == this) {
return;
}
signUpForm.style.display = 'none';
}
http://jsfiddle.net/9xhb532v/1/

Categories

Resources