Why img inside a button with onclick not trigger the script? - javascript

I have a button with onclick. There is an image inside of the button but its not trigger the script.
function myFunction1() {
document.getElementById("rightdrop02").classList.toggle("show");
}
window.addEventListener('click', function(event) {
if (!event.target.matches('.rightmenubtn02')) {
var dropdowns = document.getElementsByClassName("right_content02");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
});
body {
background-color: limegreen;
}
.rightmenubtn01,
.rightmenubtn02,
.rightmenubtn03,
.rightmenubtn04,
.rightmenubtn05 {
border: none;
cursor: pointer;
color: white;
font-family: "focim";
font-size: 17px;
width: 100%;
line-height: 38px;
text-align: left;
padding-left: 20px !important;
border-bottom: solid 1px white;
background-color: transparent;
}
.right_content02,
.right_content03 {
display: none;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
z-index: 1;
}
.right_content02 a,
.right_content03 a {
border-bottom: solid 1px #00765a;
}
.right_content02 a,
.right_content03 a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.rightmenu01 a:hover,
.rightmenu02 a:hover,
.rightmenu03 a:hover,
.rightmenu04 a:hover,
.rightmenu05 a:hover {
background-color: #ddd;
}
.show {
display: block;
}
.right_img button:focus {
outline: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.right_img button:hover {
background-color: rgba(255, 255, 255, 0.3);
}
.right_img img {
float: right;
padding: 6px 16px 6px 0;
}
.right_img button {
padding: 0;
padding-left: 10px;
border-radius: 0;
}
<div class="right_img">
<div class="rightmenu02">
<button onclick="myFunction1()" class="rightmenubtn02">Button<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAA81BMVEX////eAADwe4mNGCX9ASD/AADdAAUYGBj5w8zhFxoIAAArKyvaAADEABapFxn/ASU9S0qNGCH/HCEzMzMkJCSpFx75AAD+DxI7OzudGCj/AAmpGCn/ABm/GCt8FyTOARn0mqT6zNf+8Pbta3Ltd4TmMDoiFxfob3Lwnq7tiJDkSU7cBw/iMT/qeHfnVVqDg4NKSkpyb299fHyioqKPj4+0tLQaGhoODg5PT09hYWEcJCIVAAAUIRuzAAjCAAlednRKXFoJGBczQkHpQ1XsTWaLFxf0pKpxLDRyGiT72Nv3uL3kGyr83eL4r7rqWGHubHjoMETZSe+SAAABc0lEQVQokZWR6XKCMBSFE4EABQsoIi6tu5aGKqjFtVbRauvS9v2fpjEBdWz/9M5kTnK+ycmdXADAJsdxnGFwrI76bmwArZzGa0XLymo8zxO1snzy1mCI42WMlqsGlmWE3NVShljOxUhVWwA4ECNcJueKC4sFhoyiWyeSgAitqVFtWBF6S1FJQPhNbEciAVYmQlr5UKXoCwBJ/QRgm83EbyFZitFWbQNwOCMVS3FgBdYuAk+3EEqA6nYPpF22cIUwdKmxVovXCO4+yC2yar8CaYe49meHTtThPnX7D0QC90vyjdJlYIWiBjNA3bpGGNaqR0OS86fmMW4/tVwsY/XReSi3sMoX4ilrmiAI+eOwBYHutDuG7kvJc81ms2TypRRNuTm5ocVkQmQ6aTI0DvVQn+vjha6Hob6Y6vNXfcyQ2e/1e6PnfuD3On7Xszu+3/cYCjzPtoOhZ4/sdNc3lbSiDE2GlEEgimIgmqYYpBWyCYKBQvwf4QQtRo/eO0oAAAAASUVORK5CYII="></button>
<div id="rightdrop02" class="right_content02">
Dropdown01
Dropdown02
Dropdown03
Dropdown04
Dropdown05
Dropdown06
</div>
</div>
</div>
The img is not the original one because its from a private site. Stripped the html so its less complicated but the css is the same. I also know my code is awful, no need to remind me...

When you click the image, the event target is the image, not the button. You have to fix the condition in order to get that to work:
if (!event.target.matches('.rightmenubtn02') &&
!event.target.matches('.rightmenubtn02 img')) {
https://jsfiddle.net/swynmuat/
The condition now checks not only for the button but for the image inside the button as well.

Related

I can't get the JavaScript toggle to work

What I want to do is when I click the task it will have a line through the text means that I'm done with the task. but the add event listener function for this is not working, I'm working with the javascript toggle and that's all I can think of right now to achieve this functionality.
Is there another way to do this? I searched on the internet and it seems complicated when I'm trying to figure it out.
const addBtn = document.querySelector("#push");
const taskInput = document.querySelector("#taskInput");
const taskOutput = document.querySelector("#tasks");
addBtn.addEventListener("click", function() {
let newTasks = taskInput.value;
if (newTasks.length == 0) {
alert("Please enter a task");
} else {
taskOutput.innerHTML += `<div class="task">
<span id="taskname">${newTasks} </span>
<button class="delete" id="deleteButton"><i class="fa-solid fa-trash"></i> </button>
</div>
`;
//delete
let deleteBtn = document.querySelector("#deleteButton");
deleteBtn.addEventListener("click", function() {
this.parentNode.remove();
});
//line through
let theTask = document.querySelectorAll(".task");
theTask.addEventListener("click", function() {
this.classList.toggle("completed");
});
}
});
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100vh;
background: linear-gradient( 90deg, rgba(241, 206, 221, 1) 0%, rgba(124, 184, 254, 1) 100%);
display: flex;
justify-content: center;
align-items: center;
font-family: 'Kumbh Sans', sans-serif;
}
.container {
border: 2px solid white;
width: 50%;
min-width: 450px;
margin: auto;
padding: 30px 40px;
}
#new-task {
position: relative;
background-color: white;
padding: 30px 20px;
border-radius: 1em;
}
#new-task input {
width: 70%;
height: 45px;
font-family: 'Manrope', sans-seif;
font-size: 1.2em;
border: 2px solid #d1d3d4;
padding: 12px;
color: #111111;
font-weight: 500;
position: relative;
border-radius: 5px;
}
#new-task input:focus {
outline: none;
border-color: violet;
}
#new-task button {
font-family: 'Manrope', sans-seif;
position: relative;
float: right;
width: 25%;
height: 45px;
border-radius: 5px;
font-weight: bold;
font-size: 16px;
border: none;
background-color: violet;
color: white;
cursor: pointer;
}
#tasks {
background-color: white;
padding: 30px 20px;
margin-top: 50px;
border-radius: 10px;
width: 100%;
}
.task {
background-color: white;
height: 50px;
padding: 5px 10px;
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2px solid violet;
cursor: pointer;
}
.task span {
font-size: 18px;
font-weight: 400;
}
.task button {
background-color: violet;
color: white;
height: 100%;
width: 40px;
border: none;
border-radius: 5px;
outline: none;
cursor: pointer;
}
.task button:hover {
background-color: red;
}
.completed {
text-decoration: line-through;
}
<body>
<div class="container">
<div id="new-task">
<input type="text" name="" id="taskInput" placeholder="Task to be done" />
<button id="push">ADD</button>
</div>
<div id="tasks"></div>
</div>
<script src="/script.js"></script>
</body>
querySelectorAll will return the list of nodes matching the selector tasks. So you have to iterate through each of those nodes and add your listener. See the below code snippet
let theTasks = document.querySelectorAll(".task");
theTasks.forEach((task) => {
task.addEventListener("click", function() {
this.classList.toggle("completed");
});
});
theTask is a list of nodes. Trying to attach event listener on this list is causing issues.
Also, you will be inserting lots of buttons with same id deleteButton and spans with same id taskname which is incorrect and can cause undefined behavior.
For theTask fix, you may want to do something like:
let theTasks = [...document.querySelectorAll(".task")];
theTasks.forEach(task => {
task.addEventListener("click", function() {
this.classList.toggle("completed");
})
});
Using innerHTML to create manipulate the DOM for an application like a todo list is probably not a good idea. The answers to Advantages of createElement over innerHTML? give good explanations why.
It is worth noting that in the innerHTML code, the span and the button are created with an id and so all of these elements will have the same id. It is also probably not a good idea to have duplicate ids on one page. Why are duplicate ID values not allowed in HTML? explains why.
Also, adding event listeners to every new task is also probably not a good idea. What is DOM Event delegation? gives a good explanation why.
Finally, the Difference between HTMLCollection, NodeLists, and arrays of objects and Document.querySelectorAll() explain how to get lists of elements that can be manipulated.
So, I have rewritten the task creation code in the addBtn.addEventListener to show one way how this could be done with document.createElement().
And I have created a separate event listener on the Tasks container div, which handles both task deletion and task completion.
I also added the following CSS so that clicking on a trash can icon is handled by the parent button. Without this CSS, clicking on an icon would not delete the task.
div#tasks i {
pointer-events: none;
}
To make the todo list more visible in the code snippet below, I reduced the heights, margins, and paddings of some of the elements in the CSS.
I also added a link to the font awesome icon library.
const addBtn = document.querySelector("#push");
const taskInput = document.querySelector("#taskInput");
const taskOutput = document.querySelector("#tasks");
taskOutput.addEventListener("click", function(event) {
if (event.target && event.target.nodeName === "SPAN") {
event.target.classList.toggle("completed");
}
if (event.target && event.target.nodeName === "BUTTON") {
event.target.parentNode.remove();
}
});
addBtn.addEventListener("click", function() {
let newTasks = taskInput.value;
if (newTasks.length == 0) {
alert("Please enter a task");
} else {
// Create a task DIV
const newTaskElement = document.createElement("div");
newTaskElement.classList.add("task");
// Create a SPAN with the task name
const newTaskNameElement = document.createElement("span");
const taskTextnode = document.createTextNode(newTasks);
newTaskNameElement.appendChild(taskTextnode);
// Create a BUTTON with a TRASH CAN ICON
const newTaskDeleteButton = document.createElement("button");
const deleteImageElement = document.createElement("i");
deleteImageElement.classList.add("fa-solid", "fa-trash");
newTaskDeleteButton.appendChild(deleteImageElement);
// Append the SPAN and the BUTTON to the task DIV
newTaskElement.appendChild(newTaskNameElement);
newTaskElement.appendChild(newTaskDeleteButton);
// Append the task DIV to the TASK LIST DIV
taskOutput.appendChild(newTaskElement);
}
});
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100vh;
background: linear-gradient( 90deg, rgba(241, 206, 221, 1) 0%, rgba(124, 184, 254, 1) 100%);
font-family: 'Kumbh Sans', sans-serif;
}
/* ADDED TO MAKE SURE THAT THE TRASH ICON DOES NOT PROCESS CLICKS */
div#tasks i {
pointer-events: none;
}
.container {
border: 2px solid white;
width: 50%;
min-width: 450px;
margin: auto;
padding: 3px 4px;
}
#new-task {
position: relative;
background-color: white;
padding: 6px 4px;
border-radius: 1em;
}
#new-task input {
width: 70%;
height: 45px;
font-family: 'Manrope', sans-seif;
font-size: 1.2em;
border: 2px solid #d1d3d4;
padding: 12px;
color: #111111;
font-weight: 500;
position: relative;
border-radius: 5px;
}
#new-task input:focus {
outline: none;
border-color: violet;
}
#new-task button {
font-family: 'Manrope', sans-seif;
position: relative;
float: right;
width: 25%;
height: 45px;
border-radius: 5px;
font-weight: bold;
font-size: 16px;
border: none;
background-color: violet;
color: white;
cursor: pointer;
}
#tasks {
background-color: white;
padding: 6px 4px;
margin-top: 5px;
border-radius: 10px;
width: 100%;
min-height: 50px;
}
.task {
background-color: white;
height: 50px;
padding: 5px 10px;
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2px solid violet;
cursor: pointer;
}
.task span {
font-size: 18px;
font-weight: 400;
}
.task button {
background-color: violet;
color: white;
height: 100%;
width: 40px;
border: none;
border-radius: 5px;
outline: none;
cursor: pointer;
}
.task button:hover {
background-color: red;
}
.completed {
text-decoration: line-through;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" rel="stylesheet" />
<div class="container">
<div id="new-task">
<input type="text" name="" id="taskInput" placeholder="Task to be done" />
<button id="push">ADD</button>
</div>
<div id="tasks"></div>
</div>

dropdown menu wont appear in navbar

I am having an issue with my dropdown menu after clicking, it won't appear in the way I want to, it should just be a simple dropdown menu with the tab "about" like the one from w3schools.
Here is the code:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunctionlang() {
document.getElementById("myDropdown").classList.toggle("showlang");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtnlang')) {
var dropdowns = document.getElementsByClassName("dropdownlang-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('showlang')) {
openDropdown.classList.remove('showlang');
}
}
}
}
/*dropdown lang start*/
.dropbtnlang {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtnlang:hover,
.dropbtnlang:focus {
background-color: #2980B9;
}
.dropdownlang {
position: relative;
display: inline-block;
}
.dropdownlang-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdownlang-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdownlang a:hover {
background-color: #ddd;
}
.showlang {
display: block;
}
/*dropdown lang end*/
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<i class="fa fa-fw fa-language" onclick="myFunctionlang()" class="dropbtnlang"></i>
<div id="myDropdown" class="dropdownlang-content">
Test
</div>
Your problem is here <i class="fa fa-fw fa-language" onclick="myFunctionlang()" class="dropbtnlang"></i> you have set class attribute twice, I've just fix this minor issue in your code and everything seems ok.
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunctionlang() {
document.getElementById("myDropdown").classList.toggle("showlang");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtnlang')) {
var dropdowns = document.getElementsByClassName("dropdownlang-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('showlang')) {
openDropdown.classList.remove('showlang');
}
}
}
}
/*dropdown lang start*/
.dropbtnlang {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtnlang:hover,
.dropbtnlang:focus {
background-color: #2980B9;
}
.dropdownlang {
position: relative;
display: inline-block;
}
.dropdownlang-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdownlang-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdownlang a:hover {
background-color: #ddd;
}
.showlang {
display: block;
}
/*dropdown lang end*/
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<i class="fa fa-fw fa-language dropbtnlang" onclick="myFunctionlang()" ></i>
<div id="myDropdown" class="dropdownlang-content">
Test
</div>

Assistance With Organizing User Input Inside Of Border JS

I am currently creating a To Do list program using HTML, CSS, and JS. One of my current issues with my program is that the item added to the list partially blocks the add button inside of my program when you choose to run it. And another issue is that the clear button isn't function properly when you enter clear to remove all of the added items. So I am wondering how to resolve these issues where the added items are partially blocking the add and clear button. And how to get the clear button to function properly to clear the list of added items inside of the to do list.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
margin: 0;
min-width: 250px;
}
#todo{
float:left;
width:50%;
}
#done{
float:right;
width:50%;
}
/* Include the padding and border in an element's total width and height */
//* {
// box-sizing: border-box;
//}
/* Remove margins and padding from the list */
ul {
margin: 0;
padding: 0;
}
/* Style the list items */
ul li {
cursor: pointer;
position: relative;
padding: 12px 8px 12px 40px;
list-style-type: none;
background: #eee;
font-size: 18px;
transition: 0.2s;
/* make the list items unselectable */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Set all odd list items to a different color (zebra-stripes) */
ul li:nth-child(odd) {
background: #f9f9f9;
}
/* Darker background-color on hover */
ul li:hover {
background: #ddd;
}
/* When clicked on, add a background color and strike out text */
ul li.checked {
background: #888;
color: #fff;
text-decoration: line-through;
}
/* Add a "checked" mark when clicked on */
ul li.checked::before {
content: '';
position: absolute;
border-color: #fff;
border-style: solid;
border-width: 0 2px 2px 0;
top: 10px;
left: 16px;
transform: rotate(45deg);
height: 15px;
width: 7px;
}
/* Style the close button */
.close {
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close:hover {
background-color: #f44336;
color: white;
}
/* Style the header */
.header {
background-color: #f44336;
padding: 30px 40px;
color: white;
text-align: center;
}
/* Clear floats after the header */
.header:after {
content: "";
display: table;
clear: both;
}
/* Style the input */
input {
margin: 0;
border: none;
border-radius: 0;
width: 75%;
padding: 10px;
float: left;
font-size: 16px;
}
/* Style the "Add" button */
.addBtn {
padding: 10px;
width: 25%;
background: #d9d9d9;
color: #555;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
}
.Clear {
padding: 10px;
width: 25%;
background: #d9d9d9;
color: #555;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
}
.Clear:hover {
background-color: #bbb;
}
.addBtn:hover {
background-color: #bbb;
}
h1 {
font-size: 30px;
border: 1px solid black;
margin: auto;
padding: 30px;
text-align: center;
}
h2 {
font-size: 30px;
border: 1px solid black;
margin: auto;
padding: 30px;
text-align: center;
}
</style>
</head>
<body>
<form id="todo" style="float:left">
<h1 id="todo" style="font-family:Helvetica; color:#006600"><b>To Do</b>
<input type="text" id="myInput" placeholder="Add Item">
<span onclick="newElement()" class="addBtn">Add</span>
<input type="button" onclick="newFunction()" value="Clear">
<ul id="myUL">
</ul>
</h1>
</form>
<form id="done" style="float:right">
<h2 id="done" style="font-family:Helvetica; color:#006600"><b>Done</b></h2>
</form>
<script>
// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
myNodelist[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('checked');
}
}, false);
// Create a new list item when clicking on the "Add" button
function newElement() {
var li = document.createElement("li");
var inputValue = document.getElementById("myInput").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === '') {
alert("You must write something!");
} else {
document.getElementById("myUL").appendChild(li);
}
document.getElementById("myInput").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
}
function newFunction() {
document.getElementById("todo").reset();
}
</script>
</body>
</html>
It is the position: absolute in the css.
When you use this property, elements will "float" through page.
You should remove all properties with absolute.
There is no need to use them in your page.
I also recommend these two articles about position and flexbox:
https://www.w3schools.com/css/css_positioning.asp
https://www.w3schools.com/css/css3_flexbox.asp

