Jquery .on() not calling selector - javascript

I am trying to make the image of the mole clickable and once clicked will increase the score but the .on() will not work with the class name of the image. It will, however, work if I use the selector "#gamespace", but then clicking anywhere within the game space will get the player points rather than just clicking the mole.
<!DOCTYPE html>
<html>
<head>
<title>Whack-A-Mole (CSCI2447)</title>
<!-- CSS styles: This is for me to worry about; not you. -->
<link href="css/game.css" rel="stylesheet" />
<script src="js/jquery-2.2.1.min.js"></script>
<script type="text/javascript">
var score = 0
var time = 30
var t;
var moleRepeat;
$(document).ready(function(){
$('#start_button').click(function (){
start();
});
$('.mole').on('click' , function () {
counter();
});
});
function getYRandomNumber(){
return Math.floor((Math.random()*300)+0);
};
function getXRandomNumber(){
return Math.floor((Math.random()*600)+0);
};
function counter() {
score++;
$("#score").html(score + ' pts');
};
function start() {
$('#timer').show();
addMole();
decrement();
$('h1').css("color","purple");
$('#gamespace').css("background-color", "green");
};
function decrement() {
time--;
$('#timer').html(time + ' seconds left');
t = setTimeout('decrement()', 1000);
};
function addMole() {
$('#gamespace').append('<img class="mole" src="img/mole.png" onClick="counter()"/>');
moleRepeat = setTimeout('addMole()', 2000);
};
</script>
</head>
<body>
<div id="content">
<h1>Whack-A-Mole</h1>
<p>After clicking "start", you will have 30 seconds to click
as many moles as you can. The moles appear randomly so be ready! </p>
<div id="controls">
<span id="score">0 pts</span>
<button type="button" id="start_button">Start!</button>
</div>
<div id="timer">30 seconds left</div>
<div id="gamespace">
</div>
</div>
</body>
</html>

You are adding click event handler on .mole before it is appended to #gamespace and exist on the page, use event delegation instead
$('#gamespace').on('click','.mole' ,function () {
counter();
});

It looks like your trying to bind to the click event of '.mole' before any exist. Direct bindings only work for elements that already exist in the DOM. You could fix this by doing a delegate binding.
$('#content').on('click', '.mole', function(){ ... });
This will make it listen for the bubbled events from mole elements. Since it works with the bubbled events, it does not matter when they are created.

Related

How do I programmatically trigger "hoverintent" on an element

I am using Tristen Brown's hoverintent library, which is a pure Javascript version of the jQuery hoverIntent library.
I have two elements first and second.
The second element has hoverintent handlers which causes a tooltip to appear above that element. When I manually hover over second, the tooltip appears as expected.
I would like to trigger the tooltip of second programmatically. For example, to make interacting with the first element cause the tooltip of the second element to appear. I have attempted to do this using jQuery trigger. I am able to trigger mouseover handlers, but not any hoverIntent.
Any suggestions?
Here is my Javascript:
$( document ).ready(function() {
var first = document.getElementById('first');
var second = document.getElementById('second');
$(first).mouseover(function(){
$(second).trigger({ type:"mouseover", clientX:"350", clientY:"105" });
$(second).trigger({ type:"mousemove", clientX:"350", clientY:"105" });
});
hoverintent(second, function(e) {
this.className = 'on';
}, function(e) {
this.className = 'off';
});
$(second).mouseover(function(){
console.log("mouseover");
});
});
Here is my HTML:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src='http://tristen.ca/hoverintent/dist/hoverintent.min.js'></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div style="padding:100px;">
<ul class='examples'>
<li id='first'>
Trigger
</li>
<li id='second'>
hoverintent
<span class='popup'>Hi there</span>
</li>
</ul>
</div>
</body>
</html>
The full JS bin is here:
http://jsbin.com/kumeva/4/edit?js,output
I would like to trigger the tooltip of second by mousing over the first element.
You can dispatch a sequence of mouse events to #second and keep the hoverintent code and the dispatch code completely separate like this:
// Hoverintent code
$(document).ready(function() {
var second = document.getElementById('second');
hoverintent(second, function(e) {
this.className = 'on';
}, function(e) {
this.className = 'off';
});
});
///////////////////////////////////
// Dispatch code
$(document).ready(function() {
var first = document.getElementById('first');
var second = document.getElementById('second');
$(first).on("mouseover", function(){
// Send a mouseover to wake hoverintent
var event = new MouseEvent("mouseover");
second.dispatchEvent(event);
// Send a mousemove trigger the internal hover code
event = new MouseEvent("mousemove");
second.dispatchEvent(event);
});
$(first).on("mouseout", function(){
// Cancel the hover code
var event = new MouseEvent("mouseout");
second.dispatchEvent(event);
});
});
Demo
According to the source code of the librairy, it seam that it rely on mouseover and mouseout. To determine the mouse position, it seam to use clientX and clientY, not pageX/Y.
Source file : https://github.com/tristen/hoverintent/blob/gh-pages/index.js

