event is executed twice instead of once - javascript

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.

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

Why is my click not working after I add a class with jQuery?

I set a click on some divs. When I click on them, the click either doesn't work or doesn't work immediately.
I've a carousel. The carousel has a background image that's determined by a css class. There are also divs inside the carousel that have a class. I'm attaching a fadein class to the inside divs to give a cross-fading effect. This works.
If I click a div immediately after page load, everything works. However, after the first carousel cycle completes, I have to click a div several times before the click takes, if it does.
After a lot of trial and error, I determined that ".addClass('fadein')" causes the problem. Removing that restores my clicks on the first try.
This is strange to me because I'm not adding it to anything that's a click.
Here's a snippet of my code. My HTML:
<div id="slider-wrapper" class="videos-set-1">
<div id="ss-video-1" class="video-selection video-display-top"></div>
<div id="ss-video-2" class="video-selection video-display-left"></div>
<div id="ss-video-3" class="video-selection video-display-right"></div>
</div>
My css:
#slider-wrapper.fadein.videos-set-3 .video-display-top,
#slider-wrapper.fadein.videos-set-3 .video-display-left,
#slider-wrapper.fadein.videos-set-3 .video-display-right {
visibility: hidden;
opacity: 0;
transition: visibility 0s 1s, opacity 1s linear;
}
And my jQuery:
var activeIndex = 0;
var play;
var carouselItems = $('#slider-wrapper .video-selection');
var panelsTotal = carouselItems.length;
var videoGallery = $('.container-videos');
var animateScreensaver = true;
$(function() {
function animateCarousel(n) {
if(!animateScreensaver) return;
if((n > activeIndex && n < panelsTotal) || (n < activeIndex && n >= 0)) {
if(carouselItems.eq(n)) {
$('#slider-wrapper').removeClass().addClass('videos-set-' + (n+1)).addClass('fadein');
}
}
setTimeout(function () {
$('#slider-wrapper').removeClass('fadein');
}, 3000);
activeIndex = n;
}
function playScreensaver() {
animateScreensaver = true;
play = setInterval(function() {
if(activeIndex >= panelsTotal-1) {
animateCarousel(0);
} else {
animateCarousel(activeIndex+1);
}
}, animateDuration);
}
function showScreensaver() {
animateScreensaver = true;
playScreensaver();
}
function playVideo(video) {
// play video stuff
}
var autoStart = setTimeout(function() {
playScreensaver();
});
$('.video-selection').on('click', function() {
var thisVideo = $(this).attr('id');
if(!animateScreensaver) {
showVideoGallery(thisVideo);
} else {
animateScreensaver = false;
playVideo(thisVideo);
}
});
})
I'd like to keep the cross-fade, but, after a couple hours of attempting to resolve this, I'm prepared to go without. I read through other SO answers, but they seem different from my issue, as they're adding a class to a click handler, and I'm not.
If someone could point me in the right direction, I can take it from there.
Thanks.
I'm not sure that my solution can solve your problem or not.
But from my experience, click event of Jquery have to write in ready event.
Example:
//this is ready event
$(document).ready(function() {
//add your click function here
});

Vanilla Javascript, mouseout delay with cancelation without jQuery

i am currently having a problem. I am using css to hide and display elements depending on the mouse function. One of my elements (a navigation arrow) depends on some other things. I now need a cancleable timer function which counts for lets say 2 seconds on mouseleave and then changes the class attribute. But it should have a timer which cancels on mouseover immediately. I dont want it to disappear too early.
Below my code with which i tried so far. I have no idea how to access the current timings of that setIntervall stuff. I alreasy experimented with Date.now(). But now i hope some of the geeks is able to help me.
Thanks in advance.
function hideElementOnMouseOut(el)
{
el.addEventListener("mouseleave", function( event )
{
mySlideAction = setInterval( function()
{
}, 1000 );
}
}
You can initialize interval on mouseleave function and clear this interval on mouseover function, which would prevent executing it's function.
Check the snippet below.
function hideElementOnMouseOut(el)
{
var interval;
el.addEventListener("mouseleave", function(event)
{
el.innerHTML = 'mouse out';
interval = setInterval(function()
{
el.innerHTML = 'time out';
el.className = 'out';
}, 1000);
});
el.addEventListener("mouseover", function(event)
{
el.innerHTML = 'mouse in';
el.className = '';
if(interval) {
clearInterval(interval);
}
});
}
hideElementOnMouseOut(document.getElementById("element"));
#element {
display: block;
width: 200px;
height: 200px;
background: red;
}
#element.out {
background: blue;
}
<div id="element"></div>

