Is it possible to check if (condition) onclick of an event of a button? cause I want to return a value if user click on popupButton
function showPopup(){
popup.style.visibility = "visible";
popupButton.onclick = ()=>{
popup.style.visibility = "hidden";
}
popupClose.onclick = () => {
popup.style.visibility = "hidden";
}
}
I suggest you do this
window.addEventListener("load", () => {
document.getElementById("popBut").addEventListener("click", e => {
console.log("Open button clicked"); // here you can call something
document.getElementById("popup").classList.remove("hide");
})
document.querySelector("#popup div.close").addEventListener("click", e => {
console.log("Close button clicked"); // here you can call something
document.getElementById("popup").classList.add("hide");
})
})
.hide {
display: none;
}
#popup {
height: 100px;
width: 100px;
background-color: yellow;
border: 1px solid black;
}
.close {
display: inline-block;
float: right
}
<button type="button" id="popBut">Show</button>
<div id="popup" class="hide"><div class="close">X</div>Here is a popup </div>
You are trying to read a return value from an asynchronous call. By the time the return fires the other code has already finished running. You need to use a promise and make the other code wait for a response back before executing.
function askQuestion() {
return new Promise(function(resolve, reject) {
const msg = document.getElementById("msg");
const btnYes = document.getElementById("btnYes");
const btnNo = document.getElementById("btnNo");
const cleanUp = function() {
msg.classList.remove("active");
btnYes.removeEventListener("click", yesFnc);
btnNo.removeEventListener("click", noFnc);
}
const yesFnc = function() {
resolve(true);
cleanUp();
}
const noFnc = function() {
resolve(false);
cleanUp();
}
btnYes.addEventListener("click", yesFnc);
btnNo.addEventListener("click", noFnc);
msg.classList.add("active");
});
}
function example1 () {
askQuestion().then(function(result){
console.log("The answer was: ", result);
});
}
async function example2 () {
const result = await askQuestion()
console.log("The answer was: ", result);
}
document.getElementById("test1").addEventListener("click", example1);
document.getElementById("test2").addEventListener("click", example2);
#msg {
display: none;
position: absolute;
top: 0; left: 0;
background-color: #CCC;
border: 1px solid black;
width: 300px;
padding: 1em;
}
#msg.active {
display: block;
}
<button id="test1">Example 1</button>
<button id="test2">Example 2</button>
<div id="msg">
<h2>Do you like pie?</h2>
<button id="btnYes" type="button">Yes</button>
<button id="btnNo" type="button">No</button>
</div>
Related
I have been tried to write a custom inspired element with an input field where the user can write and a list that appears and disappears based on input's focus.
const unitsList = {lenght:{fm:"femtometers (fm)",pm:"picometers (pm)",nm:"nanometers (nm)",um:"micrometers (μm)",mm:"millimiters (mm)",cm:"centimiters (cm)",dm:"decimeters (dm)",m:"meters (m)",dam:"decameters (dam)",hm:"hectometers (hm)",km:"kilometers (km)",in:"inchs (in)",ft:"foots (ft)",yd:"yards (yd)",mi:"miles (mi)"}}
let groups = ['lenght', ]
function $$(id) {
return document.querySelectorAll(id);
}
function s$(id) {
return document.querySelector(id);
}
$$('ul').forEach(selector => {
for (group of groups) {
for (unit in unitsList[group]) {
selector.insertAdjacentHTML('beforeend', `<li onclick="console.log('${unit}')">${unitsList[group][unit]}</li>`);
}
}
})
$$('.customSelectorInput').forEach(input => {
input.addEventListener('focus', () => {
$$('ul').forEach(() => {
s$(`#${input.parentNode.id} > ul`).hidden = false;
})
})
})
$$('.customSelectorInput').forEach(input => {
input.addEventListener('blur', () => {
$$('ul').forEach(() => {
s$(`#${input.parentNode.id} > ul`).hidden = true;
})
})
})
ul {
position: absolute;
list-style: none;
padding-left: 10px;
margin: 5px;
background-color: lightgray;
padding: 5px;
border-radius: 5px;
height: 100px;
overflow-y: scroll;
}
li {
margin: 2px 0;
padding: 5px;
}
li:hover {
background-color: grey;
}
<div class="inputContainer">
<div id="inSelector">
<input type="text" class="customSelectorInput">
<ul hidden id="inList"></ul>
</div>
</div>
The problem is that the input loses focus when the user clicks on the list and that happens before the onclick is able to work.
I have tried several methods, including but not limited to event.stopPropagation(), disabling useCapture or refocusing the input on a list's click event handler but nothing seems to work.
I'd really appreciate someone's help.
You could try something like that:
let isListClicked = false;
onListClick() {
isListClicked = true;
//do something on click item
};
onBlur() {
setTimeout(() => {
if (!selectClick) {
//do something on blur
};
selectClick = false;
}, 250);
}
I was hoping a kind soul might be able to assist.
I have a slideshow which auto-plays, my intention is to have the next button act as a visual aid, highlighting the when the next frame is coming in.
sync with the autoPlay interval.
Right now, the update func concludes too early, which is the best I have managed to do. Typically I have the clearInterval and setInterval conflicting creating shuddering animations.
What am I doing wrong?
<!doctype html>
<html lang="en">
<head>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
.carousel_wrapper {
height: 50vh;
width: 100%;
position: relative;
}
.carousel_frame {
width: 100%; height: 100%;
}
.carousel_controls {
position: absolute;
bottom: 0;
left: 0;
}
.prev, .next {
height: 50px;
width: 100px;
background: aqua;
display: inline-block;
}
.next {
background: linear-gradient(to right, white 0%, aqua);
}
.carousel_frame:nth-child(1) {
background: red;
}
.carousel_frame:nth-child(2) {
background: blue;
}
.carousel_frame:nth-child(3) {
background: green;
}
</style>
<script>
window.addEventListener('DOMContentLoaded', () => {
const homepage_carousel = new carousel();
});
function carousel() {
const carousel = document.getElementsByClassName('.carousel_wrapper')[0];
const frames = [...document.getElementsByClassName('carousel_frame')];
const prev_button = document.getElementsByClassName('prev')[0];
const next_button = document.getElementsByClassName('next')[0];
this.frameIndex = 1;
prev_button.addEventListener('click', () => {
this.resetPlay();
this.move(-1);
})
next_button.addEventListener('click', () => {
this.resetPlay();
this.move(+1);
})
this.hideAll = () => {
frames.forEach((f) => {
f.style.display = 'none';
});
}
this.show = () => {
this.hideAll();
frames[this.frameIndex - 1].style.display = 'block';
this.update_bg();
}
this.move = (amount) => {
this.frameIndex += amount;
this.frameIndex = (this.frameIndex > frames.length ? 1 : (this.frameIndex < 1) ? frame.lengh : this.frameIndex);
this.show();
}
this.update_bg = () => {
let w = 1;
let test = setInterval(adjust, 10);
function adjust() {
if (w >= 100) {
clearInterval(test);
w = 0;
} else {
w++;
next_button.style.backgroundImage = `linear-gradient(to right, white ${w}%, aqua)`
}
}
setInterval(adjust, 3000);
}
this.autoPlay = () => {
this.move(+1)
this.update_bg();
}
this.resetPlay = () => {
// clearInterval(timer);
// timer = setInterval(this.autoPlay(), 4000);
}
this.show();
const timer = setInterval(this.autoPlay, 3000);
}
</script>
</head>
<body>
<div class='carousel_wrapper'>
<div class='carousel_frame'>
<span>Headline</span>
<span>Description</span>
<span>CTA</span>
</div>
<div class='carousel_frame'>
<span>Headline</span>
<span>Description</span>
<span>CTA</span>
</div>
<div class='carousel_frame'>
<span>Headline</span>
<span>Description</span>
<span>CTA</span>
</div>
<div class='carousel_controls'>
<span class='prev'>Previous</span>
<span class='next'>
Next
</span>
</div>
</div>
</body>
</html>
Im implementing a calculator, and I'm stuck trying to display the digit on the screen. I iterate trough all my digit to get them, but when I try to replace them in order to display them in my div with the id #nums it won't work. this is the function i'm stuck with
buttons.forEach(button => {
button.addEventListener('click', function(){
console.log('it work')
document.querySelector('#nums').textContent = buttons.innerHTML
})
})
here is a fiddle to see more
function add(a, b) {
return a + b
}
function substract(a, b) {
return a - b
}
function sum(arr) {
result = 0;
for (var i = 0; i < arr.length; i++) {
result += arr[i]
}
return result
}
/*
function multiply_range(arr){
result = 1;
for(var i = 0; i < arr.length; i++){
result *= arr[i]
}
return result
}
*/
function multiply(a, b) {
return a * b
}
function divide(a, b) {
return a / b
}
var sum = document.getElementById('sum');
var substract = document.getElementById('minus')
var multiply = document.getElementById('multiply')
var divide = document.getElementById('divide')
function operate(operator, a, b) {
if (operator === sum) {
return add(a, b);
} else if (operator === substract) {
return substract(a, b);
} else if (operator === multiply) {
return multiply(a, b);
} else if (operator === divide) {
return divide(a, b);
}
}
operate(sum, 1, 1);
var display_value = document.querySelector('#nums');
const buttons = document.querySelectorAll('.number-btn')
// loop through all the buttons
// Object.keys(buttons) transform my object in a array
/*
Object.keys(buttons).forEach(button => {
button.addEventListener('click', function(){
console.log('it work')
})
})
*/
buttons.forEach(button => {
button.addEventListener('click', function() {
console.log('it work')
document.querySelector('#nums').textContent = buttons.innerHTML
})
})
/*
var btn_1 = document.querySelector('#btn-1')
btn_1.addEventListener('click', function(){
console.log('it work')
document.querySelector('#nums').textContent = btn_1.textContent
})
*/
/*
document.querySelector('#nums').textContent = 0;
*/
/*
document.getElementsByClassName('number-btn').addEventListener('click', function(){
display_value == document.queryselector('nums');
})
*/
body {
background-color: black;
}
.container {
display: grid;
grid-template-columns: auto auto auto auto;
grid-gap: 10px;
padding: 10px;
width: 85%;
height: 300px;
margin: 0 auto;
background-color: #cc1515;
}
#btn-equals {
grid-row-start: 2;
grid-column-start: 4;
grid-row-end: 6;
grid-column-end: 4;
}
.number-btn {
border: 0.5px solid black;
background-color: white;
font-size: 30px;
}
.operator-btn {
border: 0.5px solid black;
background-color: black;
color: white;
font-size: 30px;
}
.results {
margin: 0 auto;
width: 90%;
height: 50px;
background-color: white;
}
.contour {
background-color: lightblue;
position: absolute;
top: 30%;
left: 35%;
width: 400px;
margin: auto;
vertical-align: middle;
}
#nums {
font-size: 40px;
text-align: right;
}
#operator {
font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="contour">
<p>The calculator</p>
<div id="results" class="results">
<div id="nums">55</div>
</div>
<div class="container">
<button id="sum" class="operator-btn">+</button>
<button id="minus" class="operator-btn">-</button>
<button id="multiply" class="operator-btn">x</button>
<button id="divide" class="operator-btn">/</button>
<button id="btn-7" class="number-btn">7</button>
<button id="btn-8" class="number-btn">8</button>
<button id="btn-9" class="number-btn">9</button>
<button id="btn-4" class="number-btn">4</button>
<button id="btn-5" class="number-btn">5</button>
<button id="btn-6" class="number-btn">6</button>
<button id="btn-1" class="number-btn">1</button>
<button id="btn-2" class="number-btn">2</button>
<button id="btn-3" class="number-btn">3</button>
<button id="btn-period" class="number-btn">.</button>
<button id="btn-O" class="number-btn">0</button>
<button id="btn-clear" class="number-btn">AC</button>
<button id="btn-equals" class="operator-btn">=</button>
</div>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
hope someone can help
use button.innerHTML not buttons.innerHTML
The array is called buttons - each item you're pulling out is being initialized as button. You want to set the div equal to that item's innerHTML, not the array buttons - which, as it is an array to begin with, does not have an innerHTML property. Furthermore, it wasn't clear in your question, but if you would like to keep adding digits to the calculator box, be sure to use the += operator instead of the =, like so document.querySelector('#nums').textContent += button.innerHTML That way it will keep adding to each box on button press.
If you would like the buttons to just replace the previous item in the calculator window, this will work:
buttons.forEach(button => {
button.addEventListener('click', function(){
document.querySelector('#nums').textContent = button.innerHTML
})
})
EDIT: As a matter of fact, since you just want the text node within your HTML, it would be better for performance to simply use button.textContent or as #Barmar pointed out, this.textContent ( this also references button )
textContent is faster because when you utilize innerHTML the Browser Engine has to reprocess and parse everything while it copies it over. textContent specifically only deals with a text node and the content therein.
buttons.forEach(button => {
button.addEventListener('click', function(){
document.querySelector('#nums').textContent = button.textContent;
})
})
It should be button and not buttons :)
document.querySelector('#nums').textContent = button.innerHTML
document.querySelector('#nums').textContent += button.innerHTML;
I have many <p>s with the same function.
document.getElementById("minus").onclick = function() {
functionHide()
};
function functionHide() {
document.getElementById("plus").style.display = "block";
document.getElementById("minus").style.display = "none";
}
document.getElementById("plus").onclick = function() {
functionShow()
};
function functionShow() {
document.getElementById("plus").style.display = "none";
document.getElementById("minus").style.display = "block";
}
#plus {
display: none;
cursor: pointer;
}
#minus {
cursor: pointer;
}
.floatright {
float: right
}
.w50 {
width: 50%;
text-align: center;
}
<div class="w50">
<p>What paperwork do I need to complete to file for divorce ?
<span class="floatright inlineb" id="minus">- </span>
<span class="floatright inlineb" id="plus">+</span>
</p>
<p>How do I change my custody and suport orders ?
<span class="floatright inlineb" id="minus">- </span>
<span class="floatright inlineb" id="plus">+</span>
</p>
</div>
When I click on the first minus ( "-" ) it works correctly.
but for the second, it doesn't work.
I want to know how can I automatically chain for all others divs. they have the same typing code.
Also, I would know how can I change the last element (" - ") when an another + is clicked?
Here is a preview of what I want to do
And a fiddle: https://jsfiddle.net/khrismuc/prsebqg3/15/
You are using duplicate IDs, which is a no-no. Here is an example using classes and .querySelectorAll.
var minuses = document.querySelectorAll(".minus");
var pluses = document.querySelectorAll(".plus");
minuses.forEach(function(minus) {
minus.addEventListener('click', functionHide);
});
pluses.forEach(function(plus) {
plus.addEventListener('click', functionShow);
});
function functionHide() {
pluses.forEach(function(plus) {
plus.style.display = "block";
});
minuses.forEach(function(minus) {
minus.style.display = "none";
});
}
function functionShow() {
pluses.forEach(function(plus) {
plus.style.display = "none";
});
minuses.forEach(function(minus) {
minus.style.display = "block";
});
}
You can modify for your particular uses.
Your logic needs to be slightly more complex:
var current = -1;
function handleClick(clicked) {
$(".w50 p").removeClass("active").find("span").text("+");
$("#box p").hide();
if (current === clicked) {
current = -1;
return;
}
current = clicked;
$(".w50 p").eq(current).addClass("active").find("span").text("-");
$("#box p").eq(current).show();
}
$(document).ready(function() {
$(".w50 p").each(function(i, el) {
$(this).append($("<span>").text("+"));
$(this).click(function() {
handleClick(i);
});
});
$(".w50 p").eq(0).click();
});
.w50 {
width: 80%;
text-align: center;
}
.w50 p {
cursor: pointer
}
.w50 p.active {
color: orange
}
.w50 p span {
float: right;
width: 1em;
display: inline-block;
}
#box {
background-color: orange;
margin: 20px;
min-height: 6em;
}
#box p {
display: none;
padding: 1em
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="w50">
<p>What paperwork do I need to complete to file for divorce?</p>
<p>How do I change my custody and support orders?</p>
</div>
<div id="box">
<p>Paperwork description</p>
<p>Custody description</p>
</div>
i created custom confirm box like this:
function formPopup(message, callback) {
message = message + '<div class="clear"></div><button class="mybutton" name="check" value="true">Yes</button>' +
'<button class="mybutton mybutton2" name="check" value="false">No</button>';
createPopup("Message", message);
$(".popup .body button[name='check']").bind("click", function (e) {
val = $(this).val();
if (val == "true") {
$(".popup").find(".close").trigger("click");
typeof (callback) != "undefined" ? callback() : null;
} else {
$(".popup").find(".close").trigger("click");
}
});
}
i want when i run formPopup function the page wait like "confirm" or "alert" until i will click on $(".popup .body button[name='check']").
i tried with
promise and when
but its didnt helped.
tnx a lot
Do you mean something like this?
jQuery could not get "this" in your click function, i replaced it with e.target, so event.target == the button that you are clicking.
function showPopup(message, callback) {
$(".popup").css("display", "block");
$(".title").html(message);
// only button 1, value will be true anyways, but just to show how to access the button object
$(".b1").on("click", (e) => {
var val = $(e.target).val();
if (val == "true") {
closePopup();
typeof (callback) != "undefined" ? callback() : null;
} else {
closePopup();
}
});
// button 2, try to split as much as you can, makes everything alot easier
$(".b2").on("click", (e) => {
closePopup();
});
}
function closePopup() {
$(".popup").css("display", "none");
setTimeout(() => {
showPopup("back again", () => { console.log("callback"); });
}, 2000);
}
showPopup("message", () => { console.log("callback"); });
.popup {
position: fixed;
display: none;
left: 0;
top: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.2);
z-index: 1;
}
.popup-content {
position: absolute;
color: red;
background: green;
width: 300px;
left: calc(50% - 150px);
height: 100px;
top: calc(50% - 50px);
z-index: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clear">
</div>
<div class="popup">
<div class="popup-content">
<h1 class="title"></h1>
<button class="b1" name="check" value="true">Yes</button>
<button class="b2" name="check" value="false">No</button>
</div>
</div>