I'm creating a JavaScript and JQuery "Whack-a-Mole" game, and I'm appending "mole" images at random coordinates into the gamespace every two seconds. When a mole is clicked, I would like it to hide (disappear from the screen). However, the way I have the code written now, clicking on one mole causes all mole images to be hidden. Would love to hear any thoughts on selecting and hiding only the clicked mole image, but not hiding the other mole images.
Here's my "addMole" function:
function addMole() {
xPos = randPosX();
yPos = randPosY();
$('#gamespace').append('<img src="img/mole.png" style="top:'+yPos+'px;left:'+xPos+'px" />').addClass('mole'); // insert mole into #gamespace
repeatAddMole = setTimeout("addMole()", 2000); // append moles every 2 seconds
};
And here's the game's main function:
$(document).ready(function() {
$('#start_button').click(function() {
start();
$('#timer').show(); // show timer
$('.mole').on("click", function(){
incScore();
$('img', this).hide();
});
});
Thanks!
You are adding the mole class to the #gamespace, not the image. Maybe you want this:
$('#gamespace').append($('<img src="img/mole.png" style="top:'+yPos+'px;left:'+xPos+'px" />').addClass('mole'));
Here's a demo to help you https://jsfiddle.net/bradlis7/ubar2Lzb/1/. I like to keep the functions doing what they say they are doing (addMole should not really be setting a new timer).
You can do it like this:
$('#gamespace').append('<img onclick="this.style.display=\'none\'" src="img/mole.png" style="top:'+yPos+'px;left:'+xPos+'px" />').addClass('mole'); // insert mole into #gamespace
Also the problem is cause you attach event only to created images (moles) before you clicked on start.
You can use event delegation. Use this code out of start button click handler.
$( "#gamespace" ).on( "click", "img", function( event ) {
incScore();
$(this).hide();
});
I would do it pretty much in this way:
function addMole() {
xPos = randPosX();
yPos = randPosY();
var el = $('#gamespace').append('<img src="img/mole.png" style="top:'+yPos+'px;left:'+xPos+'px" />').addClass('mole');
el.on("click", function(){
$(this).remove();
incScore();
});
repeatAddMole = setTimeout("addMole()", 2000);
};
append function returns you jQuery object of appended element, so you can attach event directly on it after it is created. If you create events before objects are created, events will not be attached to it. This way, you create element and then attach the event.
You could do it in the way mhodges wrote in his comment, but I simply don't like this way because I believe it's not that efficient.
Related
I am finding it very difficult to create programmatic events using Hammer.js. What I would like is to have two elements, when element one is tapped, I would like to fire or trigger or emit an event on the second element as well.
My end goal is to use this technique when dragging items. Basically, hold down on an element to create a clone of it, and then emit the drag event on the clone. This would stop dragging the original element and start the drag on the new cloned element.
With that said, I've created a simple jsFiddle http://jsfiddle.net/vk3reu0w/1/. It has two div elements. What I am trying to do is have div one be tapped and an event automatically fire a tap event on div two.
var buttonOne = document.getElementById("one");
var buttonTwo = document.getElementById("two");
var mc1 = Hammer(buttonOne);
var mc2 = Hammer(buttonTwo);
mc1.on("tap", function(event) {
alert("MC1 Tapped");
console.log("MC1 Tapped");
mc2.emit("tap");
});
mc2.on("tap", function(event) {
alert("MC2 Tapped");
console.log("MC2 Tapped");
});
Any help is much appreciated. Thanks.
You should add to .emit method a second param.
mc1.on("tap", function(event) {
alert("MC1 Tapped");
console.log("MC1 Tapped");
mc2.emit("tap", event); // HERE
});
http://jsfiddle.net/Lnvgcupg/1/
You can custom your event as well.
mc1.on("tap", function(event) {
console.log("MC1 Tapped");
var customEvent = JSON.parse(JSON.stringify(event)); // Creating
customEvent.center.x = 999; // ...changing something
mc2.emit("tap", customEvent); // Emitting
});
http://jsfiddle.net/ntgrdq7n/3/
I am making a Sentence Generator. So far, it can take a list of words. Then it gets data from sentence.yourdictionary.com to take a sentence. I display the first sentence from sentence.yourdictionary.com using $("ul.example>li").first().Then it is put into a paragraph <p id="sents">.
So if you entered in the words yo and nose your output would be
<p id="sents"><li id="yo"><strong>Yo</strong> ' money
back a hund'd times, de preacher says!</li><li id="nose">I will no longer be caught with a
bleeding <strong>nose</strong>, heart palpatations, week long benders or hurting myself in any major way.</li></p>
I want a function to be called when you hover over the new list items.
$(document).ready( function() {
$("li").hover( function () {
$(this).append("<span>Testing</span>");
var id = $(this).attr("id");
console.log(id);
}, function () {
$(this).find("span:last").remove();
});
});
This doesnt work after the new list items are injected into the DOM. I tried adding an event listener for mousemove, but then when you hover over it the word "test" shows up a bunch of times! How can I make it happen after the new list items are injected?
Here is a jfiddle if you want some clarification: http://jsfiddle.net/varhawk5/cNKyx/1/
Thank you so much. Sorry I'm just learning javascript!
EDIT
To fix this issue, I used the .on() function as the comments suggested. There is no "hover" event though, so I think this is the only way.
$("body").on("mouseenter", "li#topWord", function() {
var word = $(this).data("word");
var sents = sentences[word]
$(this).html("<div class='restOfSents' data-word='" + word +"'></div>");
for(var i=1; i<sentences[word].length; i++) {
$(".restOfSents").append($(sentences[word][i]));
}
console.log(sents);
});
$("body").on("mouseleave", "li", function() {
// Remove the new div
});
$(document).ready( function() {
$(document).on('hover','li', function () {
$(this).append("<span>Testing</span>");
var id = $(this).attr("id");
console.log(id);
}, function () {
$(this).find("span:last").remove();
});
});
You're right! The reason for this, is that $(document).ready() only gets called on page load. You can either manually add a new event hook to each new element as you add it, or take advantage of jQuery's "on" functionality which will automatically detect new dom elements which match your criteria.
You should make use of .on() rather than .hover():
$('li').on('mouseenter', function() { ... })
Also you shouldn't use IDs for this. Make use of data-* attributes instead. Otherwise your code will break when a user enters the same word twice (as IDs are unique).
var id = $(this).attr('data-example');
I looking for a solution for iOS, like hover in the 'desktop world'.
I have a lot of image item on my page, and when the user move his finger across the images, the actual image gets opacity 0. (so one move hides all item :) )
I tried something like this:
$("img").on "touchstart", ->
$(this).animate({opacity:0}, 100)
If you want to hide all images when one recive the touchstart-event you should use:
$("img").on("touchstart", function() {
$("img").animate({opacity:0}, 100);
});
Or even better:
var $images = $("img").on("touchstart", function() {
$images.fadeTo(100, 0);
});
The this keyword refers the the DOM Element receiving the event rater then the whole jQuery collection.
Not good with CoffeeScript.
$(document.body).on "touchmove", (event) ->
if $(event.target).is("img")
$(event.target).animate
opacity: 0
, 100
I am currently working on a website and got stuck with the following problem:
On the website I have small dots (images) with the ids "dot0001", "dot0002", "dot0003", etc. . I also have hidden images (visibility:hidden) with the ids "info0001", "info00002", "info0003", etc.
I am looking for a jQuery solution. What I need is a code that allows the following events:
When users move the mouse over "dot0001" the image "info0001" becomes visible and when they leave "dot0001", "info0001" becomes invisible again. Same applies to "dot0002"-"info0002" , "dot0003"-"info0003" etc. So only the info-images with the corresponding 4 digit number become visible.
I gave it endless tries but got nowhere and there is not even a point in pasting my code.
Any help appreciated!
Something like this should work (though untested):
$('[id^="dot"]').on({
mouseenter: function(e) {
var infoId = this.id.replace('dot', 'info');
$('#' + infoId).show();
},
mouseleave: function(e) {
var infoId = this.id.replace('dot', 'info');
$('#' + infoId).hide();
}
});
That uses an attribute-starts-with selector to select all elements with an id beginning with "dot", then binds the event handlers to them. The event handler functions themselves simply replace the "dot" part of the id with "info" to form the correct new one, then show or hide the element as appropriate.
Don't forget to wrap that code in a DOM ready event handler so that it executes once the elements actually exist, otherwise it won't work.
Get all elements which id starts with "dot" and show/hide related "info" on mouseover/out:
$("[id^=dot]").hover(
function(){
$("#info" + this.id.substring(3)).css({"visibility":"visible"});
},
function(){
$("#info" + this.id.substring(3)).css({"visibility":"hidden"});
}
);
http://jsfiddle.net/EGBnR/
I need to make a div so that when the cursor hovers over it then I can detect it (using javascript) but I want to make it so that you can click through the div to the elements underneath. Is there a way to do this?
Thanks
Edit
As far as I'm aware, and through my quick searches, I do not believe that you are able to do this, if you can it wouldn't be easy and or very practical I wouldn't think.
old
Using jQuery:
$(document).ready(function(){
$("body").on("hover", "div", function(){
//do whatever you want on hover
});
$("body").on("click", "div .child-class", function(){
//do whatever on click
});
});
If this doesn't answer your question and do what you want, let me know what more specifically why it doesn't.
There are multiple solutions for this depending on your problem.
I will start with some assumptions:
1. You are the owner of the page (you know what happens there);
2. You know what element is beneath the clicked element.
For this case check this code:
//function executed when you click on element with id: beneath
function clickOnBeneath() {
alert("beneath click");
}
//function executed when you click on element with id: above
function clickOnAbove() {
var beneathEl;
beneathEl = document.getElementById("beneath");
beneathEl.click();
}
//attach click event on element with id: above and beneath
function attachClickOnElements() {
var aboveEl,
beneathEl;
aboveEl = document.getElementById("above");
aboveEl.addEventListener("click", clickOnAbove, false);
beneathEl = document.getElementById("beneath");
beneathEl.addEventListener("click", clickOnBeneath, false);
}
attachClickOnElements();
and also working example: http://jsfiddle.net/darkyndy/xRupb/
If you don't know what element is beneath it then I will try to find some code as I wrote a couple of years back something like this, as start point you can check getClientRects() function that is available on HTML elements (documentation: https://developer.mozilla.org/en-US/docs/DOM/element.getClientRects )