jquery create and delete input fields

I wrote this code here:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"> </script>
</head>
<body>
<button id="add_field">Noch ein Inputfeld</button>
<hr>
<div class="input_fields">
</div>
<script>
$(function(){
var number = 1;
$("#add_field").click(function(){
if(number < 11){
var name = "input";
name = name + number;
$(".input_fields").append('<a>'+ number +':</a><input type="text" name="' + name + '" />entfernen<br>');
number++;
}
else{
alert("10 ist Max");
}
});
$(".remove_field").click(function(){
$(this).parent('input').remove();
x--;
});
});
</script>
</body>
I can create input fields, but if i press on the loeschen Button, nothing happens. So i think here is a mistake in this function:
$(".remove_field").click(function(){
$(this).parent('input').remove();
x--;
});
Try something like this:
$('.input_fields').on('click', '.remove_field', function(){
$(this).parent('input').remove();
x--;
});
You need to use the delegate pattern for the event handler.
You might also be interested in:
Your fiddle fixed (note that you need to re-do the logic for displaying numbers if you want them to handle inputs getting removed from the middle)
https://developer.chrome.com/devtools/docs/javascript-debugging
JQuery event handlers not firing
https://api.jquery.com/on/
You need to use event delegation for attaching events to dynamically added elements:
$("body").on("click",".remove_field",function(){
$(this).parent('input').remove();
number--;
});
Working Demo

How Can I Display a Message Box That Has No Buttons, and That Disappears After a Specified Period of Time?

