I created a button that creates a grid. However, clicking on the button repeatedly executes the code repeatedly and I only want it to execute once. The code is below:
inputBtn.addEventListener("click", function () {
createGrid();
});
function createGrid() {
for (let i = 0; i < 256; i++) {
div = document.createElement("div");
div.classList.add("grid-child");
if (gridContainer) {
randomColor();
}
gridContainer.appendChild(div);
}
}
I created a loop that I thought would stop executing after 256 times. I also tried adding a break at the very end but that led to some other problems.
Set the once option to true when adding the listener:
inputBtn.addEventListener(
"click",
function () {
createGrid();
},
{ once: true }
);
Related
I have two functions that are triggered whilst the user is inputting data. They essentially add up the values of the options they choose, and output them.
On this form, in particular, the options are already pre-populated. Because of this, the functions have not been triggered, leaving their calculation as null.
The functions are shown just above </body>
Functions:
$(calculateScore);
function calculateScore () {
var fields = $('.form-group #input').change(calculate);
function calculate () {
var score = 0;
fields.each(function () {
score += +$(this).val();
});
$('#score').html(score.toFixed(0));
}
}
$(calculateHiddenScore);
function calculateHiddenScore () {
var fields = $('.form-group #input').change(calculate);
function calculate () {
var score = 0;
fields.each(function () {
score += +$(this).val();
});
$('#hidden_score').val(score.toFixed(0));
}
}
Code placed underneath the functions to try and trigger them:
$(function () {
calculateHiddenScore();
calculateScore();
});
and I have also tried:
window.onload = function () {
calculateScore();
calculateHiddenScore();
};
How can I trigger these two functions when the page has loaded please? Many thanks.
DOM ready will not trigger an onchange event even if your items are pre-populated.
Therefore you have to modify a bit your script like:
function calculateScore() {
var fields = $('.form-group #input'); // Cache only!
function calculate() {
var score = 0;
fields.each(function() {
score += +$(this).val();
});
$('#score').html(score.toFixed(0));
$('#hidden_score').val(score.toFixed(0));
}
calculate(); // Calculate ASAP (on DOM ready)
fields.on("change", calculate); // and also on change
}
jQuery(function($) { // DOM is ready and $ alias secured
calculateScore(); // Trigger
// other jQuery code here
});
P.S: BTW even if the above is a bit improved, it makes not much sense to loop using each over a single ID #input element - I'll leave that to you...
I am trying to modify the script below to click a button that looks like this on a site:
<button id="checkPrice-02070" onclick="checkPrice(02070,null); return false;" class="orangeDark">
<span>check price</span>
</button>
I am using the code below. So far, the page seems to keep reloading; nothing else happens.
Any advice to someone new?
(function () {
window.addEventListener("load", function (e) {
clickConfirmButton()
}, false);
})();
function clickConfirmButton() {
var buttons = document.getElementsByTagName('button');
var clicked = false;
for (var index = 0; (index < buttons.length); index++) {
if (buttons[index].value == "check price") {
buttons[index].click();
clicked = true;
break;
}
}
if (!clicked) {
setTimeout("window.location.reload()", 300 * 1000);
}
}
A <button>s value is not the visible text. You'd want to search textContent.
However:
If that sample HTML is correct, you'd be better off searching for ids that start with checkPrice. See the code below.
Are you sure you want to reload if the button is not found? If it is added by AJAX this is not the best approach. See this answer.
Don't use setTimeout with a string (to evaluate) argument like that. See the code below.
You do not need to wrap the code in an anonymous function.
Anyway, this should work, given the sample HTML:
window.addEventListener ("load", clickConfirmButton, false);
function clickConfirmButton (zEvent) {
var button = document.querySelector ("button[id^='checkPrice']");
if (button) {
button.click ();
}
else {
setTimeout (function () { location.reload(); }, 300 * 1000);
}
}
To check the button text anyway, use:
function clickConfirmButton (zEvent) {
var buttons = document.querySelectorAll ("button[id^='checkPrice']");
var clicked = false;
for (var index = 0, numBtn = buttons.length; index < numBtn; ++index) {
if (/check price/i.test (buttons[index].textContent) ) {
buttons[index].click();
clicked = true;
break;
}
}
if (!clicked) {
setTimeout (function () { location.reload(); }, 300 * 1000);
}
}
I have a slideshow which works fine, leaving a 3 second gap between images.
I also have a set of dynamically generated links which when clicked on, the next image is corresponds to that link.
What I want to do is skip the 3 second time out when one of these links is clicked - then restart the timeout after the image is changed.
Code below:
$(document).ready(function() {
var images=new Array();
var totalimages=6;
var totallinks=totalimages;
var nextimage=2;
while (totallinks>0) {
$(".quicklinks").prepend("<a href='#' class='"+(parseInt(totallinks))+"' onclick='return false'>"+(parseInt(totallinks))+"</a> ");
totallinks--;
}
function runSlides() {
if(runSlides.opt) {
setTimeout(doSlideshow,3000);
}
}
function doSlideshow()
{
if($('.myImage').length!=0)
$('.myImage').fadeOut(500,function(){slideshowFadeIn();$(this).remove();});
else
slideshowFadeIn();
}
function slideshowFadeIn()
{
if(nextimage>=images.length)
nextimage=1;
$('.container').prepend($('<img class="myImage" src="'+images[nextimage]+'" style="display:none;">').fadeIn(500,function() {
runSlides();
nextimage++;
}));
}
if(runSlides.opt) {} else {
images=[];
totalimages=6;
while (totalimages>0) {
images[totalimages]='/images/properties/images/BK-0'+parseInt(totalimages)+'.jpg';
totalimages--;
}
runSlides.opt = true;
runSlides();
}
$(".quicklinks a").live('click', function() {
nextimage=$(this).attr("class");
});
});
You can stop a timeout using this code:
var t = setTimeout(myFunction,3000);
clearTimeout(t);
Using this, you can abort your timeout when the user clicks the button and call the function directly. Then you can restart the timeout.
Hope this helps.
I have a few buttons on my page and I want to switch focus on each on of them with a certain delay. How I can achieve that with jquery or pure javascript. This is the idea I have for iterating along all my buttons but I obviously end up with the focus on my last button.
$(document).ready(function() {
var allButtons = $(":button");
for (i=0;i<=allButtons.length;i++) {
$('.category_button')[i].focus()
}
});
You can do this by creating a closure within your for loop and passing the index to the setTimeout delay:
var allButtons = $(":button");
for (i = 0; i < allButtons.length; i++) {
(function(index) {
setTimeout(function() {
allButtons[index].focus();
}, 1000*index);
}(i));
}
See example here.
You can use setTimeout to call a function after a delay. The function can set the focus on your next button.
So pseudocode --
setTimeout(2000, focusOn(0));
// somewhere else
function focusOn(i) {
$('.category_button')[i].focus();
if (i + 1 < numButtons)
{
setTimeout(2000, focusOn(i + 1);
}
}
var currentButtonIndex = 0;
function FocusButton()
{
// focus current button index here
// increment counter
// some condition when to stop
// call FocusButton again with delay
// window.setTimeout(FocusButton,1000);
}
Can anybody help me on this one...I have a button which when is hovered, triggers an action. But I'd like it to repeat it for as long as the button is hovered.
I'd appreciate any solution, be it in jquery or pure javascript - here is how my code looks at this moment (in jquery):
var scrollingposition = 0;
$('#button').hover(function(){
++scrollingposition;
$('#object').css("right", scrollingposition);
});
Now how can i put this into some kind of while loop, so that #object is moving px by px for as #button is hovered, not just when the mouse enters it?
OK... another stab at the answer:
$('myselector').each(function () {
var hovered = false;
var loop = window.setInterval(function () {
if (hovered) {
// ...
}
}, 250);
$(this).hover(
function () {
hovered = true;
},
function () {
hovered = false;
}
);
});
The 250 means the task repeats every quarter of a second. You can decrease this number to make it faster or increase it to make it slower.
Nathan's answer is a good start, but you should also use window.clearInterval when the mouse leaves the element (mouseleave event) to cancel the repeated action which was set up using setInterval(), because this way the "loop" is running only when the mouse pointer enters the element (mouseover event).
Here is a sample code:
function doSomethingRepeatedly(){
// do this repeatedly when hovering the element
}
var intervalId;
$(document).ready(function () {
$('#myelement').hover(function () {
var intervalDelay = 10;
// call doSomethingRepeatedly() function repeatedly with 10ms delay between the function calls
intervalId = setInterval(doSomethingRepeatedly, intervalDelay);
}, function () {
// cancel calling doSomethingRepeatedly() function repeatedly
clearInterval(intervalId);
});
});
I created a sample code on jsFiddle which demonstrates how to scroll the background-image of an element left-to-right and then backwards on hover with the code shown above:
http://jsfiddle.net/Sk8erPeter/HLT3J/15/
If its an animation you can "stop" an animation half way through. So it looks like you're moving something to the left so you could do:
var maxScroll = 9999;
$('#button').hover(
function(){ $('#object').animate({ "right":maxScroll+"px" }, 10000); },
function(){ $('#object').stop(); } );
var buttonHovered = false;
$('#button').hover(function () {
buttonHovered = true;
while (buttonHovered) {
...
}
},
function () {
buttonHovered = false;
});
If you want to do this for multiple objects, it might be better to make it a bit more object oriented than a global variable though.
Edit:
Think the best way of dealing with multiple objects is to put it in an .each() block:
$('myselector').each(function () {
var hovered = false;
$(this).hover(function () {
hovered = true;
while (hovered) {
...
}
},
function () {
hovered = false;
});
});
Edit2:
Or you could do it by adding a class:
$('selector').hover(function () {
$(this).addClass('hovered');
while ($(this).hasClass('hovered')) {
...
}
}, function () {
$(this).removeClass('hovered');
});
var scrollingposition = 0;
$('#button').hover(function(){
var $this = $(this);
var $obj = $("#object");
while ( $this.is(":hover") ) {
scrollingposition += 1;
$obj.css("right", scrollingposition);
}
});