how to close an element upon the click of another element - javascript

I want each element to close upon the click of the "x" icon using pure javascript. i'm actually new to javascript so i am trying some stuffs out. Below is my code and what i have been able to do.
I want each element to close upon the click of the "x" icon.
var closeBtnTask = document.querySelectorAll(".times");
for (var i = 0; i < closeBtnTask.length; i++) {
closeBtnTask[i].addEventListener("click", function() {
var panel = document.querySelectorAll(".taskpanel");
for (var x = 0; x < taskpanel.length; x++) {
Things[x].style.display = "none";
}
});
}
.task-box {
float: left;
width: 100%;
}
.task-wrapper {
width: 400px;
background: #f5f5f5;
}
ul.mytask {
padding: 0px;
margin: 0px;
padding-left: 5px;
}
ul.mytask li {
list-style: none;
line-height: 34px;
border-bottom: 1px solid #ddd;
}
.mytask span {
float: right;
padding-right: 10px;
cursor: pointer;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<div class="task-box">
<div class="task-wrapper">
<ul class="mytask">
<li class="taskpanel">First Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Second Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Third Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fourth Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fifth Task <span><i class="fa fa-close times"></i></span></li>
</ul>
</div>
</div>

You can delegate in plain JS too
document.querySelector(".mytask").addEventListener("click",function(e) {
let tgt = e.target;
if (tgt.matches(".fa-close")) tgt.closest("li").style.display="none";
})
.task-box {
float: left;
width: 100%;
}
.task-wrapper {
width: 400px;
background: #f5f5f5;
}
ul.mytask {
padding: 0px;
margin: 0px;
padding-left: 5px;
}
ul.mytask li {
list-style: none;
line-height: 34px;
border-bottom: 1px solid #ddd;
}
.mytask span {
float: right;
padding-right: 10px;
cursor: pointer;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<div class="task-box">
<div class="task-wrapper">
<ul class="mytask">
<li class="taskpanel">First Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Second Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Third Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fourth Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fifth Task <span><i class="fa fa-close times"></i></span></li>
</ul>
</div>
</div>

Your code was just a bit wrong, I fixed it here
https://jsfiddle.net/L81t9ym6/
var closeBtnTask = document.querySelectorAll(".times");
for (var i = 0; i < closeBtnTask.length; i++) {
closeBtnTask[i].addEventListener("click", function() {
var panel = document.querySelectorAll(".taskpanel");
for (var x = 0; x < panel.length; x++) {
panel[x].style.display = "none";
}
});
}
Note: this closes EVERY element when you click ANY x, rather than just the element that the click happened on.
edit
here's the code for closing JUST the panel you clicked
var closeBtnTask = document.querySelectorAll(".times");
for (var i = 0; i < closeBtnTask.length; i++) {
closeBtnTask[i].addEventListener("click", function(ev) {
var tp = ev.target.closest('.taskpanel');
tp.style.display = "none";
});
}
I didn't know that javascript has a native .closest method now, that's useful! https://developer.mozilla.org/en-US/docs/Web/API/Element/closest

use this Javascript
working demo is here https://jsfiddle.net/Lg7bjr3k/
$('.times').click(function(){
$(this).parent().parent().hide();
})

Related

JavaScript Sliding Sidebar Menu

I'm trying to create this sidebar menu to the right using HTML CSS transitions and standard JavaScript and I also imported some FontAwesome icons.
My code looks like this (the JavaScript code is inside the HTML document):
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sidebar Menu</title>
<script src="https://kit.fontawesome.com/b1956a1c85.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="sidebar">
<ul>
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-user"></i></li>
<li><i class="fas fa-cogs"></i></li>
<li><i class="fas fa-wrench"></i></li>
<li><i class="fas fa-tools"></i></li>
<li><i class="fas fa-lock"></i></li>
</ul>
</div>
<i class="fas fa-bars"></i>
<script>
let btn = document.querySelector('.button'),
side = document.querySelector('.sidebar');
btn.addEventListener('click', function() {
if(btn.innerHTML === '<i class="fas fa-bars"></i>') {
btn.innerHTML = '<i class="fas fa-times"></i>';
side.style.marginLeft = '0px';
} else if (btn.innerHTML === '<i class = "fas fa-times"></i>') {
btn.innerHTML = '<i class= "fas fa-bars"></i>';
side.style.marginLeft = '-25px';
}
});
</script>
</body>
</html>
And my CSS page looks like this:
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #af8f36;
}
.sidebar {
float: left;
width: 120px;
height: 100vh;
background: #6e36af;
overflow: hidden;
margin-left: -125px;
transition: 0.5s;
}
.sidebar ul {
list-style: none;
}
.sidebar ul li a {
text-decoration: none;
color: #fff;
height: 100px;
width: 100%;
font-size: 40px;
line-height: 100px;
display: block;
text-align: center;
transition: 0.5s;
}
.sidebar ul li a:hover {
background: #5d2e94;
}
.button {
float: left;
padding: 27px 20px;
font-size: 40px;
text-decoration: none;
color: #333;
}
For some reason the sidebar won't slide to the right when I click on the hamburger button. Can someone explain to me why? Is my JavaScript code correct?
I found your problem:
In your JS code you check if the inner HTML of the Button is:
<i class="fas fa-bars"></I>
But Fontawesome adds a new Attribute to your <I> Element. So now it's inner HTML is:
<i class="fas fa-bars" aria-hidden="true"></I>
I would recommend using a variable in js or something similar to check/save wether your menu is open or not.
Your way could easy lead to more bugs.
In Addition, for better performance I would recommend animating with Transform not margin, if possible.

Javascript toggle working but shows unstyled menu

On my ruby on rails 5 app I have a menu button that uses javascript to toggle the menu, the toggle function is showing and hiding the menu but the menu is not styled with css anymore
onclick the menu toggles like it should but all the elements are not styled, I dont know if its related to rails or I am missing something here
//Toggle between adding and removing the "show_for_mobile" class to admin_side_bar when the user clicks on the icon
function toggleNav() {
var x = document.getElementById("admin_side_bar");
console.log(x.className)
if (x.className === "admin_side_bar") {
x.className += "show_for_mobile";
} else {
x.className = "admin_side_bar";
}
}
.admin_side_bar {
width: 70%;
height: 50vh;
background-color: #e2e6e8;
position: absolute;
left: 0;
top: 60px;
padding: 20px 10px;
display: none;
}
//show side bar on click
.show_for_mobile {
display: block;
}
.admin_side_bar>ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.admin_side_bar>ul>a {
color: #3d3d3d;
font-size: 19px;
text-decoration: none;
}
.admin_side_bar>ul>a:hover {
color: #06bed3;
}
.admin_side_bar .fas {
margin-right: 20px;
color: #afaeae;
}
.admin_side_bar .fas:hover {
color: #7a7a7a;
}
.admin_side_bar>ul>a>li {
margin-bottom: 20px;
}
<!--Admin side bar-->
<div class="admin_side_bar" id="admin_side_bar">
<ul>
<a href="#">
<li><i class="fas fa-home fa-fw fa-lg"></i>Home</li>
</a>
<a href="#">
<li><i class="fas fa-tshirt fa-fw fa-lg"></i>Items</li>
</a>
<a href="#">
<li><i class="fas fa-gift fa-fw fa-lg"></i>Orders</li>
</a>
<a href="#">
<li><i class="fas fa-chart-line fa-fw fa-lg"></i>Stats</li>
</a>
<a href="#">
<li><i class="fas fa-newspaper fa-fw fa-lg"></i>Blog</li>
</a>
</ul>
</div>
When you add the .show_for_mobile class the original display:none from .admin_side_bar still takes precedence. If all you really want to do is show the nav then you can use x.style.display = "block"; to overwrite display:none from the admin_side_bar class
x.style.display="block" works because it adds inline style which is the highest CSS specificity (it overwrites all other css rules).
From CSS specificity
Inline styles added to an element (e.g., style="font-weight:bold") always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.
document.getElementById("toggleButton").addEventListener("click", toggleNav);
//Toggle between adding and removing the "responsive" class to topnav when the user clicks on the icon
function toggleNav() {
var x = document.getElementById("admin_side_bar");
if (x.className === "admin_side_bar") {
x.className += " show_for_mobile";
x.style.display = "block";
} else {
x.className = "admin_side_bar";
x.style.display = "none";
}
}
.admin_side_bar {
width: 70%;
height: 50vh;
background-color: #e2e6e8;
position: absolute;
left: 0;
top: 60px;
padding: 20px 10px;
display: none;
}
//show side bar on click
.show_for_mobile {
display: block !important;
}
.admin_side_bar>ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.admin_side_bar>ul>a {
color: #3d3d3d;
font-size: 19px;
text-decoration: none;
}
.admin_side_bar>ul>a:hover {
color: #06bed3;
}
.admin_side_bar .fas {
margin-right: 20px;
color: #afaeae;
}
.admin_side_bar .fas:hover {
color: #7a7a7a;
}
.admin_side_bar>ul>a>li {
margin-bottom: 20px;
}
<button id="toggleButton">Toggle Nav</button>
<!--Admin side bar-->
<div class="admin_side_bar" id="admin_side_bar">
<ul>
<a href="#">
<li><i class="fas fa-home fa-fw fa-lg"></i>Home</li>
</a>
<a href="#">
<li><i class="fas fa-tshirt fa-fw fa-lg"></i>Items</li>
</a>
<a href="#">
<li><i class="fas fa-gift fa-fw fa-lg"></i>Orders</li>
</a>
<a href="#">
<li><i class="fas fa-chart-line fa-fw fa-lg"></i>Stats</li>
</a>
<a href="#">
<li><i class="fas fa-newspaper fa-fw fa-lg"></i>Blog</li>
</a>
</ul>
</div>

jQuery .each() span.Title get .text() connect with "/"

Live Snippet
$(document).ready(function() {
"use strict";
var PushState, Current;
$(document).on('click', function(e) {
if ($(e.target).closest($('.page-breadcrumb')).length) {
$(e.target).closest('li').nextAll().remove();
PushState = $('.page-breadcrumb').children('li').each(function() {
return $(this).children().find('span.Title').text();
}).get().join("/");
console.log(PushState);
Current = $(e.target).closest('a').html();
$(e.target).closest('li').remove();
$('.page-breadcrumb').append(Current);
}
});
});
.page-bar {
box-sizing:border-box;
position: relative;
width:100%;
height:61px;
padding: 0 20px;
}
.page-bar .page-breadcrumb {
display: inline-block;
float: left;
padding: 20px 0;
margin: 0;
list-style: none;
}
.page-bar .page-breadcrumb>li {
display: inline-block;
}
.page-bar .page-breadcrumb>li,
.page-bar .page-breadcrumb>li a {
font-size: 14px;
color: #A3A3A3;
text-decoration: none;
}
.page-bar .page-breadcrumb>li a:hover {
text-decoration: underline;
}
.page-bar .page-breadcrumb>li>i.fa-arrow-right {
font-size: 12px;
margin: 0 5px;
position: relative;
opacity: .4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<div class="page-bar">
<div class="page-breadcrumb">
<li>
<i class="fa fa-home"></i> <span class="Title">Dashboard</span>
</li>
<li><i class="fa fa-arrow-right"></i></li>
<li>
<a href="javascript:;">
<i class="fa fa-user"></i>
<span class="Title">Account</span>
</a>
</li>
<li><i class="fa fa-arrow-right"></i></li>
<li>
<a href="javascript:;">
<i class="fa fa-envelope"></i>
<span class="Title">Messages</span>
</a>
</li>
<li><i class="fa fa-arrow-right"></i></li>
<li></li>
<i class="fa fa-plus"></i>
<span class="Title">Compose</span>
</div>
</div>
Outcome
Dependant on where you click, the outcome is as follows (I clicked on 'Account'):
[object HTMLLIElement]/[object HTMLLIElement]/[object HTMLLIElement]
What I'm Trying To Achieve
If $(e.target) is $('.page-breadcrumb li a')
Initiate everything the script currently does
PushState should return (clicking on Messages example):
Dashboard/Account/Messages
Questions
How do I return the text only of each span.Title connectings all with '/'?
Using return in each callback is causing you to loose the data .If you even have this
PushState = $('.page-breadcrumb').children('li').each(function() {
return 0;
}).get().join("/");
you would still be getting the same results because what you are getting is just the outer <li> elements .So instead of returning use some variable in which you can store the individual results of eachs callback
Make some global like variable var v =[]; outside each and use below modification
$('.page-breadcrumb').children('li').each(function() {
var txt = $(this).children().find('span.Title').text();
if(txt != '')
v.push(txt);
});
PushState = v.join('/');
Target the selector you want in the event listener:
Change
$(document).on('click', function(e) {
To
$(document).on('click','.page-breadcrumb a' function(e) {
// "this" will be instance of .page-breadcrumb a
var spanText = $(this).find('.Title').text()
.....

Is it possible to apply hover property based on width of a particular area?

function shrinkMenu(){
document.getElementById("aside").className="aside-after-click";
document.getElementById("main").className="main-after-click";
var l= document.getElementsByClassName('hide-menu');
for (var j = 0;j < l.length ; j++) {
l[j].classList.add("hide-menu-after-click");
}
}
ul,li {
list-style:none;
}
#aside {
float:left;
/*width:220px;*/
height:60px;
background-color:red;
}
.aside{
width:220px;
}
.aside-after-click{
width:60px;
}
#main {
float:left;
height:60px;
background-color:green;
}
.main{
width:calc(100% - 220px);
}
.main-after-click{
width:calc(100% - 60px);
}
#button{
margin-top:10px;
margin-left:10px;
}
.hide-menu-after-click{
display:none;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<div id="aside" class="aside">
<ul>
<li>
<i class = "fa fa-glass" > </i>
<span class="hide-menu"> menu title1 </span>
</li>
<li>
<i class = "fa fa-glass" > </i>
<span class="hide-menu"> menu title2 </span>
</li>
<li>
<i class = "fa fa-glass" > </i>
<span class="hide-menu"> menu title3 </span>
</li>
</ul>
</div>
<div id="main" class="main">
<button type="button" onclick="shrinkMenu();" id="button">shrink menu</button>
</div>
On the above code mainly we have two parts 1.aside 2.main. The aside part will shrink when we click on the button and also the menu title will hided.i need to be displayed the menu titles on hover on corresponding icon.is it possible to apply hover property based on width of a particular area(using # media rule) ? or any other alternatives to solve this ?
Note: the hover property doesn't need to be work when the aside have width :220px (works only when width: 60px)
Here, using the ~ general siblings CSS combinator, together with :hover pseudoclass:
function shrinkMenu() {
document.getElementById("aside").className = "aside-after-click";
document.getElementById("main").className = "main-after-click";
var l = document.getElementsByClassName('hide-menu');
for (var j = 0; j < l.length; j++) {
l[j].classList.add("hide-menu-after-click");
}
}
ul,
li {
list-style: none;
}
#aside {
float: left;
/*width:220px;*/
height: 60px;
background-color: red;
}
.aside {
width: 220px;
}
.aside-after-click {
width: 60px;
}
.aside-after-click:hover {
width: 220px;
}
#main {
float: left;
height: 60px;
background-color: green;
}
.main,
.aside-after-click:hover ~ .main-after-click {
width: calc(100% - 220px);
}
.main-after-click {
width: calc(100% - 60px);
}
#button {
margin-top: 10px;
margin-left: 10px;
}
.hide-menu-after-click {
display: none;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<div id="aside" class="aside">
<ul>
<li>
<i class="fa fa-glass"> </i>
<span class="hide-menu"> menu title1 </span>
</li>
<li>
<i class="fa fa-glass"> </i>
<span class="hide-menu"> menu title2 </span>
</li>
<li>
<i class="fa fa-glass"> </i>
<span class="hide-menu"> menu title3 </span>
</li>
</ul>
</div>
<div id="main" class="main">
<button type="button" onclick="shrinkMenu();" id="button">shrink menu</button>
</div>

Links in the dropdown menu are not working

Having an issue getting any kind of interaction from these links in the dropdown. I tried various link types and none are responding to clicks.
<li class="headerContact">
Contact Us<i class="fa fa-envelope"></i>
</li>
<li class="menuLink">
Features<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Science<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Videos<i class="fa fa-caret-right right"></i>
</li>
The test page is at bruxzir.jgallardo.me/header.aspx.
This is the full code for that page that I am using during development. (I am not doing this in production)
<!doctype html>
<html class="no-js" lang="en">
<head>
<!--#include file="/pages/_includes/head-default.html" -->
<style>
.active .dropdown { display:block; }
.dropdown { display:none; }
.header {
background-color: #333;
color: #fff;
height: 36px;
width: 100%;
line-height: 36px;
}
/* should be replaced with image */
.headerLogo {
display:inline;
font-size: 24px;
line-height: 36px;
padding-left: 6px;
}
.headerMenu{
float:right;
font-size: 36px;
margin-right: 6px;
}
.headerLogo a, .headerMenu a { color:#fff; text-decoration:none; }
.headerNav {
background-color: #292c2d;
overflow:hidden;
width:100%;
}
.headerNav a { color: #f3f3f3; text-decoration: none; }
.headerNav ul {
list-style-type: none;
margin:0;
padding-left: 0;
text-align:left;
}
.headerNav ul li {
border-bottom: 1px dotted #34393b;
display:inline-block;
width: 100%;
}
.menuLink a {
display:block;
line-height: 48px;
padding: 0 12px;
}
.headerNav ul li a i {
line-height: 48px;
}
.right { float:right; }
.findLabLink {
background-color: #48e0a4;
margin: 0 auto;
text-align: center;
width: 84%;
}
.findLabLink a {
color: rgb(40,43,45);
display:block;
line-height: 48px;
}
.headerContact {
line-height: 60px;
text-align: center;
}
.headerContact a {
background-color: #464241;
border-radius: 2px;
letter-spacing: 3px;
padding: 8px 18px;
}
.headerContact i {
margin-left: 30px;
}
</style>
</head>
<body>
<div class="container">
<div id="mainContent" class="block push">
<div class="row">
<div class="large-12 columns">
<h1>BruxZir Home Page</h1>
<div id="dd" class="wrapper-dropdown-3 dd" tabindex="1">
<div class="header">
<div class="headerLogo">
<!-- change # to / -->
BruxZir
</div>
<div class="headerMenu">
≡
</div>
</div> <!--/ end of .header -->
<div class="headerNav">
<ul class="dropdown">
<li class="findLabLink">
Find An Authorized Lab
</li>
<li class="headerContact">
Contact Us<i class="fa fa-envelope"></i>
</li>
<li class="menuLink">
Features<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Science<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Videos<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Cases<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Testimonials<i class="fa fa-caret-right right"></i>
</li>
</ul>
</div> <!-- headerNav -->
</div>
</div>
</div>
</div> <!-- end of #mainContent -->
</div>
<!-- JavaScript Declarations
======================== -->
<!--#include file="/pages/_includes/js-default.html" -->
<script>
// all of this is for the menu
function WTF() {
window.location.href = "";
}
function DropDown(el) {
this.dd = el;
this.placeholder = this.dd.children('span');
this.opts = this.dd.find('ul.dropdown > li');
this.val = '';
this.index = -1;
this.initEvents();
}
DropDown.prototype = {
initEvents: function () {
var obj = this;
obj.dd.on('click', function (event) {
event.stopPropagation();
if (event.target.className === 'dd') {
$(this).toggleClass('active');
}
return false;
});
}
}
$(function () {
var dd = new DropDown($('#dd'));
$(document).click(function () {
// all dropdowns
$('.wrapper-dropdown-3').removeClass('active');
});
});
</script>
</body>
</html>
You're returning false and stopping event bubbling for all clicks withing the $('#dd') element right now. I think you only want to do that for your initial menu toggling click on the $('.dd') element.
if (event.target.className === 'dd') {
$(this).toggleClass('active');
event.stopPropagation(); // not sure why you need this
return false;
}
Look at the jsFiddle. I removed a lot of javascript and used one jQuery. I am not sure what you need, let me know if there something I missed.
$(function () {
$('.dd').on('click', function(event){
event.stopPropagation();
$('.wrapper-dropdown-3').toggleClass('active');
});
$(document).click(function () {
// all dropdowns
$('.wrapper-dropdown-3').removeClass('active');
});
});

Categories

Resources