Basic Javascript click function not loading - javascript

I am just trying to change the font attribute via a click function real beginner stuff, however I want to check if the element has been clicked a second time and do something if so.
var clicks = 0;
document.getElementById('button2').click(function(){
clicks++;
if(clicks%2===0){
document.getElementById('demo2').style.fontSize='22px';
} else{
document.getElementById('demo2').style.fontSize='12px';
}
});
What am i doing wrong?

Why not using an event listener instead?
According to the mozilla documentation (https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click), the click function does not expect a function that defines the behavior of the click.
Try the following:
var clicks = 0;
document.getElementById('button2').addEventListener('click', function(){
clicks++;
if(clicks%2===0){
document.getElementById('demo2').style.fontSize='22px';
} else{
document.getElementById('demo2').style.fontSize='12px';
}
});
<button id="button2">Click me</button>
<div id="demo2">Hello</div>

https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Attribute/onclick
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
.click fires a click, it doesn't watch for them
var clicks = 0;
document.getElementById('button2').onclick = function(){
clicks++;
console.log(clicks)
if(clicks%2===0){
document.getElementById('demo2').style.fontSize='22px';
} else{
document.getElementById('demo2').style.fontSize='12px';
}
};
<div id="button2">button2</div>
<div id="demo2">demo2</div>
This is what you should do though just toggle a class look how much code is removed and it does the exact same thing :)
const button = document.querySelector('.button2');
const demo = document.querySelector('.demo2');
button.addEventListener('click', () => demo.classList.toggle('large'));
.demo2 {
font-size: 12px;
}
.large {
font-size: 22px;
}
<div class="button2">button2</div>
<div class="demo2">demo2</div>

Related

JavaScript how to get if a button is active (after click)

I have only one button. In css you can use button:active { do stuff } and it will become valid once and after the button is clicked, so interacting with other objects (clicking on a image) will cause
the statement to be null. How Can I translate this into java script?
Something like that:
const Ham_Button = document.querySelector('button');
while (Ham_Button.isActive)
{
do stuff
}
I tried this:
const Ham_Button = document.querySelector('button');
const ClickEvent = function() {
Hidden_Nav.style.display = "block";
}
Ham_Button.addEventListener("click", ClickEvent);
But the event is triggered only and only when I click, not after, when the element is still the last interacted object.
Maybe you can use the onblur event. With that you can detect if the user "removes" the active state of a link or button.
https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event
You can find out which element currently has focus by consulting
document.activeElement
This has good browser compatibility.
Don't put this in a while loop as in your example, though, or you'll lock up the browser's thread of execution. If you must check this periodically, consider using setTimeout.
Maybe you could try something like this:
const Ham_Button = document.querySelector('button');
let hamIsActive = false;
Ham_button.addEventListener('click', () => {
if(hamIsActive) {
// do stuff, add styles...
hamIsActive = false; // to add a toggle functionality
} else {
// do stuff, add styles...
hamIsActive = true; // to add a toggle functionality
}
})
You have the mousedown event fired once each time the button is pressed.
You also have the mouseup event fired once each time the button is released.
you can't use a while loop since it would block the main thread but you can setup a tick loop (fired roughly every 16ms, or 60 times per second)
const btn = document.getElementById('btn');
const counterDown = document.getElementById('counter_down');
let totalTimeDown = 0;
let downRequestId;
let lastTimeDown = 0;
function loopDown(time) {
if (lastTimeDown) {
const dt = time - lastTimeDown;
totalTimeDown += dt;
counterDown.innerHTML = (totalTimeDown / 1000).toFixed(2);
}
lastTimeDown = time;
downRequestId = requestAnimationFrame(loopDown);
}
function onMouseDown() {
downRequestId = requestAnimationFrame(loopDown);
}
function onMouseUp() {
lastTimeDown = 0;
cancelAnimationFrame(downRequestId);
}
btn.addEventListener('mousedown', onMouseDown);
btn.addEventListener('mouseup', onMouseUp);
// SAME LOGIC FOR FOCUS/BLUR
const counterFocus = document.getElementById('counter_focus');
let totalTimeFocused = 0;
let focusRequestId;
let lastTimeFocus = 0;
function loopFocus(time) {
if (lastTimeFocus) {
const dt = time - lastTimeFocus;
totalTimeFocused += dt;
counterFocus.innerHTML = (totalTimeFocused / 1000).toFixed(2);
}
lastTimeFocus = time;
focusRequestId = requestAnimationFrame(loopFocus);
}
function onFocus() {
focusRequestId = requestAnimationFrame(loopFocus);
}
function onBlur() {
lastTimeFocus = 0;
cancelAnimationFrame(focusRequestId);
}
btn.addEventListener('focus', onFocus);
btn.addEventListener('blur', onBlur);
button:focus {
outline: 1px solid blue;
}
button:active {
outline: 1px solid red;
}
<button id="btn">press me</button>
<div>time pressed: <span id="counter_down">0</span>s</div>
<div>time focused: <span id="counter_focus">0</span>s</div>
Note that you can switch for focus and blur events if that's what you are looking for

