I made a button that is supposed to start changing the color of some text every couple of seconds. The code DOES change color, but it happens right when the page is loaded, and doesn't wait for the user to click the button for it to change color. Here is my code. Please explain to me and show me how to make the code only execute when the user clicks the button.
<!DOCTYPE html>
<body>
<style>
#woo{
color: green;
}
#woot{
color: orange;
}
</style>
<button onClick="onChange()">SWAG</button>
<p id="woo">WAM</p>
<script>
setInterval(function(){onChange()}, 2000);
function onChange(){
document.getElementById("woo").id = "woot";
setTimeout(function(){
document.getElementById("woot").id = "woo";
}, 1000);
}
</script>
</body>
</html>
If you can help answer my question, please do.
As soon as you call setInterval() you ask the browser to execute onChange() every 2 seconds, regardless of the button.
Try something like:
<style>
#woo.green {
color: green;
}
#woo.orange {
color: orange;
}
</style>
<button onClick="startChange()">SWAG</button>
<p id="woo" class="orange">WAM</p>
<script>
var intervalRef;
var green = false;
function startChange() {
intervalRef = setInterval(function() { doChange(); }, 1000);
}
function stopChange() {
clearInterval(intervalRef);
}
function doChange() {
var el = document.getElementById("woo");
if (green) {
el.className = "orange";
green = false;
} else {
el.className = "green";
green = true;
}
}
</script>
All you need to do is remove the call to setInterval. Your onclick handler is fine. See this example, where I deleted the setInterval call:
http://jsfiddle.net/U6Z8F/
Related
The aim was to make a "run/stop" button completely unresponsive whilst in the "stopping" state (ie waiting for some code to reach a termination point.
Despite disabling click (mouse) handling use both element.disabled = true AND element.removeEventListener , i find that whilst the code is running with the click event supposedly disabled the browser still collects clicks and will fire events after the wait code ends and the even listener is re-enabled.
Example code :
fiddle here : https://jsfiddle.net/xjf26dpe/
<!doctype html>
<html>
<head>
<script type="text/javascript" src="js.js"></script>
</head>
<body onload="init();">
<button type="button" id="runstatus">Play</button>
</body>
</html>
var runstatus="stopped";//values 'stopped' , 'running', 'stopping'
function init() {
UIupdate();
}
//toggle button display text
function UIupdate(){
var t = document.getElementById("runstatus");
if ( runstatus == "stopped") {
t.innerText = "Run";
t.addEventListener("click",stopstart);
t.disabled = false;
} else
if ( runstatus == "stopping") {
t.innerText = "stopping..";
// t.removeEventListener("click",stopstart,);
t.removeEventListener("click",stopstart,true);
t.disabled = true;
} else
if ( runstatus == "running") {
t.innerText = "Stop";
}
}
function stopstart(){
var f,f2;
if (runstatus=="stopped"){
runstatus="running";
UIupdate();
} else
if (runstatus=="running"){
document.getElementById("runstatus").removeEventListener("click",stopstart);
f = function(){
runstatus="stopping";
UIupdate();
window.requestAnimationFrame(f2);
}
f2=function(){
wait();
runstatus="stopped";
UIupdate();
}
window.requestAnimationFrame(f);
} else
if (runstatus=="stopping"){
//nothing to do
}
}
function wait(){
var i,j=0;
for (i=0;i<1e10;i++){
if (i%1e9 ==0){
j++;
console.log("waiting to stop",j,"of 10");
}
}
console.log("finished");
return;
}
.. whilst the code is in the 'wait' function I find that clicking on the button will still stack click responses that are acted on when the wait code terminates. I want these clicks to be completely ignored
i made a button function that has a button with a word and when its clicked the definition shows. but now i'm trying to make it so that the buttons shows the definition every couple seconds with "SetInterval" without needing to be clicked and i don't know how to go about doing so can you please help.
'use strict';
//below is the function for the even
$(document).ready(function() {
//
function salutationsHandler(evnt) {
let box = $("#message-box");
if (box.hasClass("hidden")) {
box.attr("class", "");
$(evnt.target).text("1.Salutation");
} else {
box.attr("class", "hidden");
$(evnt.target).text('a greeting in words or actions');
}
}
//end of function
setInterval(salutationsHandler, 1000);
//start of another
function DiffidenceHandler(evnt2) {
let box2 = $("#message-box2");
if (box2.hasClass("hidden")) {
box2.attr("class", "");
$(evnt2.target).text("2.Diffidence");
} else {
box2.attr("class", "hidden");
$(evnt2.target).text("the quality of being shy");
}
console.log(evnt2);
}
//lets me target id
let salutationsGrab = $('#Salutations');
// adds event to said id
// event listeners grab events from functions
salutationsGrab.on('click', salutationsHandler);
let DiffidenceGrab = $("#Diffidence");
DiffidenceGrab.on("click", DiffidenceHandler);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>hello welcome to our dictionary</h1>
<h2>Click on button to reveal definition of word shown</h2>
<button id="Salutations">1.Saluation</button>
<div id="message-box"></div>
<br>
<button id="Diffidence">2.Diffidence</button>
<div id="message-box2"></div>
<br>
The function salutationsHandler needs the event object generated by an event to work. Instead of calling the function directly, you can use jQuery's .trigger() to "click" the button.
function salutationsHandler(evnt) {
const box = $("#message-box");
const target = $(evnt.target);
if (box.hasClass("hidden")) {
box.removeClass("hidden");
target.text("1.Salutation");
} else {
box.addClass("hidden");
target.text('a greeting in words or actions');
}
}
let salutationsGrab = $('#Salutations');
salutationsGrab.on('click', salutationsHandler);
setInterval(() => salutationsGrab.trigger('click'), 1000);
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>hello welcome to our dictionary</h1>
<h2>Click on button to reveal definition of word shown</h2>
<button id="Salutations">1.Saluation</button>
<div id="message-box">a greeting in words or actions</div>
I'm using a .slideToggle to show a div once an image is clicked. I want the div to disappear 10 seconds after the last time the toggle is clicked. The problem is that if I click the image a few times, the duration is 10 seconds after the first click and not the last. If you view the fiddle (I used a shorter duration for testing) and click the image a few times you will see what I mean.
Does anyone have any idea how I can get this working as desired? Any help would be greatly appreciated!
Fiddle: https://jsfiddle.net/7fy536nv/
Requirements...
The div should show for 10 seconds then disappear
The div will disappear if the image is clicked again
The div will disappear if something outside the div is clicked
HTML
<div class="box-new">
<a href="box-link" id="box-link">
<img src="https://dummyimage.com/100x60/ff0000/fff.png">
</a>
</div>
<div id="empty-box">jkhsahg akjfhsajk fhas jklsad flkasd hfjkashd fjka sdkjfh adskjfhs dakjfh kafh sdah dhjaf</div>
CSS
body, html {
margin: 0;
}
#empty-box {
display: none;
position: absolute;
background: #000;
top: 60px;
width: 240px;
padding: 20px;
left: 0;
color: #fff;
text-align: center;
font-family: "open sans", "arial";
font-size: 14px;
font-weight: 600;
line-height: 18px;
z-index: 1;
}
JS
$('#box-link').click(function(event){
event.stopPropagation();
$("#empty-box").slideToggle(400);
setTimeout(function() {
$("#empty-box").slideUp();
}, 5000);
return false;
});
$("#empty-box").on("click", function (event) {
event.stopPropagation();
});
$(document).on("click", function () {
$("#empty-box").slideUp(400);
});
Assign your call to setTimeout to a variable declared in the outer scope and clear it with clearTimeout in every subsequent event:
var timeout;
$('#box-link').click(function(event){
clearTimeout(timeout);
event.stopPropagation();
$("#empty-box").slideToggle(400);
timeout = setTimeout(function() {
$("#empty-box").slideUp();
}, 5000);
return false;
});
The setTimeout function returns a value that you can cancel using clearTimeout.
So in your code, store the return value, and each time it is clicked, cancel the previous timeout and restart a new one.
var timeout = null;
function test()
{
if( timeout !== null )
clearTimeout(timeout);
timeout = setTimeout(..., 10000);
}
It's quite simple, really. The key is placing your setTimeout in a variable and calling clearTimeout(variable).
Example:
let someVar = false,
someTime = 5000,
msgTimer = document.getElementById('timer'),
timer,
current,
displayTimer = false;
$('.yourButton').on('click', someFunc)
function someFunc() {
if (someVar) {
clearTimeout(someVar) // <<< juice is here
console.log('cleared timeout!')
}
timer = performance.now()
someVar = setTimeout(function () {
clearInterval(displayTimer)
console.log(someTime / 1000 +
' seconds passed since last click...')
someVar = false
displayTimer = false
msgTimer.innerHTML = ''
}, someTime)
/**
* ¯\_(ツ)_/¯
* ignore past this point, rest is timer
*
* ˙ʇᴉ pǝǝu ʇ,uop no⅄ ˙ʎllɐǝɹ
**/
if (displayTimer) {
clearInterval(displayTimer)
displayTimer = false
}
displayTimer = setInterval(function () {
current = performance.now()
msgTimer.innerHTML = Math.max(timer + 5000 - current,0)
.toFixed(2) + 'ms'
}, 15)
}
#timer {
font-family: monospace;
text-align:right;
display: inline-block;
width: 100px;
font-size: 1.2rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="yourButton">Don't click. Think.</button>
<span id="timer"></span>
Reduced interval to 5 seconds for faster testing.
Here is a solution to show a div for a maximum of 10 seconds...
And hide it if user clicks anywhere before this delay.
There is no problem with the delay if user clicks often or repeately...
Because I took care of resets.
I created a CodePen, with a timer displayed aside the cart link, to show the time passing.
And here is a CodePen with the exact same code as in the below snippet, if your want to play with it.
var emptyCart = $("#emptyCart");
var cartTimer;
var carMaxTime = 10000;
// Function to hide the cart
var hideCart = function(){
emptyCart.dequeue().slideUp("slow");
}
// Function to show the cart
var showCart = function(){
emptyCart.dequeue().slideDown("slow");
clearTimeout(cartTimer); // Just to be sure We have only one timer running
cartTimer = setTimeout(function(){
hideCart();
},carMaxTime);
}
// Function to handle click on the cart link
$("#clickCart").click(function(){
$(document).off("click",hideCart()); // Just to prevent a slideUp which would counter-act a slideUp
if(emptyCart.is(":hidden")){
showCart();
}
setTimeout(function(){ // 1ms delay to use this event handler on next click.
$(document).on("click",function(){
hideCart();
$(document).off("click",hideCart()); // Unbind this handler once used.
});
},1);
});
#emptyCart{
display:none;
width:100px;
background:#000;
color:#fff;
height:30px;
margin-top:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clickCart">
Cart
</div>
<div id="emptyCart">
No items
</div>
I want to give blink effect(dark and light) when clicked on the button.I have written the following code but it does not work.So please help me.
$(document).ready(function () {
$(".search").click(function () {
setInterval(function () {
var curSrc = $("#red").attr('src');
if (curSrc === '../images/lightred.jpg') {
$(curSrc).attr("src", "../images/Darkred.jpg");
}
if (curSrc === '../images/Darkred.jpg') {
$(curSrc).attr("src", "../images/lightred.jpg");
}
}, 2000);
});
});
curSrc is your source attribute, yet you are trying to wrap it in jQuery, that won't make it an object. You'll have to target #red again and then set the source:
if (curSrc === '../images/lightred.jpg') {
$("#red").attr("src", "../images/Darkred.jpg");
}
if (curSrc === '../images/Darkred.jpg') {
$("#red").attr("src", "../images/lightred.jpg");
}
It seems the question might be how to make the button blink. This can be done with the css background-color property. CSS is a better fit, assuming lightRed and darkRed are solid colors. If the images are required you can use the background-image property.
<input type="button" class="search lightRed" value="Search"/>
<style>
.lightRed { background-color: lightcoral }
.darkRed { background-color: darkRed }
</style>
<script>
$(document).ready(function(){
$(".search").click(function(){
setInterval(function(){
var isLightRed = $(".search").hasClass("lightRed");
if (isLightRed) {
$(".search").removeClass("lightRed").addClass("darkRed");
} else {
$(".search").removeClass("darkRed").addClass("lightRed");
}
},2000);
});
});
</script>
im having a prob with javascript which has been bugging me for hours now. I need to delay a css popup so that if you just scroll mouse around page you wont get loads of popups.
Whatever i try it either makes the popup act goofy, poping up after x seconds with a swipe of any link, auto closing etc etc. if i add a timer to the mouseover it starts acting weird, if i then delete the timer for mouseout it works fine but you can no longer mouseover menu before it closes, also tried adding negative margin and it autocloses
cheers all
javscript
<script type="text/javascript">
var span = document.querySelectorAll('.pop');
for (var i = span.length; i--;) {
(function () {
var t;
span[i].onmouseover = function () {
hideAll();
clearTimeout(t);
this.className = 'popHover';
};
span[i].onmouseout = function () {
var self = this;
t = setTimeout(function () {
self.className = 'pop';
}, 300);
};
})();
}
function hideAll() {
for (var i = span.length; i--;) {
span[i].className = 'pop';
}
};
</script>
css
.pop {
position:relative;
}
.pop div {
display: none;
}
.popHover {
position:absolute;
}
.popHover div {
background-color:#FFFFFF;
border-color:#AAAAAA;
border-style:solid;
border-width:1px 2px 2px 1px;
color:#333333;
padding:5px;
position:absolute;
z-Index:9999;
width:150px;
display: inline-block;
margin-top: -20px;
}
Using jquery might be a little more helpful for what you are trying to do. Try something like this:
// Use a CDN to take advantage of caching
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript">
var t;
$('.pop').on('mouseover', $.proxy(function () {
hideAll();
clearTimeout(t);
this.addClass('popHover');
this.removeClass('pop');
}, this));
$('.pop').on('mouseout', $.proxy(function () {
var self = this;
t = setTimeout(function () {
self.addClass('pop');
self.removeClass('popHover');
}, 300);
},this));
function hideAll() {
// Since you are calling this from the mouseover function of all the
// elements with the 'pop' class, I dont understand what the purpose of this class
// is so it might not be entirely correct.
$('.pop').addClass('pop');
}
</script>
Let me know if this helps. If you still need it. It would be helpful to have a fiddle to maybe tweak to give you a more accurate response.