I have a button enclosing an icon. I believe the icon is interfering with my click event. I am only able to click on the icon margins to activate the onclick event, but nothing happens when I click on the icon. I replaced the icon with some text and the button onclick works perfectly fine. I have tried z-index to put the icon behind the button, but to no avail. Can someone explain why the icon blocks the click from occurring and how I can fix it?
html:
<div class="navMenu">
<button onclick="navClick()" class="navMenu-button"><i class="fas fa-bars"></i></button>
<div id="navList" class="navMenu-content">
Home
About
Resume
</div>
sass:
.navMenu{
position: relative;
display: inline-block;
margin-top:5px;
margin-left:5px;
&-button {
background-color: #615b5b;
border-radius:50%;
color: white;
padding: 7px;
opacity:0.7;
border:none;
font-size: 14px;
cursor: pointer;
}
&-button:hover, &-button:focus {
background-color: #615b5b;
}
&-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 200px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
&-content .navMenu-link{
color: $body-text-color;
padding: 12px 16px;
text-decoration: none;
display: block;
}
&-content .navMenu-link:hover {
background-color: #ddd;
}
&-show {
display:block;
}
}
js:
function navClick() {
document.getElementById("navList").classList.toggle("navMenu-show");
}
window.onclick = function(event) {
if (!event.target.matches('.navMenu-button')) {
var dropdowns = document.getElementsByClassName("navMenu-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var show = dropdowns[i];
if (show.classList.contains('navMenu-show')) {
show.classList.remove('navMenu-show');
}
}
}
}
This is happening becuase your are setting an event that verifies if the element clicked contains an especific class, and indeed when it clicks the icon, it won't match because the icon does not contains the class you can solve it asking if also the parent contains the class....
window.onclick = function(event) {
if (event.target.matches('.navMenu-button') ||
event.target.parentNode.matches('.navMenu-button')
) {
console.log("it matches...");
}
}
.icon {
background:red;
}
<button class="navMenu-button">this is the button
<div class="icon">this is the icon</div>
</button>
On the other hand you could reference the click event using the "onclick" method in this case it will solve it automatically..
var button = document.querySelectorAll('.navMenu-button')[0];
button.onclick = function() {
console.log("button clicked");
}
Related
Suppose I have 3 buttons:
.all-buttons{
display:flex;
width: 100%
}
.bttn{
width: 33%
border: none;
background-color: blue;
padding: 20px 20px;
color: white;
}
<html>
<head><title>yes</title></head>
<body>
<div class="all-buttons">
<button class="bttn">BUTTON1</button>
<button class="bttn">BUTTON2</button>
<button class="bttn">BUTTON3</button>
</div>
</body>
</html>
As of my understanding I can use JavaScript const buttons = document.querySelectorAll('bttn'); which will create an array with every element with the class 'bttn'. How do I change the style of a button? For example, say I want to change the background-color of Button2 if I click on it. How do I get Button2 using classes in javascript?
I have tried this:
const buttons = document.querySelectorAll('link');
Array.from(buttons).forEach(el => {
el.addEventListener('click', function(event) {
//code
});
});
My end goal is to create a drop-down menu for each of the buttons but I would like to avoid adding an id for each button.
Any input is appreciated.
For getting elements by className, you have 2 options:
getElementsByClassName (without ".")
const buttons = document.getElementsByClassName('bttn');
querySelectorAll (with ".")
const buttons = document.querySelectorAll('.bttn');
And for changing the style of an element, you can use .style property on that element:
element.style.backgroundColor = 'blue';
So this code will help you:
const buttons = document.querySelectorAll('.bttn');
Array.from(buttons).forEach(el => {
el.addEventListener('click', function(event) {
el.style.backgroundColor = "blue";
});
});
Read more here.
First, document.querySelectorAll('bttn'); will not get elements with class equal to .bttn but it gets the elements with tag name equal to bttn.
You need to add the . like document.querySelectorAll('.bttn');
Then, you need to loop through with forEach and on each button add an event listener with addEventListener method on click, then you can change the color with style or create a class for the color and use classList methods.
const buttons = document.querySelectorAll('.bttn');
buttons.forEach(button => {
button.addEventListener('click', () => {
button.classList.toggle('red');
})
})
.all-buttons{
display:flex;
width: 100%
}
.bttn{
width: 33%
border: none;
background-color: blue;
padding: 20px 20px;
color: white;
}
.red {
background-color: red;
}
<html>
<head><title>yes</title></head>
<body>
<div class="all-buttons">
<button class="bttn">BUTTON1</button>
<button class="bttn">BUTTON2</button>
<button class="bttn">BUTTON3</button>
</div>
</body>
</html>
Hope it helps!
const buttons = document.querySelectorAll('.bttn'); // You must declare element's type; class (.) or id (#).
Array.from(buttons).forEach(el => {
el.addEventListener('click', function(event) {
el.style.color = "red"; // Added the line for changing the style of the button.
});
});
<button class="bttn">BUTTON1</button>
<button class="bttn">BUTTON2</button>
<button class="bttn">BUTTON3</button>
i think you need,
change element using queryseletorall
dropdown menu to each button
without using id to each button
to achieve this try like below,
const nodeList = document.querySelectorAll(".dropbtn");
const submenuList = document.querySelectorAll(".dropdown-content");
//alert(nodeList.length);
for (let i = 0; i < nodeList.length; i++) {
nodeList[i].addEventListener('click', function(event) {
submenuList[i].classList.toggle("show");
});
}
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #ddd}
.show {display:block;}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link- 1
Link- 2
Link- 3
</div>
</div>
if any query please comment
This question already has answers here:
Get ID of element clicked
(2 answers)
Closed 1 year ago.
wish all of you are fine , in my code below :
the user every time he clicked on element --> #crBtn, a new button should be create with different id (but all have the same className), for example if the user clicked on #crBtn three times that means 3 buttons will appear , now if I clicked on any of these button i want it to change its background-color and at the same time I need its id , how can i do that in js?
var idNum = 0;
function crBtn()
{
idNum++;
var button = document.createElement("button");
button.innerHTML="HERE";
button.setAttribute("class","name");
button.setAttribute("id","na"+idNum);
document.body.appendChild(button);
}
.name
{
background-color: aquamarine;
border: none;
width:300px;
height: 50px;
cursor: pointer;
margin-right: 10px;
margin-bottom:10px;
}
#crBtn
{
width:500px ;
height:60px;
background-color: blue;
border: none;
margin:30px;
color:white;
font-size: 30px;
}
.name:hover
{
background-color: skyblue;
color:aliceblue;
}
<body>
<button id = "crBtn" onclick="crBtn()">CLICK TO CREATE BUTTONS</button><br>
</body>
Pass event to the function. target property of the event object is your clicked element.
<button id = "crBtn" onclick="crBtn(event)">CLICK TO CREATE BUTTONS</button><br>
function crBtn(e){
console.log(e.target); //e.target is the button element
}
The following script defines a delegated click handler, bound to the body element of the document. Different actions are taken depending on which button was clicked.
var idNum = 0;
document.body.onclick=ev=>{
if (ev.target.id==="crBtn") crBtn()
else if (ev.target.className==="name") {
console.log("click on button with ID "+ev.target.id)
ev.target.style.backgroundColor="red";
}
}
function crBtn(){
idNum++;
var button = document.createElement("button");
button.innerHTML="HERE";
button.setAttribute("class","name");
button.setAttribute("id","na"+idNum);
document.body.appendChild(button);
}
.name
{
background-color: aquamarine;
border: none;
width:300px;
height: 50px;
cursor: pointer;
margin-right: 10px;
margin-bottom:10px;
}
#crBtn
{
width:500px ;
height:60px;
background-color: blue;
border: none;
margin:30px;
color:white;
font-size: 30px;
}
.name:hover
{
background-color: skyblue;
color:aliceblue;
}
<body>
<button id="crBtn">CLICK TO CREATE BUTTONS</button><br>
</body>
When I click on the menu anchor element it takes me back to the top of the page. As I scroll through the site I would like the menu to stay at the section that I have scrolled to when I click the menu anchor. I would like the menu anchor to only act as an open and close function of the expanding nav. [
function openMenu() {
document.getElementById('menu').style.width = "608px"
document.getElementById('content').style.marginLeft = "608px"
}
function closeMenu() {
document.getElementById('menu').style.width = "0px"
document.getElementById('content').style.marginLeft = "0px"
}
:root {
--main-color: #FEFF66;
--second-color: #000000;
--third-color: #FFFFFF;
}
* {
margin: 0;
padding: 0;
}
.slide {
margin: 18px;
font-size: 25px;
position: fixed;
}
.slide a {
text-decoration: none;
color: var(--second-color);
writing-mode: vertical-rl;
transform: rotate(-180deg);
}
.help a {
text-decoration: none;
color: var(--second-color);
}
.help {
display: flex;
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: var(--third-color);
color: var(--second-color);
overflow: hidden;
}
.links {
font-size: 40px;
line-height: 60px;
padding-top: 14px;
}
.header-menu {
writing-mode: vertical-rl;
transform: rotate(-180deg);
margin: 18px;
font-size: 25px;
padding-left: 55px;
}
<section id="header">
<span class="slide">
MENU
</span>
<div id="menu" class="help">
<div><a class="header-menu" href="#" onclick="closeMenu()">MENU</a></div>
<div class="links">
OUR STORY<br>
ROOMS + BOOK<br>
THE NEIGHBOURHOOD<br>
THE ART<br>
FAQ
</div>
</div>
</section>
]1
On your click listener pass in the event received as follow:
<div><a class="header-menu" href="#" onclick="closeMenu($event)">MENU</a></div>
The $event in the template has a special meaning in this case.
Then, on your closeMenu function adjust accordingly and prevent the default behavior of browser for anchor elements.
// Here, the function parameter can be named whatever you like,
// I named it "event" but anything else would work.
function closeMenu(event) {
// The line below will prevent the default behavior of the browser
// for this element and event, which means, it scroll to anywhere
// in this case, nor redirect to another page in case you had a URL
// in the href attribute.
event.preventDefault();
// Your code ...
}
Add event.preventDefault(); inside your javascript.
function openMenu(event) {
event.preventDefault();
document.getElementById('menu').style.width = "608px"
document.getElementById('content').style.marginLeft = "608px"
}
This prevent default actions of object you clicked, in this case anchor tag.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault?retiredLocale=it
How do I allow the user to click on the button that says "click me" appears on mouseenter of another button.
Here is the code -
<div class="hint"> ?</div>
<div class="desc">
This is supposed to appear on hover
This is supposed to appear on hover
This is supposed to appear on hover
This is supposed to appear on hover
<button type="button">
Click me
</button>
</div>
$(document).ready(function() {
var hint = $('.hint');
var desc = $('.desc');
hint.mouseenter(function() {
desc.show();
});
hint.mouseleave(function() {
desc.hide();
});
});
Here is the Demo
Just Place the .desc inside the .hint.
Fiddle
For the basic tooltip, you want:
<div title="This is my tooltip">
For fancier tooltips, See this
Wrap your html with another div and add mouseenter and mouseleave event to this.
var con = $('.container');
var desc = $('.desc');
con.mouseenter(function() {
desc.show();
});
con.mouseleave(function() {
desc.hide();
});
.hint {
padding: 20px;
background: white;
width: 10px;
height: 10px;
border-radius: 50%;
}
.desc {
display: none;
width: 200px;
background: white;
z-index: 3;
border: 1px solid #CCC;
border-radius: 3px;
top: 20px;
left: -5px;
padding: 12px;
color: #666;
font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="hint"> ?</div>
<div class="desc">
This is supposed to appear on hover This is supposed to appear on hover This is supposed to appear on hover This is supposed to appear on hover
<button type="button">
Click me
</button>
</div>
</div>
Make the .desc div a child of your .hint
$(document).ready(function() {
var hint = $('.hint');
var desc = $('.desc');
hint.mouseenter(function() {
desc.show();
});
hint.mouseleave(function() {
desc.hide();
});
});
.hint {
padding: 20px;
background: white;
width: 10px;
height: 10px;
border-radius: 50%;
text-align: center;
position: relative;
}
.desc {
display: none;
width: 200px;
background: white;
z-index: 3;
border: 1px solid #CCC;
border-radius: 3px;
top: 20px;
left: -5px;
padding: 12px;
color: #666;
font-size: 12px;
position: absolute;
top: 50%;
left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="hint"> ?<div class="desc">
This is supposed to appear on hover
This is supposed to appear on hover
This is supposed to appear on hover
This is supposed to appear on hover
<button type="button">
Click me
</button>
</div></div>
See fiddle
Updated Fiddle.
If you can't change the structure of your HTML code try to wait a little before hidding a desc div using setTimeout() so if the user enter mouse inside this div you will not hide it by clearing the timeout check the example bellow :
$(document).ready(function() {
var hide_timeout;
var hide_after = 100; //100 ms
var hint = $('.hint');
var desc = $('.desc');
hint.mouseenter(function() {
desc.show();
});
hint.mouseleave(function() {
hide_timeout = setTimeout(function(){
desc.hide();
},hide_after);
});
desc.mouseenter(function() {
clearTimeout(hide_timeout);
});
desc.mouseleave(function() {
desc.hide();
});
});
Hope this helps.
$(document).ready(function() {
var hide_timeout;
var hide_after = 100; //100 ms
var hint = $('.hint');
var desc = $('.desc');
hint.mouseenter(function() {
desc.show();
});
hint.mouseleave(function() {
hide_timeout = setTimeout(function(){
desc.hide();
},hide_after);
});
desc.mouseenter(function() {
clearTimeout(hide_timeout);
});
desc.mouseleave(function() {
desc.hide();
});
});
.hint {
padding: 20px;
background: white;
width: 10px;
height: 10px;
border-radius: 50%;
}
.desc {
display: none;
width: 200px;
background: white;
z-index: 3;
border: 1px solid #CCC;
border-radius: 3px;
top: 20px;
left: -5px;
padding: 12px;
color: #666;
font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hint"> ?</div>
<div class="desc">
This is supposed to appear on hover
This is supposed to appear on hover
This is supposed to appear on hover
This is supposed to appear on hover
<button type="button">
Click me
</button>
</div>
You have 2 options
1 - You can add the show() and hide() when the tooltip is hover : Fiddle
2 - You can use only css to show or hide it. Not sure you need JS for simple things like that.
This Demo shows what I think you want to achieve. The trick is to also catch the event that is triggerd, when the mouse enters a other element.
$('*').not('.hint').not('.desc').not('.desc>button').mouseenter(function() {
desc.hide();
});
$(function(){
$('.desc').hide();
$(document).on('mouseenter','.hint',function(){
$('.desc').show();
})
});
I'm trying to remove class 'active' when you click on the checkbox the 2nd time, the same way Pinterest does it for Twitter/Facebook checkboxes when a user adds a pin:
Adding 'active' class on click is easy. However, I couldn't figure how to remove it once it was added. I tried this, but it didn't work:
$(".add_link_twitter.active").click(function(e) {
$(this).removeClass(activePostTwitter);
});
I have two questions:
How to remove the 'active' css class on the 2nd click on the
checkbox?
How to disable '.add_link_twitter:hover' when the Twitter
checkbox is selected?
Thanks in advance!
Here's the jQuery:
var postTwitter = ".add_link_twitter";
var activePostTwitter = "active";
$(postTwitter).click(function(e) {
$(this).addClass(activePostTwitter);
});
Here's the html:
<label class="add_link_twitter">
<input type="checkbox" name="publish_to_twitter" class="publish_to_twitter"><span>Share on Twitter</span>
</label>
Here's the css:
.add_link_twitter{
position:absolute;
left:15px;
bottom:16px;
color: #a19486;
border: 2px solid transparent;
border-color: #F0EDE8;
border-radius: 4px;
font-size: 13px;
font-weight: bold;
cursor: pointer;
padding: 7px;
padding-top: 5px;
padding-bottom: 5px;
}
.active {
border-color: #468BD0;
color: #468BD0;
background-color: whiteSmoke;
}
.add_link_twitter:hover
{
color: #A19486;
border: 2px solid transparent;
border-color: #C2B1A2;
border-radius: 4px;
background-color: white;
padding: 7px;
padding-top: 5px;
padding-bottom: 5px;
}
Instead of
$(postTwitter).click(function(e) {
$(this).addClass(activePostTwitter);
});
use
$(postTwitter).click(function(e) {
$(this).toggleClass(activePostTwitter);
});
EDIT:
The event triggers twice per click, probably because of event propagation. To work around this, assign the handler to the input and have it change the class of its parent:
$(postTwitter + " input").click(function(e) {
$(this).parent().toggleClass(activePostTwitter);
});
Confirm jsfiddle: http://jsfiddle.net/bpfqB/
This should work for both your questions:
$(function() {
"use strict";
var $postTwitter = $("label.add_link_twitter");
$postTwitter.find("input:checkbox").click(function() {
$(this).parent().toggleClass("active");
if($("input.publish_to_twitter").is(":checked")) {
$(this).parent().removeClass("hover");
}
});
$postTwitter.hover(
function() {
if($("input.publish_to_twitter").is(":checked")) {
return;
}
$(this).addClass("hover");
},
function() {
$(this).removeClass("hover");
});
});
You need to make some changes to your CSS though, you have to do the hovering with jQuery (skip the CSS hover).
DEMO