Multiple Show Hide Function with Javascript

Currently I am developing a simple show/hide div function with JavaScript. Now I have made it partially work. Take a look or you can copy and paste and try my code on your com. Here is the code:
http://jsfiddle.net/HRn3Q/
The current problem is I don't know how to trigger the content in the drop down list and show/hide it at the same position as graph1, graph2 and graph3 etc...I also want something like when diagram 1 is being shown then when I click show div 2, the content of diagram 1 will be replaced by graph2. I hope I have state my question clear.
This should do it.
The page wasn't recognizing the functions in that state for some reason.
turned:
function toggleStock(id)
{
}
into:
toggleStock = function(id)
{
}
http://jsfiddle.net/HRn3Q/
<script>
var opacity =0;
var intervalId =0;
function fadein()
{
intervalId = setInterval(hide,200)
}
function hide()
{
var img = document.getElementById("img1");
opacity = Number(window.getComputedStyle(img).getPropertyValue("opacity"));
if(opacity>0)
{
opacity=opacity-0.2;
img.style.opacity=opacity;
}
else
{
clearInterval(intervalId);
}
}
function fadeout()
{
intervalId = setInterval(show,200)
}
function show()
{
var img = document.getElementById("img1");
opacity = Number(window.getComputedStyle(img).getPropertyValue("opacity"));
if(opacity<1)
{
opacity=opacity+0.1;
img.style.opacity= opacity;
}
else
{
clearInterval(intervalId);
}
}
</script>

.each() function with interval between each iteration

Not sure if it is possible. The idea is very basic, list of buttons that onload start changing its background with a short interval and then repeat. I have a list of elements like:
<div class="container">
<div class="button"></div>
<div class="button"></div>
<div class="button"></div>
</div>
Next I want to manipulate it one by one, change background and pass to next with short interval. The problem is that it applies changes to all of them at once.
Here is the way I do it:
var element = $('.button');
element.each(function(){
var thisObj = $(this);
setInterval(function(){
thisObj.css({
'background':'#000'
})
}, 1000)
});
And then simply repeat it till the mouseover event is detected.
Could anyone suggest a way to do this? Thank you.
Here is an example: http://jsfiddle.net/maniator/S7C9h/
Some code to go along with it:
var buttons = $('.button'),
buttons_length = buttons.length;
function sliiide(index, interval){
var button = buttons.eq(index%buttons_length);
if(button.css('background-color') == 'rgb(0, 0, 255)'){ //blue
button.css({
background: 'white'
});
}
else {
button.css({
background: 'blue'
});
}
setTimeout(function(){
sliiide(++index, interval);
}, interval)
}
sliiide(0, 500);
This uses setTimeout instead of setInterval to reduce bubbling of the timeout events.
Update based on your comments below: http://jsfiddle.net/maniator/gMDEM/4/
I don't know if I understood what you want to do. Would this work?
var element = $('.button');
element.each(function(index){
var thisObj = $(this);
setTimeout(function(){
setInterval(function(){
thisObj.css({
'background':'#000'
})
},1000);
},1000 * index);
});
So each interval will begin with 1 second of difference.
Did I understood right?
If you only want the effect to happen once you should use setTimeout not setInterval. setInterval sets up a repeating event. Maybe you should try something like...
var element = $('.button');
var offsetTime = 1000;
element.each(function(){
var thisObj = $(this);
setInterval(function(){
thisObj.css({
'background':'#000'
})
},offsetTime)
offsetTime += 1000;
});
I would say, you should use different intervals for each button. In addition it is better to use setTimeout instead of setInterval, as the latter can cause performance issues:
var $element = $('.button');
$element.each(function(index, button){
var $button = $(button);
setTimeout(function changeColor(){
$button.css({'background':'#000'});
setTimeout(changeColor, 1000);
}, 1000*index);
});

Categories

Resources