I have this short code:
<!DOCTYPE html>
<html>
<body>
<button onclick="addedSuccess()">Add to Cart</button>
<p id="demo"></p>
</body>
</html>
<script>
function addedSuccess() {
document.getElementById("demo").innerHTML = "Item added successfully in Cart";
}
</script>
Is there a way to make the message disappear after a given period of time? I want the message to show every time the user would click on "add to cart" then disappear after a period of time without having to worry about pressing on a button to make it go away... Is there a way of doing this? Thanks a lot!
Set a time out function and then remove the html from the element:
function addedSuccess() {
document.getElementById("demo").innerHTML = "Item added successfully in Cart";
setTimeout(function() {
$('#demo').html('');
}, 3000);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button onclick="addedSuccess()">Add to Cart</button>
<p id="demo"></p>
Removing the HTML, rather than hiding the element makes it easier to re-use it on the next click (if that's what you plan to do) - just re-set the content, rather than re-set content and visibility.
use below code . use setTimeout function .here 3000 meaning 3 seconds. you can change seconds as per your requirement.
The setTimeout() method calls a function or evaluates an expression after a specified number of milliseconds.1000 ms = 1 second.
<script>
function addedSuccess() {
document.getElementById("demo").style = "display:block";
document.getElementById("demo").innerHTML = "Item added successfully in Cart";
setTimeout(function() {
document.getElementById("demo").style = "display:none";
}, 3000);
}
</script>
or use below code to clear text
<script>
function addedSuccess() {
document.getElementById("demo").innerHTML = "Item added successfully in Cart";
setTimeout(function() {
document.getElementById("demo").innerHTML = "";
}, 3000);
}
</script>
if you want to use jquery then use below code . see DEMO
<!DOCTYPE html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
<script>
$(document).ready(function(){
$(document).on('click','#addtocart',function(){
$('#demo').html('Item added successfully in Cart');
$('#demo').delay( 3000 ).hide(0);
});
});
</script>
</head>
<html>
<body>
<button id="addtocart">Add to Cart</button>
<p id="demo"></p>
</body>
</html>
use JavaScript function setTimeout()
setTimeout(function,milliseconds,param1,param2,...)
setTimeout(function() {
document.getElementById("demo").style = "display:none";
}, 3000);
Or if you want to do with jquery try this
$( "#demo" ).delay( 3000 ).hide(0);

Change the text of clicked element with 'this' in JavaScript / jQuery callback

Can anybody explain is this in the callback.
Example.
Web page.
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="myApp.js"></script>
</head>
<body>
<button type="button" id="btn001">Show</button><br/>
<p id="p001" class="article">Some contents...</p>
<button type="button" id="btn002">Show</button><br/>
<p id="p002" class="article">Other content...</p>
<!-- more paragraphs -->
</body>
</html>
First, I had written a function for each paragraph. Source code of the myApp.js.
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
$("#p001").toggle();
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
$("#p002").toggle();
});
// repeat code for next paragraphs
});
I get angry with the code repetition, so I tried excluding code to function.
function handleHideShow(par) {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
par.toggle();
}
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
handleHideShow($("#p001"));
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
handleHideShow($("#p002"));
});
});
Toggling paragraphs works, but the text on the button is not changing. Can anybody explain what happens to this?
Why in the first example $(this) selects the clicked element?
What is $(this) in the second example?
And how to solve this problem?
Your first function is an event handler. With Event handlers $(this) automatically refers to the element that was clicked, changed, hovered, etc.. jQuery creates $(this) for you and, while you can't explicitly see it passed into the function it is available to all the code within the click handler's callback.
Your second function is a simple function and is not an event handler therefore jQuery does not create the $(this) reference for you
In your code, you could pass $(this) from your event handler like handleHideShow($(this),$("#p002")); and reference it in your function like function handleHideShow(btn, par). Then, inside handleHideShow, btn will refer to the same element as $(this) referred to in your click handler (see the second snippet below).
But, I would simplify the code alltogether by giving the buttons and paragraphs classes instead of ids and doing this:
$(document).ready(function () {
$('.article').hide();
$('.myBtn').click(function(){
$(this).html( $(this).html() == 'Show' ? 'Hide' :'Show' );
$(this).nextAll('.article').first().toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="myApp.js"></script>
</head>
<body>
<button type="button" class="myBtn">Show</button><br/>
<p class="article">Some contents...</p>
<button type="button" class="myBtn">Show</button><br/>
<p class="article">Other content...</p>
<!-- more paragraphs -->
</body>
</html>
Now, one could argue that this is less efficient as jQuery has to search through more elements to find the paragraph but I believe it to be more robust as you can add as many buttons and paragraphs as you like without worrying about all the sequential ids. And honestly, you'd have to have a pretty giant webpage to see any performance issues.
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
handleHideShow($(this),$("#p001"));
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
handleHideShow($(this),$("#p002"));
});
});
function handleHideShow(btn, par) {
if (btn.html() === "Show") {
btn.html("Hide");
} else {
btn.html("Show");
}
par.toggle();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="myApp.js"></script>
</head>
<body>
<button type="button" id="btn001">Show</button><br/>
<p id="p001" class="article">Some contents...</p>
<button type="button" id="btn002">Show</button><br/>
<p id="p002" class="article">Other content...</p>
<!-- more paragraphs -->
</body>
</html>
You need to pass the object of button in the function:
Try this:
function handleHideShow(par,that) {
if ($(that).html() === "Show") {
$(that).html("Hide");
} else {
$(that).html("Show");
}
par.toggle();
}
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
handleHideShow($("#p001"),this);
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
handleHideShow($("#p002"),this);
});
});
Or you try this also:
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("button[id^='btn']").click(function () {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
$(this).next().toggle();
});
});
The above code is optimal and you can add buttons as many as you want.
The function is called with no special context, and this is not the element.
Reference the function instead
$("#btn001").click(handleHideShow);
$("#btn002").click(handleHideShow);
function handleHideShow() {
$(this).html(function (_, html) {
return html === "Show" ? "Hide" : "Show";
});
$('#' + this.id.replace('btn', 'p')).toggle();
}
FIDDLE

In a for loop how to pass parameter of function invoked by document.getElementById('').onClick

When I click on the div element I want to alert the id of div I clicked on. But on all the div elements it is alerting the last value of array i.e. 'e1'.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body onload="populate();">
<script type="text/javascript">
function populate() {
var divArray = ["a1", "b1", "c1", "d1", "e1"];
for (var x in divArray) {
if (divArray[x] === 'a1')
document.getElementById(divArray[x]).innerHTML = "aaaaa";
else
document.getElementById(divArray[x]).innerHTML = "Common";
document.getElementById(divArray[x]).onclick = function() {
getDiv(divArray[x]);
};
}
}
function getDiv(x)
{
alert(x);
}
</script>
<div id="a1"></div>
<div id="b1"></div>
<div id="c1"></div>
<div id="d1"></div>
<div id="e1"></div>
</body>
</html>
Your x is not the x you're hoping for. This might help.
// ...
document.getElementById(divArray[x]).onclick = (function(n) {
return function() {
getDiv(divArray[n]);
};
}(x));
// ...
Replace getDiv(divArray[x]) with getDiv(this.id), as you want to return the ID of the clicked element.
This is because your for-loop has already ended by the time you actually click the div, so x is whatever it was when the loop ended.
To fix this, you need to call getDiv(this.id);
Try passing the click event (e) into your click handler
document.getElementById(divArray[x]).onclick = function(e) {
console.log(e.toElement.id);
};

Categories

Resources