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

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

Related

Jquery checkbox to hide or display an element

I want to use jquery to always hide an element when it is checked, and show the element when it is unchecked. After doing some research I found the "is" attribute and so I created a simple html file as:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
if($("#s").is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
</script>
</head>
<body>
<h2>This is a heading</h2>
<p id="test">This is a paragraph.</p>
<p id="test">This is another paragraph.</p>
<input type="checkbox" id="s">Click me</input>
</body>
</html>
Now for some reason, the jquery is not functional. Any help would be appreciated please. I also tried:
if(document.getElementById('isAgeSelected').checked) {
$("#txtAge").show();
} else {
$("#txtAge").hide();
}
And this doesn't work either.
This is simple in javascript. Please try the following:
var cb = document.getElementById('isAgeSelected');
var txtAge = document.getElementById('txtAge');
$(document).ready(function(){
cb.change= function(){
if(cb.checked) {
txtAge.style.display ='block';
} else {
txtAge.style.display ='none';
}
};
});
In JQuery, you can do the following:
$(document).ready(function(){
$('#s').on('change', function(){
if($(this).is(":checked")){
$('#txtAge').show();
}
else{
$('#txtAge').hide();
}
});
});
You are only checking the checkbox once after the DOM is ready instead you should do it on its change event
$("#s").change(function(){
if($(this).is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
You can do this using following jQuery onchange event and .checked function
$(document).ready(function(){
$('#s').change(function(){
if(this.checked)
$("#test").hide(); // checked
else
$("#test").show();
});
});
Working URL:: https://jsfiddle.net/qn0ne1uz/
Good question !
now you were almost there.
$(document).ready(function(){ // <= !! you only evaluete the chackbox once (on document ready)
if($("#s").is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
What you want to do is monitor checkbox the whole time, like so:
$('#s').bind('change', function() {
if ($("#s").is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
example on jsfiddle
I'm guessing you are wanting to use the jQuery when the checkbox changes - at the moment you are just changing the hide / show it when the document loads.
Also ids need to be unique or jQuery will only get the first item with that id it comes to when you use the id selector. Change the test id to a class.
If you want the click me to change the state of the checkbox, turn it into a label (think you had it as a button) and target the input (using either for="input-id or wrap the label around the input and the text)
Try the following:
// this is to go in your document ready
$('#s').on('change', function() { // bind to the change event of the chackbox
// inside any change event, this is the js object of the thing that changed (ie the checkbox)
if (this.checked) {
$('.test').hide();
} else {
$('.test').show();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>This is a heading</h2>
<!-- ids need to be unique so change this to a class or your jquery won't work -->
<p class="test">This is a paragraph.</p>
<p class="test">This is another paragraph.</p>
<input type="checkbox" id="s"><label for="s">Click me</label>

JQuery Click does not effect window.onload

I have a trouble to fire window.onload event when I clicked, seem it doesn't work to me.
For example, when I clicked checkbox they will call function to render iframe with content. If you uncomment line 2 callOnLoad(), the iframe will be loaded with content, but this is not what I expect, I expect when the checkbox checked, the content in iframe will be rendered.
JSFiddle Demo
I assume that you want below thing:-
iframe will show on page-load(or on window-load),but the text appear/disappear when check-box checked/unchecked?
If yes do like below:-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<input type="checkbox" id="cgv" />
<div id="foo"></div>
</body>
<script>
$(document).ready(function() {
callOnLoad();
$('#cgv').on('click', function(e) {
if ($('#cgv:checked').length !== 0) {
$('#iframe').contents().find("body").append('Test <br/>' + new Date());
} else {
$('#iframe').contents().find("body").html('');
}
});
});
// Function render iframe
function callOnLoad() {
$("#foo").append("<div id=\"div-parent\"><iframe id=\"iframe\"></iframe></div>");
}
</script>
Check Fiddle
JS:
// Add your javascript here
$(function() {
$('#cgv').on('click', function(e) {
if ($('#cgv:checked').length !== 0) {
callOnLoad(); // Load iframe here, iframe does not work, the content does not render
} else {
$('#div-parent').remove(); // Remove div,
}
});
});
// Function render iframe
function callOnLoad() {
$("#foo").append("<div id=\"div-parent\"><iframe id=\"iframe\" class=\"active\"></iframe></div>");
var iframe = $("#foo").find('[id="iframe"]');
iframe.contents().find("body").append('Test <br/>' + new Date());
}
HTML:
<input type="checkbox" id="cgv" />
<div id="foo">
</div>

Jquery .on() not calling selector

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.

If jQuery has Class do this action

I am trying to check whether or not a particular element has been clicked but am having trouble doing so. Here is my HTML:
<div id="my_special_id" class="switch switch-small has-switch" data-on="success" data-off="danger">
<div class="switch-on switch-animate"><input type="checkbox" checked="" class="toggle">
<span class="switch-left switch-small switch-success">ON</span>
<label class="switch-small"> </label>
<span class="switch-right switch-small switch-danger">OFF</span>
</div>
</div>
Here is my jQuery:
<script type="text/javascript">
$(document).ready(function() {
$('#my_special_id').click(function() {
if ($('#my_special_id div:first-child').hasClass('switch-on')) {
window.alert('ON!');
}
});
});
</script>
I am guessing that my id "my_special_id" is not what is actually being clicked?
I guess click event should have event parameter.
$(document).ready(function() {
$('#my_special_id').click(function(e) {
if (e.target check condition) {
window.alert('ON!');
}
});
});
parameter 'e' above specified is the event object that has all info about click event.
so if u check all info under 'e.tartget', u will be able to find out which one is clicked.
Hope it's helpful for you.
Cheers :)
Since you are looking for a alert when the checkbox is clicked
$(document).ready(function() {
$('#my_special_id input.toggle').click(function() {
if ($('#my_special_id div:first-child').hasClass('switch-on')) {
window.alert('ON!');
}
});
});
Demo: Fiddle
Simply put alert when you click on that particular class switch-on
<script type="text/javascript">
$(document).ready(function() {
$('#my_special_id div:first-child .switch-on').on('click',function() {
window.alert('ON!');
});
});
</script>
Or even try like
$(document).ready(function() {
$('#my_special_id').click(function() {
if ($(this + 'div:first-child').hasClass('switch-on')) {
window.alert('ON!');
}
});
});
This JavaScript works for me.
$(document).ready(function() {
$('#my_special_id').click(function() {
if ($('#my_special_id div:first-child').hasClass('switch-on')) {
alert("On!");
}
});
});
You are sure you have JQuery?
Your code looks fine I think either you have a syntax error somewhere else or you do not have JQuert.
does this alert?
$(document).ready(function() {
alert("Jquery works");
});
The click event will trigger to whatever you're bound do. the only time you'd have to be worried is if you bound to both a parent and child (e.g. you had listed #my_special_id,.switch-small--then you'd have to look at e.target).
With that said, you can use scope to limit how jQuery finds the div:first-child. I'm not 100% sure what you're after, but the below appears to do what you're after:
$(document).ready(function() {
$('#my_special_id').click(function() {
// look for div:first-child within `this` (where `this=#my_special_id`
// per the .click selector above)
if ($('div:first-child',this).hasClass('switch-on')) {
window.alert('ON!');
}
});
});
If you're looking to bind to the on/off separately, you may want to change it around a bit. we can still check for .switch-on, just have to traverse differently:
// here we bind to the on/off buttons and not the container
$('#my_special_id .switch-small').click(function(){
// you want the facsimilee of `div:first-child`, so (because we're now
// within that node, we use .parent() to get back up to it
var $firstChild = $(this).parent();
if ($parent.hasClass('switch-on')){
alert('ON!');
}
});

Override javascript click event one time

I would like to replace the default action of an click event for all anchors in a webpage.
When I use this piece of code:
<html> <head> <script>
var list=document.getElementsByTagName("a");
var isChecked = false;
function load () {
for (i=0; i<list.length; i++)
{
var old = (list[i].onclick) ? list[i].onclick : function () {};
list[i].onclick = function () {
if( !isChecked)
{
test();
old();
}
else
old();
};
}
}
function test() {
alert("new action");
isChecked = true;
}
</script> </head>
<body onload="load();">
<a id="nr_1" onClick="alert('test');"> Anchor 1 </A>
<a id="nr_2" onClick="alert('test2');"> Anchor 2 </A>
</body> </html>
When I click an anchor I get the alert out of the test function and then the default function of the second anchor (even when I click the first anchor). When I then again click one of the two anchors I always get the Alert from the second anchor.
How do I put the original onclick functions back for each anchor element? When someone has an solution in jquery I would be glad as well.
EDIT
I was succesfull using this code:
function load()
{
$('a').attr('disabled', 'disabled');
$('a').click(function(e){
if($(this).attr('disabled'))
{
alert("new");
e.preventDefault();
$('a').removeAttr("disabled");
this.click();
}
});
}
On loading of the page this function is called giving all anchor elements a "disabled" attribute. After clicking the element the e.preventDefault() function disables the inline onclick function. Then I remove the "disabled" attribute and call the click function of the element again. because now the element doesn't have a "disabled" attribute only the default function is performed. I'm still open for "more elegant" solutions to this problem, but for now I'm a happy camper!
If you use jQuery you can combine a one-time handler with a persistent handler:
Documentation for .one() and .on()
Working Example: http://jsfiddle.net/Q8gmN/
Sample HTML:
<input type="button" id="click" value="click" />
​
Sample JavaScript:
button.one('click', function () {
console.log('one time function fired');
});
button.on('click', function () {
console.log('persistent function fired');
});
​

Categories

Resources