Dropdown not appearing on click

I am trying to add a dropdown menu so when the page is viewed on mobile the user can click and access all the pages available. I am not getting any type of error code, just no response. Below are the snippets of HTML, CSS and JavaScript that should be affecting the code. Thanks for taking the time to read through this.
/*When user clicks name on shows dropdown menu allowing for nav on smaller viewports */
function dropDown() {
document.getElementById("dropNav").classList.toggle("show");
}
//close drop down if clicked outside
window.onclick = function(event) {
if (!event.target.matches('dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.dropbtn {
background-color: white;
color: #000;
padding: 8px 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover .dropbtn:focus {
background-color: #f1f1f1;
}
/* menu below button*/
.dropdown {
position: relative;
display: inline-block;
}
/* hidden dropdown, using z to plac in front of other elements */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 100px;
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: goldenrod
}
.show {
display: block;
}
<div class="dropdown">
<button onclick="dropDown()" class="dropbtn"><b>AH</b>NAME</button>
<div id="dropNav" class="dropdown-content">
Portfolio
About
Contact
Travels
Web Security Information
</div>
</div>
/*When user clicks name on shows dropdown menu allowing for nav on smaller viewports */
function dropDown(event) {
event.stopPropagation();
document.getElementById("dropNav").classList.toggle("show");
}
//close drop down if clicked outside
window.onclick = function(event) {
if (!event.target.matches('dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.dropbtn {
background-color: white;
color: #000;
padding: 8px 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover .dropbtn:focus {
background-color: #f1f1f1;
}
/* menu below button*/
.dropdown {
position: relative;
display: inline-block;
}
/* hidden dropdown, using z to plac in front of other elements */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 100px;
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: goldenrod
}
.show {
display: block;
}
<div class="dropdown">
<button onclick="dropDown(event)" class="dropbtn"><b>AH</b>NAME</button>
<div id="dropNav" class="dropdown-content">
Portfolio
About
Contact
Travels
Web Security Information
</div>
</div>

JavaScript addEventListener "click" for button that moves while clicking

I have a button styled to move when clicking. If the button is not in position with the mouse cursor when releasing, the click function is not triggered. How can I still make the click function trigger as expected?
Here is a fiddle with the HTML, CSS and JavaScript. Notice if you hold a click and release in a place where the button does not exist under your mouse pointer, it will not trigger the function.
https://jsfiddle.net/du1eL8gc/1/
Just a note: I know that it makes sense this does not trigger because the button is actually moving out of place, I just want to have it work as a user would expect.
HTML:
<div class="buttons-dialog" style="position:absolute; bottom:20px; left:33%">
<a class="button" id="saveButton">Save</a>
</div>
CSS:
#import url('https://fonts.googleapis.com/css?family=IBM+Plex+Mono');
:root {
--blueColor: #0028aa;
--darkBlueColor: #022693;
--errorColor: rgb(255, 130, 0);
--grayColor: #bcbdaa;
--darkgrayColor: #525252;
--cyanColor: #59ffff;
--yellowColor: #fffa51;
--emeraldColor: #184343;
--lightEmeraldColor: #38a6a6;
--redColor: #9c0b07;
--badTextColor: #fe6666;
--highlightTextColor: #ffffff;
--fontName: 'IBM Plex Mono', monospaced;
font-family: var(--fontName);
font-size: 16px;
}
body {
background: var(--blueColor);
}
.button-panel {
margin-bottom: 1.5em;
}
.button {
background: var(--darkgrayColor);
border: 0;
font-family: var(--fontName);
font-size: 1rem;
color: var(--grayColor);
outline: 0;
padding: 2px;
margin-right: 1em;
box-shadow: 10px 8px 0 black;
text-decoration: none;
}
.buttonNoShadow {
background: var(--darkgrayColor);
border: 0;
font-family: var(--fontName);
font-size: 1rem;
color: var(--grayColor);
outline: 0;
padding: 2px;
margin-right: 1em;
text-decoration: none;
}
.button:active {
color: var(--highlightColor);
position: relative;
left: 10px;
top: 8px;
box-shadow: none;
}
.button::before {
content: "▯ ";
color: var(--highlightColor);
}
.button::after {
content: " ▯";
color: var(--highlightColor);
}
JavaScript:
document.getElementById("saveButton").addEventListener("click", function () {
console.log('clicked')
});
You can use your JavaScript with the "mouseup" event and have it work by wrapping your button content and moving that content instead of your button.
Working example: https://jsfiddle.net/8a5upveg/3/
For instance you can wrap the text in a <span>:
<a class="button" id="saveButton"><span>Save</span></a>
Then change your CSS to target the <span>:
.button {
// Seems necessary to catch top pixel of button click
padding: 1px;
}
.button span {
background: var(--darkgrayColor);
border: 0;
font-family: var(--fontName);
font-size: 1rem;
color: var(--grayColor);
outline: 0;
padding: 2px;
margin-right: 1em;
box-shadow: 10px 8px 0 black;
text-decoration: none;
}
.buttonNoShadow span {
background: var(--darkgrayColor);
border: 0;
font-family: var(--fontName);
font-size: 1rem;
color: var(--grayColor);
outline: 0;
padding: 2px;
margin-right: 1em;
text-decoration: none;
}
.button:active span {
color: var(--highlightColor);
position: relative;
left: 10px;
top: 8px;
box-shadow: none;
}
.button span::before {
content: "▯ ";
color: var(--highlightColor);
}
.button span::after {
content: " ▯";
color: var(--highlightColor);
}
Instead of .addEventListener("click", function() {});, you can use .addEventListener("mousedown", function() {});, which works exactly as you wanted.
Then the function will be called even if the mouse button is released outside of the moving button.

Categories

Resources