How to create a sequence of mouse clicking event - javascript

im implementing a game (this is my first game ever) so Imagine this.
I have 4 images (html5)
onclick they call a function that makes all the game to work!
So, in the game you have turns, the turn says to me how many clicks I will need in that turn.
So how to do it if I always click the image and calls the function and the user is just able to do one click while clicks should be equal that the turn.

Something like this:
<img onclick="myFunction()"/>
<script>
var clickCounter = 0;
var turnNum = 1;
function myFunction () {
clickCounter++;
if (clickCounter == turnNum) {
// do stuff
turnNum++;
clickCounter = 0;
}
}
</script>

Related

How to check if an image is clicked in a function with JavaScript?

I hope this is the right place to ask, I am new to html and javascript. I want to make a simple "game". The part where I got stuck is that everytime you click on any image in the different html screens the function set to that image will be executed. It has no order to it. For example you can press an image that is supposed to be at the end of the game even if you just started it. I think I know where the problem is but not sure how to fix it.
I believe it has something to do with this part of my html code: `
<img id="img1" src="map.jpeg" onclick="myFunction()"/>
Which means that everytime you click the image the function "myFunction()" will be executed.
This is the myFunction code, that shows a "you have found the map" box and then shows an image that has display:"none" in a html file :
var r = confirm("You have found the map!");
if (r == true) {
document.getElementById("img2").style.display = "inline";
} else {
}
}
I think the solution to my problem would maybe be to have the onclick="myFunction()" part in the javascript function somehow, that first checks if the image has been clicked (once) and then continuing with the condition I set. Is there any way to do that? Thankful for any help!
You can count the number of clicks in your function and base your logic on the number of clicks.
I've attempted to use some of the code you provided in my answer below. Please run the snippet and look at the notes in the javascript to understand what's happening.
// set clicks variable to 0, we will use this var to count the number of clicks on the image
var clicks = 0;
// declare function to handle clicks
function handleClicks() {
//whenever this function runs, it will increase the clicks count by 1
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
// if number of clicks is greater than one then show image 2
if (clicks > 1) {
console.log('this image has already been clicked ' + clicks + ' times.')
document.getElementById("img2").style.display = "inline";
} else {
// if clicks aren't greater than 1 do something else
console.log('this is the first time you clicked this image.')
}
}
<div>
<img id="img1" style="width: 25%;" src="https://cdn.pixabay.com/photo/2022/10/03/23/41/house-7497001_960_720.png" onclick="handleClicks()" />
<img id="img2" style="display:none; width: 25%" src="https://cdn.pixabay.com/photo/2022/09/25/23/28/android-7479380_960_720.png" onclick="onClick()" />
<br/>
<p id="clicks"></p>
</div>

How to add eventListener function to elements with unique id?

I have some dynamic cards:
and I want to add eventListener to all play buttons (their code is):
<a href="link">
<img src="play.svg">
<audio src="myMusic.mp3"></audio>
</a>
When I click to "play", it should look like below:
(it should change image and should also play audio)
My JS code so far done is:
<script>
var imgsPlay = document.getElementsByClassName('play-img-loop');
var audioPlayers = document.getElementsByClassName('audio-player');
window.onload = function() {
for(var i = 0; i < imgsPlay.length; i++) {
imgsPlay[i].addEventListener('click', function(event) {
if(this.getAttribute('src') == "img/icons/play.svg") {
this.setAttribute('src', "img/icons/play_red.svg");
audioPlayers[i].play();
} else if(this.getAttribute('src') == "img/icons/play_red.svg") {
this.setAttribute('src', "img/icons/play.svg");
audioPlayers[i].pause();
}
});
}
}
</script>
(I can do it manually, but) can not dynamically. How can I do this ?
You need to delegate! If not, then your question is just a dupe of JavaScript closure inside loops – simple practical example
Here I assume you have a container called cardContainer
I am a little confused as to _red means playing or paused, so change the code below to match. Your example HTML does not match the code you show, there are no classes on the player and image, I therefor assume you do have those in the actual code
window.addEventListener('load', function() {
document.getElementById('cardContainer').addEventListener('click', function(e) {
const tgt = e.target;
if (tgt.classList.contains('play-img-loop')) {
const src = tgt.getAttribute('src');
const running = src.includes('_red');
const audioPlayer = tgt.closest('a').querySelector('audio');
tgt.setAttribute('src', `img/icons/play$(running?'':'_red').svg`);
if (running) audioPlayer.pause();
else audioPlayer.play();
}
});
});
Your problem is the incorrect handling of closures. The event listener call back will never get the correct value of i by the way you have written it. The value of i will always be the last one when the events are fired.
The easiest workaround is to define the variable i only for the scope of a single iteration - which is what the let do.
for(let i = 0; i < imgsPlay.length; i++) {
imgsPlay[i].addEventListener('click', function(event) {
if(this.getAttribute('src') == "img/icons/play.svg") {
...
}
Useful reference: setTimeout in for-loop does not print consecutive values

How to detect a double-click-drag in Javascript/jQuery

I'd like to detect in a web page when the user selects some text by dragging. However, there's one scenario in Windows which I'm calling a "double-click-drag" (sorry if there's already a better name I don't know) and I can't figure out how to detect it. It goes like this:
press mouse button
quickly release mouse button
quickly press mouse button again
drag with the button held down
This causes the dragging to select whole Words. It's quite a useful technique from the user perspective.
What I'm trying to do is tell the difference between a double-click-drag and a click followed by a separate drag. So when I get to step 2 I will get a click event but I don't want to treat it as a click yet; I want to see if they're about to immediately do step 3.
Presumably Windows detects this on the basis of the timing and how much the mouse has moved between step 2 and 3, but I don't know the parameters it uses so I can't replicate the windows logic. note that even if the mouse doesn't move at all between step 2 and 3, I still get a mousemove event.
I realise that I should be designing interfaces that are touch-friendly and device-neutral, and I have every intention of supporting other devices, but this is an enterprise application aimed at users on windows PCs so I want to optimize this case if I can.
We've done something similar. Our final solution was to create a click handler that suppressed the default response, and then set a global variable to the current date/time. We then set another function to fire in some 200ms or so that would handle the "click" event. That was our base function.
We then modified it to look at the global variable to determine when the last click occured. If it's been less than 200ms (modify based on your needs) we set a flag that would cause the click handler to fizzle and called a double click handler.
You could extend that approach by having your click and double click handlers manually fire the drag functionality.
I don't have access to the aforementioned code right now, but here is an example of that framework being used to track keyboard clicks to determine if a scanner or user has finished typing in a field:
var lastKeyPress = loadTime.getTime();
// This function fires on each keypress while the cursor is in the field. It checks the field value for preceding and trailing asterisks, which
// denote use of a scanner. If these are found it cleans the input and clicks the add button. This function also watches for rapid entry of keyup events, which
// also would denote a scanner, possibly one that does not use asterisks as control characters.
function checkForScanKeypress() {
var iVal = document.getElementById('field_id').value;
var currentTime = new Date()
var temp = currentTime.getTime();
if (temp - lastKeyPress < 80) {
scanCountCheck = scanCountCheck + 1;
} else {
scanCountCheck = 0;
}
lastKeyPress = currentTime.getTime();
}
// The script above tracks how many successive times two keyup events have occurred within 80 milliseconds of one another. The count is reset
// if any keypress occurs more than 80 milliseconds after the last (preventing false positives from manual entry). The script below runs
// every 200 milliseconds and looks to see if more than 3 keystrokes have occurred in such rapid succession. If so, it is assumed that a scanner
// was used for this entry. It then waits until at least 200 milliseconds after the last event and then triggers the next function.
// The 200ms buffer after the last keyup event insures the function is not called before the scanner completes part number entry.
function checkForScan() {
var currentTime = new Date();
var temp = currentTime.getTime();
if (temp - lastKeyPress > 200 && scanCountCheck > 3) {
FiredWhenUserStopsTyping();
scanCountCheck = 0;
}
setTimeout(checkForScan, 200);
}
Here is some code that I just wrote up based upon the above ideas. It's not tested and doesn't contain the actual drag events, but should give you a good starting point:
var lastClick = loadTime.getTime();
function fireOnClickEvent(event) {
event.preventDefault;
var currentTime = new Date()
var temp = currentTime.getTime();
if (temp - lastClick < 80) {
clearTimeout(tf);
doubleClickHandler();
} else {
tf = setTimeout(singleClickHandler, 100);
}
lastClick = currentTime.getTime();
}
function singleClickHandler() {
// Begin normal drag function
}
function doubleClickHandler() {
// Begin alternate drag function
}
A single double-click-drag action involves the following events in sequence:
mousedown -> mouseup -> click -> mousedown -> mousemove
With that in mind, I came up with this simple solution:
let maybeDoubleClickDragging = false;
let maybeDoubleClickDraggingTimeout;
const element = document.querySelector('#container');
element.addEventListener("click", function (e) {
maybeDoubleClickDragging = true;
element.removeEventListener("mousemove", handleMousemove);
});
element.addEventListener("mousedown", (e) => {
element.addEventListener("mousemove", handleMousemove);
if (maybeDoubleClickDragging) {
clearTimeout(maybeDoubleClickDraggingTimeout);
return;
}
});
element.addEventListener("mouseup", (event) => {
maybeDoubleClickDraggingTimeout = setTimeout(() => {
maybeDoubleClickDragging = false;
}, 200);
});
function handleMousemove(e) {
if(maybeDoubleClickDragging) {
element.textContent = 'you are double-click-dragging'
}
}
#container {
width: 300px;
height: 300px;
background: yellow;
}
<div id="container"></div>

How to use callback function to make sure a div got hidden only after the function execution is complete

I am adding a functionality to existing code in which I want that one div get visible (containing wait symbol) and after that function is executed then only the div should get hidden. but this function is making some asynchronous calls . so I don't get how to keep that div there
function bounceRunning()
{
var strBounce = confirm("Do you really want to bounce all the running interfaces?");
if (strBounce == true) {
idDivread.style.display='';
var strMsg;
var rows = document.all('KnlTbl').rows;
//loop through our interfaces
for(var i = 0;i < rows.length;i++)
{
//is this interface running?
if(rows[i].cells[1].innerText == 'Running')
{
bounce(i,true);
}
}
//display any message the bounce manager may have
displayBounceMsg();
idDivread.style.display='none';
}
}
How to make sure that this div remains there till display bounce function is complete.and this code is in quirk mode so don't worry about document.getElementById

How do I stop a image gallery from running onClick?

I have a site that has an image gallery that changes images every few seconds using JavaScript; however, I want to know how to STOP the images from changing when a user clicks on one of the images.
So far, the images are rotating as planned, but I can't seem to get the "onClick" scripting to STOP the rotation when the user clicks on an image. I don't need to have an alert popup or need it to do anything, I just need it to STOP the image rotation when someone clicks on one of the pictures.
Here's the HTML code I have:
else (getValue=='STOP')
{
alert("STOPPED");
}
That won't do what you probably want it to do. It should be:
else if (getValue=='STOP')
{
alert("STOPPED");
}
First of all, you missed out on the keyword "IF" in one of the lines of your code.
However, the way to create a terminable repetitive action is to setInterval and then use clearInterval to terminate the repetition.
semaphore = setInterval(somefunction, someinterval);
clearInterval(semaphore);
Example (I wrote this off-the-cuff, so there might be some errors, but you shd get the idea):
<img src="./images/image1.jpg" id="imageGallery" name="imageGallery"
onclick="chooseImg(this)" />
<script>
var turn = setInterval(function(){imgTurn()},5000);
var images = function2CreateImgArray();
var imageN = 0;
function chooseImg(img){
clearInterval(turn);
function2DisplayImg(imageN); // or do whatever
}
function imgTurn(){
if (imageN++ >= images.length) imageN = 0;
function2DisplayImg(imageN++);
}
</script>
You could replace the setInterval with setTimeout.
var turn = setTimeout(function(){imgTurn()},5000);
But then you need to use clearTimeout to stop it:
clearTimeout(turn);
But if you use setTimeout, you would need to setTimeout for the next image display, so you would not even need to clearTimeout to stop the rotation.
<img src="./images/image1.jpg" id="imageGallery" name="imageGallery"
onclick="chooseImg(this)" />
<script>
setTimeout(function(){imgTurn()},5000);
var images = function2CreateImgArray();
var imageN = 0;
var turn = 1;
function chooseImg(img){
turn = 0;
function2DisplayImg(imageN); // or do whatever
}
function imgTurn(){
if (turn==0) return;
if (imageN++ >= images.length) imageN = 0;
function2DisplayImg(imageN++);
}
</script>

Categories