event is executed twice instead of once

Click on the 5 and it will become 7-9-11...
I'm expecting 6-7-8...
Any help?
function go_plus(e) {
let obj = $(e.target);
let a = parseInt(obj.text());
a += 1;
obj.text(a);
}
var setint = '';
function go_spinn(e) {
setint = setInterval(function() {
go_plus(e);
}, 79);
}
$('#count').on('mouseleave mouseup', function() {
clearInterval(setint);
});
#count {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='count' onclick='go_plus(event)' onmousedown='go_spinn(event)'>5</div>
So the problem is you can "slow-click" things - hold the mousedown for a second or two, then let it go, and still result in a click.
The best way to solve the problem is to put a timeout before go_spin starts that you can clear when you click.
The drawback is your go_spinn doesn't start up as fast - i.e. you need to hold the mouse down for the duration of your timeout, in my example it was 200ms, before your go_spinn starts. Test it, you might be able to drop it back a little bit (to 150ms or so) to achieve what you want.
EDIT: By the way, I was just making an assumption on what you were trying to achieve - what were you actually trying to achieve with this code?
function go_plus(e){
let obj = $(e.target);
let a = parseInt(obj.text());
a += 1;
obj.text(a);
}
var setint = '';
var startspin;
function go_spinn(e){
startspin = setTimeout(function() {
setint = setInterval(function(){go_plus(e);}, 79);
},200);
}
$('#count').on('click mouseleave mouseup', function(){
clearInterval(setint);
clearInterval(startspin);
});
#count{
cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='count' onclick='go_plus(event)' onmousedown='go_spinn(event)'>5</div>
Just change your html code to <div id='count' onmousedown='go_spinn(event)'>5</div> so that you remove the onclick event.

Button that acts like toggle with JS functions

How can I make a HTML button act like a toggle? I have two JS functions that modify an image, one to a new image and the other to change it back. How can I make sure a button activates the first function when pressed the first time but then activates the second when pressed again, repeated for the third and fourth time etc.
document.getElementById("baseImg").src = "assets/1stImg.png";
function imgChange1() {
document.getElementById("baseImg").src = "assets/2ndImg.png";
}
function imgBack1() {
document.getElementById("baseImg").src = "assets/1stImg.png";
}
<img id="baseImg">
<button onclick="imgChange1()">Change</button>
How would I go about including the second function within this button?
`
I don't really get your question because you were saying "toggle" but you were saying
How can I make sure a button activates the first function when pressed
the first time but then activates the second when pressed again?
But well, here's how you do it:
var clicked = false;
function toggleBtnClick(button) {
var img = document.getElementById('baseImg');
if (clicked) { //this will be executed on future clicks after first click
img.src = 'http://via.placeholder.com/350x150/4CAF50/000000';
console.log('Next click');
//or do something else
} else { //this will only be executed once
img.src = 'http://via.placeholder.com/350x150/e9e9e9/000000';
console.log('First click');
}
clicked = true; //update to true after first click
}
button {
position: absolute;
right: 0;
}
<img id="baseImg" src="http://via.placeholder.com/350x150/3fafed/000000">
<button onclick="toggleBtnClick()">Change</button>
But, if you really want a "toggle" functionality, here's how you do it:
var clicked = false;
function toggleBtnClick() {
var img = document.getElementById('baseImg');
if (clicked) {
img.src = 'http://via.placeholder.com/350x150/e9e9e9/000000';
clicked = false;
} else {
img.src = 'http://via.placeholder.com/350x150/3fafed/000000';
clicked = true;
}
}
button {
position: absolute;
right: 0
}
<img id="baseImg" src="http://via.placeholder.com/350x150/e9e9e9/000000">
<button onclick="toggleBtnClick()">Change</button>

Pure JS detect click on wrapper and focus on inner input

I have responsive design, with padded container around input. Problem is, when user clicks in padded area, input wont be focused.
In jQuery the working code is:
$('.wrap').on('click', function (e) {
$(this).find('input').focus();
});
But can't seem to get it working in JS:
var elm_rows = document.getElementsByClassName("wrap");
elm_rows.addEventListener("click", function (e) {
e.getElementsByTagName("input").focus();
});
https://jsfiddle.net/2f9sq3tf/
Try accessing each of your getElementsBy functions as an array.
Example:
var elm_rows = document.getElementsByClassName("wrap")[0];
elm_rows.addEventListener("click", function (e) {
this.getElementsByTagName("input")[0].focus();
});
To resolve the remaining concern just wrap this in a loop like:
var elm_rows = document.getElementsByClassName("wrap");
for (i in elm_rows) {
elm = elm_rows[i];
elm.addEventListener("click", function (e) {
this.getElementsByTagName("input")[0].focus();
});
}
Could be better, but this works.
This should work:
let wrap = document.querySelectorAll('.wrap');
wrap.forEach((el) => {
el.addEventListener('click', (e) => {
// whatever you need to do goes here
});
});
today you can use querySelector to find elements on the DOM (and inside some NODE too).
Example:
var els = document.querySelectorAll('.wrap');
for(var i = 0; i < els.length; i++){
els[i].addEventListener('click',function(ev){
var input = ev.target.querySelector('input');
if(input) input.focus();
});
}
The if is required because with that code if you click on the input node, the event will propagate to the .wrap element, and your callback will execute too, but ev.target will be the input node and the query will return null.
var elm_rows = document.getElementsByClassName("wrap");
elm_rows[0].addEventListener("click", function (e) {
e.currentTarget.children[0].focus();
});
.wrap {border: 3px solid blue; padding: 15px;}
input {width: 100%;}
<div class="wrap">
<input type="text" name="" value="" />
</div>

Toggle Event Listeners

I am trying to make a function that would allow me to toggle eventListener of an element.
In the example below, I have three buttons: main, on and off. When I click on the on button, the main button becomes functional. After I click off button, the main button should not work anymore (but now it still does).
Now I can achieve a desired behavior by clicking on button for the second time, but I guess it's a bad coincidence and it's not supposed to work that way.
Maybe I should add that I would like to work this out without using jQuery or similar and it needs to be a function, because I am going to use it for a lot of buttons.
(I suspect something with scope causes the problem (clickHandler when calling the function to activate the button is not the same as the clickHandler when calling the function to disable the button), but I can't think of a way to test it.)
// buttons definitions, not important
var mainButton = document.querySelector("#mainButton");
var onButton = document.querySelector("#onButton");
var offButton = document.querySelector("#offButton");
// main function
var toggleButtons = function(toggleVal, button, element) {
var activateButton, clickHandler, disableButton;
// callback function for listener bellow
clickHandler = function() {
document.querySelector(element).classList.toggle("yellow");
};
activateButton = function() {
button.addEventListener("click", clickHandler);
};
disableButton = function() {
button.removeEventListener("click", clickHandler);
};
// when first argument is 1, make the button functional, otherwise disable its functionality
if (toggleVal === 1) {
activateButton();
} else {
disableButton();
}
};
// when onButton is clicked, call main function with arguments
// this works
onButton.addEventListener("click", function() {
toggleButtons(1, mainButton, "body");
});
// this fails to disable the button
offButton.addEventListener("click", function() {
toggleButtons(0, mainButton);
});
.yellow {
background-color: yellow;
}
<button type="button" id="mainButton">mainButton
</button>
<button type="button" id="onButton">onButton
</button>
<button type="button" id="offButton">offButton
</button>
<p>mainButton: toggles background color on click
</p>
<p>onButton: turns on mainButtons's functionality</p>
<p>offButton: supposed to turn off mainButton's functionality</p>
var mainButton = document.querySelector("#mainButton");
var onButton = document.querySelector("#onButton");
var offButon = document.querySelector("#offButton");
var element; // declare the element here and change it from toggleButtons when needed.
function clickHandler() {
document.querySelector(element).classList.toggle('yellow');
}
function activateButton(button) { // You missed this part
button.addEventListener('click', clickHandler);
}
function disableButton(button) { // You missed this part
button.removeEventListener('click', clickHandler);
}
function toggleButtons(value, button) {
if (value === 1) {
activateButton(button); // You missed this part
} else {
disableButton(button); // You missed this part
}
};
onButton.addEventListener('click', function() {
element = 'body'; // you can change it to some other element
toggleButtons(1, mainButton);
});
offButton.addEventListener('click', function() {
element = 'body'; // you can change it to some other element
toggleButtons(0, mainButton);
});
Below code helps to toggle between two functions from an eventListener:
var playmusic=false;
function playSound() {
const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`)
audio.currentTime = 0
audio.play()
playmusic=true;
}
function stopSound() {
const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`)
audio.pause()
playmusic=false;
}
window.addEventListener('keydown',
function(){playmusic?stopSound():playSound()} )

Categories

Resources