Changing what is shown to a user using dynamic questions - javascript

I want to, inside a webpage, as a user a series of questions, and then serve them up a page based on their response. But, I don't want to redirect them to a separate form/page.
For example:
1)Question: Do you want to see a Square?
2)Question: Do you want to see a Circle?
3)Question: Do you want it Red?
4)Question: Do you prefer Blue?
5)Question: Do you want it Orange?
6)Question: Do you prefer Yellow?
The user would see the first question, followed by a yes button and no button. If they clicked yes, then it would show them the 3rd question, if they clicked no, then it would show them the 2nd question. No to 3rd Question leads to 4th Q. No to 2nd Q leads to 5th Q, etc.
The end images are a Red Square, Blue Square, Orange Circle, Yellow Circle, and Black Square, and will be shown to users based on how they moved through the questions.
I know I can do this by giving an id to each question and set of buttons, and showing/hiding button/question sets using JS based on answers to other questions (then showing final based on last question answered) but I'm curious if there's a cleaner way to do this, maybe with some sort of form, tree, and state assignment? In my real-world version it's possible that two answers lead to the same state.
Here's the beginning of my naive implementation:
<div id="b1">
<h5 id="q1">Question: Do you want to see a Square?</h5>
<button id="ay1">Yes</button><button id="an1">No</button>
</div>
<div class ="box" id="b2"><h5 id="q2">Question: Do you want to see a Circle?</h5>
<button id="ay2">Yes</button><button id="an2">No</button>
</div>
<div class ="box" id="b3"><h5 id="q3">Question: Do you want it Red?</h5>
<button id="ay3">Yes</button><button id="an3">No</button>
</div>
And a jsFiddle of the idea

var shape, colour;
$("#an1").click(function() {
$("#b1").fadeOut();
$("#b2").fadeIn();
});
$("#ay1").click(function() {
$("#b1").fadeOut();
$("#b3").fadeIn();
shape="Square";
});
$("#ay2").click(function() {
$("#b2").fadeOut();
$("#b3").fadeIn();
shape="Circle";
});
$("#an2").click(function() {
$("#b2").fadeOut();
$("#b1").fadeIn();
});
$("#ay3").click(function() {
$("#b3").hide();
colour="red";
show();
});
$("#an3").click(function() {
$("#b3").fadeOut();
$("#b4").fadeIn();
});
$("#ay4").click(function() {
$("#b4").hide();
colour="blue";
show();
});
$("#an4").click(function() {
$("#b4").fadeOut();
$("#b5").fadeIn();
});
$("#ay5").click(function() {
$("#b5").hide();
colour="orange";
show();
});
$("#an5").click(function() {
$("#b5").fadeOut();
$("#b6").fadeIn();
});
$("#ay6").click(function() {
$("#b6").hide();
colour="black";
show();
});
$("#an6").click(function() {
$("#b6").fadeOut();
$("#b3").fadeIn();
});
function show() {
var div="<div id='myShape' class='" + shape + "' style='background: " + colour + "'></div>";
document.body.innerHTML+=(div);
}
.box {
position: absolute;
}
#myShape {
width: 100px;
height: 100px;
background: beige;
}
.Circle {
border-radius: 50%;
}
.Red {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class ="box" id="b1"><h5 id="q1">Question: Do you want to see a Square?</h5>
<button id="ay1">Yes</button><button id="an1">No</button>
</div>
<div class ="box" id="b2" hidden><h5 id="q2">Question: Do you want to see a Circle?</h5>
<button id="ay2">Yes</button><button id="an2">No</button>
</div>
<div class ="box" id="b3" hidden><h5 id="q3">Question: Do you want it Red?</h5>
<button id="ay3">Yes</button><button id="an3">No</button>
</div>
<div class ="box" id="b4" hidden><h5 id="q4">Question: Do you want it Blue?</h5>
<button id="ay4">Yes</button><button id="an4">No</button>
</div>
<div class ="box" id="b5" hidden><h5 id="q5">Question: Do you want it Orange?</h5>
<button id="ay5">Yes</button><button id="an5">No</button>
</div>
<div class ="box" id="b6" hidden><h5 id="q6">Question: Do you want it Black?</h5>
<button id="ay6">Yes</button><button id="an6">No</button>
</div>

Related

Only allowing one action and recording it in javascript

I have a two part problem I am wanting to create a game of rock,paper scissors, that allows the user to play until he loses once against the computer. I will show the user a series of images (rock,paper,scirssors). I will then highlight the choice if the user clicks the image, then double click to confirm their choice to play against.
So I have this in my HTML that is shown after the user clicks play now:
<div id="playOptionsclassic" style="display: none">
<img id="clickedRock" src="img/rock.jpg" onclick="playClassicWithRock()" dis/>
<img id="clickedPaper" src="img/paper.jpg" onclick="playClassicWithPaper()"/>
<img id="clickedScissors" src="img/scissors.jpg" onclick="playClassicWithScissors()" />
</div>
Then in my Jquery file I have:
$(function () {
$("img").one("click",function() {
$(this).css('border', "solid 2px red");
});
});
The problem I have here is the user can click more then one img right now. I want it to toggle the click, so if I click rock first, oh I change my mind I want scissors, unhighlight rock and highlight scissors. Or should i just make so it's one click and it is locked in?
How can I then pass a value of "rock","Paper" Scissors" into a javascript file to see if they beat the computer?
Use $(this).siblings().css('border','0px') for change the colors of the clicked item and use playClassicWithScissors(this) "this" to pass your element to the function
$(function () {
$("img").on("click",function() {
$(this).siblings().css('border','0px')
$(this).css('border', "solid 2px red");
});
});
function playClassicWithRock(ele){
alert($(ele).attr('id'));
}
function playClassicWithPaper(ele){
alert($(ele).attr('id'));
}
function playClassicWithScissors(ele){
alert($(ele).attr('id'));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="playOptionsclassic" style="display: block">
<img id="clickedRock" src="img/rock.jpg" onclick="playClassicWithRock(this)" dis/>
<img id="clickedPaper" src="img/paper.jpg" onclick="playClassicWithPaper(this)"/>
<img id="clickedScissors" src="img/scissors.jpg" onclick="playClassicWithScissors(this)" />
</div>
First of all, you should prefer to use classes to individual CSS styles. It is generally easier (and much more robust, maintenance-wise) to add and strip a class, than to adjust the CSS properties.
An easy way to do this is to find a selector that matches all three images; then you can strip the "selected" class from all images (whether they have it or not) before you add it to the clicked image. jQuery makes this very easy.
The other typical way is to store the selection, so you can explicitly deselect that element before selecting a new one.
<div id="playOptionsclassic" style="display: none">
<img id="clickedRock" src="img/rock.jpg" class="game-opt-img" data-val="rock" dis/>
<img id="clickedPaper" src="img/paper.jpg" class="game-opt-img" data-val="paper"/>
<img id="clickedScissors" src="img/scissors.jpg" class="game-opt-img" data-val="scissors" />
</div>
Then in your javascript
$(function(){
$(".game-opt-img").on("click", function() {
$(".game-opt-img").off("click"); // remove all image's click event
var val = $(this).data("val"); // get the value of the image that the user choose.
});
});
You can create a class in css called .active which adds the border to the image. So, when you click on an image, all you need to do is remove the .active class from all the images, and then add the .active to the image you clicked on.
This can be achieved by doing the following:
$(function() {
$("#playOptionsclassic div").on("click", function() {
$("#playOptionsclassic div").removeClass('active');
$(this).addClass('active');
});
});
.active {
border: 2px solid red;
}
/* Styles for example */
#playOptionsclassic div {
height: 100px;
width: 100px;
background: black;
color: white;
margin: 1%;
display: inline-block;
text-align: center;
box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="playOptionsclassic">
<!-- Images replaced with divs for example -->
<div id="clickedRock">Rock img</div>
<div id="clickedPaper">Paper img</div>
<div id="clickedScissors">Scissors img</div>
</div>
First you can add a predefined class to each of the images and assign them a data attribute for what they represent (rock, paper, scissors) as follows:
<div id="playOptionsclassic" style="display: none">
<img class="option" src="img/rock.jpg" data-option="rock"/>
<img class="option" src="img/paper.jpg" data-option="paper"/>
<img class="option" src="img/scissors.jpg" data-option="scissors"/>
</div>
Then you can create a class in CSS where you will have the style of the clicked image:
.active {
border: 2px solid red;
}
And in your javascript, when the user single clicks one of the options, remove the active class from the others and add it to that image.
And when they double click, check if an option was selected and perform the necessary actions.
$(function() {
$("img.option").on("click", function() {
$("img.option.active").removeClass("active");
$(this).addClass("active");
});
$("img.option").on("dblclick", function() {
var selectedOption = $("img.option.active");
// Check if an option was selected.
if (selectedOption.length) {
// Save the name of the option (rock, paper or scissors) in a variable.
var optionName = selectedOption.data("option");
// Perform your action here.
} else {
alert("Please select an option.");
}
});
});

Dynamic webpage? (HTML DOM, js)

I'm trying to change the content in a HTML using DOM JS. Rather than getting the elements by the P tag, I want to use the DIV ID.Is this possible?
In my HTML, I have two separate DIV classes, both named the same. I want one to display depending on what button the user clicks.
HTML:
<button type="button" onclick="changeContent(1)" >Example 1</button>
<button type="button" onclick="changeContent(2)" >Example 2</button>
<p id="demoX"></p>
<div class="ex1">
<h1> Example 1 </h1>
<p> nothing </p>
</div>
<div id="ex1">
<h1> Example 2 </h1>
<p> more of nothing </p>
</div>
JS:
function changeContent(inNum) {
var x = document.getElementById("ex1");
if (inNum == 1){
document.getElementById("demoX").innerHTML = x[0].innerHTML;
}
else if (inNum == 2){
document.getElementById("demoX").innerHTML = x[1].innerHTML;
}
}
How do I approach this?
First of all, you shouldn't give the same ID to more than one div so just give them both the class - 'ex1' - and then you select them by a javascript selector called getElementsByClassName('class-name') [replace class-name with the actual class name, in this case ex1] this function gets all the elements with this class name and stores them in an array. Then you do the logic for which button is pressed. And when a button is pressed you should set the display of the wanted div to 'block' [you should default it to hidden in CSS].
function showDiv(id) {
var divs = document.getElementsByClassName('ex1');
if (id === 'btn1') { divs[0].style.display = 'block' }
if (id === 'btn2') { divs[1].style.display = 'block' }
}
.ex1 {
width: 300px;
height: 300px;
background-color: green;
display: none;
margin: 50px;
}
<button id='btn1' onClick='showDiv(this.id)'>button 1</button>
<button id='btn2' onClick='showDiv(this.id)'>button 2</button>
<div class='ex1'>I'm div 1</div>
<div class='ex1'>I'm div 2</div>
you can also change the .style thing to change the inner html as you have done in your original code.

How do I hide the closest element to the element that was clicked without jQuery?

I have a function that changes the src attribute of an icon when this one is clicked.
I also want it to hide the closest icon of the class fave_icon. I tried the following but it's not working:
function trash(event, trashcan){
event.stopPropagation();
if (trashcan.getAttribute('src') == "Iconos/tacho.png")
{
trashcan.src = "Iconos/warning.png"; //this works ok
var heart = trashcan.closest(".fave_icon");
heart.style.visibility = "hidden"
}
}
Basically I want to hide the closest element with class fave_icon to trashcan.
On the HTML I have this several times:
<button class="accordion">
<div>
<img src="Iconos/heart.png" onclick="fav(event,this);" alt="Fave" class="fave_icon">
</div>
<div>
<img src="Iconos/tacho.png" onclick="trash(event,this);" alt="Delete" class="delete_icon">
</div>
</button>
If fave_icon is a class then you have to place dot (.) before the class name as part of the selector.
Change var heart = trashcan.closest("fave_icon");
To
var heart = trashcan.closest(".fave_icon");
Based on the code and HTML you have provided you can do something like the following:
function trash(event, trashcan){
event.stopPropagation();
if (trashcan.getAttribute('src') == "Iconos/tacho.png"){
trashcan.src = "Iconos/warning.png"; //this works ok
var heart = trashcan.closest('button').querySelector('.fave_icon');
heart.style.visibility = "hidden";
}
}
<button class="accordion">
<div>
<img src="Iconos/heart.png" onclick="fav(event,this);" alt="Fave" class="fave_icon">
</div>
<div>
<img src="Iconos/tacho.png" onclick="trash(event,this);" alt="Delete" class="delete_icon">
</div>
</button>
From the trash icon, you go up a level to the div, select the previousElementSibling to get the heart's div, and then go down a level to the heart image itself.
Because the element is already included in the event target, you don't need to pass this. Or, even better, if you select the trash image first, you can avoid this entirely and use explicit variable names, which are easier to understand and debug.
But inline event handlers are essentially eval inside HTML markup - they're bad practice and result in poorly factored, hard-to-manage code. Seriously consider attaching your events with JavaScript, instead, eg: https://developer.mozilla.org/en/DOM/element.addEventListener
Another problem is that buttons should not have closing tags. Use a container element instead, like a div.
So, try something like this:
document.querySelectorAll('img[src="Iconos/tacho.png"]').forEach(img => {
img.onclick = () => {
const heartImg = img.parentElement.previousElementSibling.children[0];
heartImg.style.visibility = 'hidden';
};
});
<div class="accordion">
<div>
<img src="Iconos/heart.png" alt="Fave" class="fave_icon">
</div>
<div>
<img src="Iconos/tacho.png" alt="Delete" class="delete_icon">
</div>
</div>
you can add a class to the clicked element and use the general sibling combinator if the two items are adjacent.
document.getElementById("hide")
.addEventListener("click", (event) => {
event.target.classList.add('active');
}, false);
#hide.active~.element {
visibility: hidden;
}
#hide {
cursor: pointer;
}
.accordion {
padding: 15px;
background: lightgrey;
border-bottom: 1px solid grey;
}
.accordion div {
color: black;
margin-right: 20px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/icono/1.3.0/icono.min.css" rel="stylesheet" />
<div class="accordion">
<div class="icono-trash" id="hide"></div>
<div class="element icono-heart"></div>
</div>

How to create a toggle active button with javascript

I want to create a toggle button consisting eight buttons. If seven out of the toggle buttons are clicked it toggles two classes(and changes it's CSS styles).
If one(the daily button) out of the toggle buttons is clicked it toggles the styles of the other seven.
This is my code:
The toggleclass(this) function I predefined toggles the class1 to a class2 CSS style.
I tried doing this
<div id="menu1">
$(document).ready(function() {
$('#hey').click(function()
{
if($('#btnDiv,#btnDiv1,#btnDiv2,#btnDiv3,#btnDiv4,#btnDiv5,#btnDiv6').hasClass('class1')){
$('#btnDiv,#btnDiv1,#btnDiv2,#btnDiv3,#btnDiv4,#btnDiv5,#btnDiv6').toggleClass('class2')
}else{
$('#btnDiv,#btnDiv1,#btnDiv2,#btnDiv3,#btnDiv4,#btnDiv5,#btnDiv6').toggleClass('class2')
}
});
});
<div class="cols"><button id="btnDiv" onclick="toggleclass(this);monday();" class="class1"><h5>MONDAY</h5></button></div>
<div class="cols"><button id="btnDiv1" onclick="toggleclass(this);tuesday();" class="class1"><h5>TUESDAY</h5></button></div>
<div class="cols"><button id="btnDiv2" onclick="toggleclass(this);wednesday();" class="class1"><h5>WEDNESDAY</h5></button></div>
<div class="cols"><button id="btnDiv3" onclick="toggleclass(this);thursday();" class="class1"><h5>THURSDAY</h5></button></div>
<div class="cols"><button id="btnDiv4" onclick="toggleclass(this);friday();" class="class1"><h5>FRIDAY</h5></button></div>
<div class="cols"><button id="btnDiv5" onclick="toggleclass(this);saturday();" class="class1"><h5>SATURDAY</h5></button></div>
<div class="cols"><button id="btnDiv6" onclick="toggleclass(this);sunday();" class="class1"><h5>SUNDAY</h5></button></div>
<div class="cols"><button id="hey" onclick="toggleclass(this);daily();showdaily();" class="class1"><h5>DAILY</h5></button></div>
But it doesn't work. Help me out please
What do I do to get the daily button to change the styles of other buttons(if they are clicked) to class 1 when clicked and change back to class2 again
A straightforward answer using raw JavaScript would be truly appreciated as I'm pretty new to JavaScript.. :)
If you're doing this as a "learning exercise," then you're doing yourself no favors with all the extra HTML in there. I'd even go so far as to get rid of the divs containing each button, but that's just me.
So I'll post a starting point, but this is just an off-the-cuff thing, YMMV. Logically, walk through what you actually want to happen: when a button is clicked, you want to set ALL other buttons to "class1", and then you want to set the currently clicked button to "class2". Research using the javascript classList attribute, it's very handy for this.
I did edit this, as you're looking to TOGGLE the clicked button, so now the code sets all sibling buttons back to the class1, but then the last two lines actually toggle the class1/class2 rather than forcing the button on. For more on what you can do with classList, look at this.
Third time through. You not only want to be able to toggle the classes, but you want that select all button to toggle the selection of everything? Turn them all ON, turn them all OFF, or simply toggle each one? I've got it so that clicking 'Daily' will toggle all the selected buttons. Again, largely off-the-cuff, and largely playing here.
Based on your comment, clicking on 'Daily' toggles ALL day buttons to class1. I've commented out the section in the day handling to make the day selection be exclusive, but its still there if you need.
// First, store references to the bits we'll manipulate.
var menu = document.querySelector("#menu1");
var dayBtnEls = document.querySelectorAll(".day-button");
var allBtnEl = document.querySelector("#hey");
// Now, rather than adding them in the HTML, I'll
// attach my event listeners. The menu listens
// for clicks on the buttons, and the '#hey' button
// also has a listener. I could have done it all
// within that single menu listener, as that is
// also checking if the clicked button is #hey, but
// I figured "what the hey..."
menu.addEventListener("click", toggleDays);
allBtnEl.addEventListener("click", toggleAll);
/****
* Without knowing for sure, I've simply set the
* toggleAll function to go through all the day
* buttons and toggle their class1/class2. So having
* one of the buttons selected and clicking 'Daily'
* will leave all but that one selected.
* It's really up to you what you want for the toggle
* behavior, this is mostly just an example of what
* you COULD do.
****/
function toggleAll(event){
if (event.target.innerText == "Select All") {
// go through all the day button els.
for (var i=0; i<dayBtnEls.length; i++){
// toggle their class1/class2
dayBtnEls[i].classList.add("class1");
dayBtnEls[i].classList.remove("class2");
}
event.target.innerText = "Deselect All";
} else {
// go through all the day button els.
for (var i=0; i<dayBtnEls.length; i++){
// toggle their class1/class2
dayBtnEls[i].classList.remove("class1");
dayBtnEls[i].classList.add("class2");
}
event.target.innerText = "Select All";
}
}
/****
* again, without knowing what you're trying to do,
* I've set it so that clicking on a day button
* forces all the other day buttons to be toggled
* back to class1, then the clicked element will
* toggle back-and-forth from class1 to class2.
****/
function toggleDays(event){
// as we're listening at the menu level, and #hey
// is a child of menu, we need to filter that out.
if(event.target.id != "hey") {
var thisDayEl = event.target;
/****
* I'm commenting out this section, as it seems you
* don't want to have it be an exclusive toggle.
* I don't want to delete it yet, as I don't know
* for sure, but.
*
// set ALL buttons back to class 1...
for (var i=0; i<dayBtnEls.length; i++){
if(dayBtnEls[i] != thisDayEl) {
dayBtnEls[i].classList.remove("class2");
dayBtnEls[i].classList.add("class1");
}
}
****/
// Now, set just the clicked button to class2
thisDayEl.classList.toggle("class2")
thisDayEl.classList.toggle("class1");
}
}
.class1 {
color: #333;
background-color: #ccc;
}
.class2 {
color: #ccc;
background-color: #333;
}
.cols {
float: left;
}
.cols button {
height: 50px;
}
<div id="menu1">
<div class="cols">
<button id="btnDiv" class="day-button class1">MONDAY</button>
</div>
<div class="cols">
<button id="btnDiv1" class="day-button class1">TUESDAY</button>
</div>
<div class="cols">
<button id="btnDiv2" class="day-button class1">WEDNESDAY</button>
</div>
<div class="cols">
<button id="btnDiv3" class="day-button class1">THURSDAY</button>
</div>
<div class="cols">
<button id="btnDiv4" class="day-button class1">FRIDAY</button>
</div>
<div class="cols">
<button id="btnDiv5" class="day-button class1">SATURDAY</button>
</div>
<div class="cols">
<button id="btnDiv6" class="day-button class1">SUNDAY</button>
</div>
<div class="cols">
<button id="hey" class="all-button class1">Select All</button>
</div>
</div>
Doing the same thing WITH YOUR CODE, with a few very minor changes. Basically, rather than that really long selector list, I added another class to all the day buttons and I use THAT to gather them. I added a listener for the day buttons being clicked on that simply toggles their class1/class2, and the if statement you had in the daily button handler was doing the same thing in either case, so I just got rid of the if. Here is THAT example:
$(document).ready(function() {
$(".day-button").on("click", function() {
$(this).toggleClass("class1").toggleClass("class2");
})
$('#hey').click(function() {
$('.day-button').removeClass('class2').addClass("class1");
});
});
.class1 {
color: #333;
background-color: #ccc;
}
.class2 {
color: #ccc;
background-color: #333;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu1">
<div class="cols">
<button id="btnDiv" class="day-button class1">MONDAY</button>
</div>
<div class="cols">
<button id="btnDiv1" class="day-button class1">TUESDAY</button>
</div>
<div class="cols">
<button id="btnDiv2" class="day-button class1">WEDNESDAY</button>
</div>
<div class="cols">
<button id="btnDiv3" class="day-button class1">THURSDAY</button>
</div>
<div class="cols">
<button id="btnDiv4" class="day-button class1">FRIDAY</button>
</div>
<div class="cols">
<button id="btnDiv5" class="day-button class1">SATURDAY</button>
</div>
<div class="cols">
<button id="btnDiv6" class="day-button class1">SUNDAY</button>
</div>
<div class="cols">
<button id="hey" class="all-button class1">DAILY</button>
</div>
</div>
You could do something like this:
<style>
.class1 {
color: red;
}
.class2 {
color: green;
}
</style>
<div>
<button class="class1" onclick="changeClass(event)">Click me</button>
<button class="class1" onclick="changeClass(event)">Click me</button>
</div>
<script>
function changeClass(e) {
if (e.target.className.trim() === 'class1') {
e.target.className = 'class2';
} else {
e.target.className = 'class1';
}
}
</script>
Working example: https://jsfiddle.net/g12ua8d1/

Jquery will not select button after class has been toggled

I have some jquery that will, when a button is clicked, switch a class from a button to a different class (i.e. on click switch class from #testButton from .first to .second with an image toggle to show it works). The first click works well and it toggles the image, but the second click does not do anything. It seems as if it is not recognizing the new class. Here is a fiddle.
https://jsfiddle.net/myfb44yu/
This is the problematic javascript.
$(document).ready(function(){
$('.first').click(function(){
alert('works');
$('#testButton').toggleClass('first', 'second');
});
$('.second').click(function(){
alert("works");
$('#testButton').toggleClass('second', 'first');
});
});
The interesting thing is that it works when I use an alert() to check but not when I try to change an img src.
Your main issue here is a syntax error in regards to your .toggleClass, but seeing as others have addressed that, I'd like to point out that you should consider re-thinking how you apply your listeners - just as good habit moving forward.
An overview of jQuery Event Bindings
Think of the elements on your page as items in a store. You're an employee, and your manager says "Go put a red tag on anything in the toys department", and so you do. The next day, he puts 10 new toys in the toy department, and says to you "Why don't all the toys have red tags on them?" He then moves one of the toys to the clothing section and asks you, "Why does this item have a red tag on it?" It's simple. You put the red tags on anything in the toys department when he told you to do it - things got moved around afterwards.
The toys in this example would be your .first and .second elements.
This is how jQuery event bindings work - they only apply to elements that satisfied the selector at the time the event was initialized.
So, if you do $('.myClass').click();, then put .myClass on five buttons - none of those buttons will call this function, as they didn't have listeners put on them.
Similarly, if you put a listener on an element using class, but then remove the class from that element, it will maintain the bound event.
The Solution
$(document).on("click", ".first", function() { } );
This is known as event delegation.
In continuing with my analogy from before, this would be the equivalent of skipping tagging the items altogether, and instead just deciding whether or not they're a toy when the customer brings them to the cash register.
Instead of putting the listener on specific elements, we've put it on the entire page. By using ".first" as the second parameter (which takes a selector), the function will only be executed if the element has class first.
Hope this helps.
EDIT: As I was typing, JHecht left a good answer that points out the same issue I outlined above.
N number of elements can have the same class name ,so that's the reason if your trying to search it as $('.classname') returns an array ,so that's the reason your code is not working.class selector
Id is unique,each element should have a single id . In your code button has two id's and for the same button your trying to toggle first and second,you need not have two separate events for first and second
instead you can write as following
check this snippet
$(document).ready(function() {
var firstElements = $('.first')
var first = firstElements[0];
var secondElements = $('.second');
var second = secondElements[0]
$("#testButton").click(function() {
alert('works');
$(this).toggleClass('first').toggleClass('second');
});
});
.first {
color: red;
}
.second {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="img/images.jpeg" alt="" id="testImage">
<div id="testDiv">
<button type="button" id='testButton' class='first'>Hi</button>
</div>
Hope it helps
Ho about this solution. Hope it helps!
$(document).ready(function(){
$("#testButton").click(function(){
if($(this).prop("class") === "first"){
alert('first');
$(this).removeClass("first").addClass("second");
}
else if($(this).prop("class") === "second"){
alert("second");
$(this).removeClass("second").addClass("first");
}
});
});
.first{
color: red;
}
.second{
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<img src="img/images.jpeg" alt="" id="testImage">
<div id="testDiv">
<button type="button" id='testButton' class='first'>Hi</button>
</div>
I hope that what I am about to say makes more sense than I feel it does.
Your issue is that when you assign the click events, there is not currently an element that has a class of .second.
Also, your code is wrong. toggleClass accepts a few arguments, the first is a string of classes, the second is an optional parameter to check whether or not to toggle the classes on or off.
A way to accomplish what you want without changing a whole lot of code is event delegation, shown below.
$(function() {
$(document).on('click', '.btn-first,.btn-second', function() {
//here we are adding the click event on the document object, and telling it that we only want to delegate this event to an object that matches the classes of .btn-first or .btn-second.
//Note: to those saying "why not just do it on the .btn class an avoid having to do this", it is so he can see what delegation looks like. But you are correct, with this markup it would be better to simply add the click event on the .btn class.
$(this).toggleClass('btn-first btn-second');
});
});
.btn {
padding: 4px 8px;
border-radius: 3px;
border: 1px solid grey;
}
.btn-first {
background-color: green;
border-color: green;
}
.btn-second {
background-color: orange;
border-color: orange
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="img/images.jpeg" alt="" id="testImage">
<div id="testDiv">
<button type="button" id='testButton' class='btn btn-first'>Hi</button>
</div>
A combination of javascript, CSS and HTML to toggle the class of #testButton when any element of class "first" or "second" is clicked, including the test button itself. The posted code was changed to supply JQuery's .toggleClass method with a space separated list of class names. Click "run snippet" to test the effect.
$(document).ready(function(){
$('.first').click(function(){
$('#testButton').toggleClass('first second');
});
$('.second').click(function(){
$('#testButton').toggleClass('first second');
});
});
.first { border: thick outset green;}
.second { border: thick inset red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="first">This paragraph has first class</p>
<p class="second">This paragraph has second class</p>
<button type="button" id="testButton" class="first">this button starts out first class</div>
The script can then be simplified by combining multiple class names in a single selector, leaving just:
$(document).ready(function(){
$('.first, .second').click(function(){
$('#testButton').toggleClass('first second');
});
});
Make a neutral class that the buttons both share (.btn).
Then add one of the state classes to each button (.first or .second).
Delegate the click event to the neutral class only ($('.btn').on('click',...).
Then toggle both state classes on this ($(this).toggleClass('first second');)
The images change by CSS, each button has 2 images which alternate between display:none/block according to the button's state class.
There is an example with the images outside of buttons and another example that doesn't toggle classes around.
SNIPPET
$('.btn').on('click', function() {
$(this).toggleClass('first second');
});
/* OR */
$('.alt').on('click', function() {
$('.img').toggle();
});
.first > .one {
display: block;
}
.first > .two {
display: none;
}
.second > .one {
display: none;
}
.second > .two {
display: block;
}
.first + .one {
display: block;
}
.first + .one + .two {
display: none;
}
.second + .one {
display: none;
}
.second + .one + .two {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Use jQuery with CSS</p>
<button class='btn first'>
<img src='http://placehold.it/50x50/000/fff?text=1' class='one'>
<img src='http://placehold.it/50x50/fff/000?text=2' class='two'>
</button>
<button class='btn second'>
<img src='http://placehold.it/50x50/0e0/960?text=1' class='one'>
<img src='http://placehold.it/50x50/fff/000?text=2' class='two'>
</button>
<br/>
<br/>
<button class='btn first'>Toggle</button>
<img src='http://placehold.it/50x50/fc0/00f?text=1' class='one'>
<img src='http://placehold.it/50x50/00f/fc0?text=2' class='two'>
<button class='btn second'>Toggle</button>
<img src='http://placehold.it/50x50/fc0/00f?text=1' class='one'>
<img src='http://placehold.it/50x50/00f/fc0?text=2' class='two'>
<p>Or use only jQuery no CSS</p>
<img src='http://placehold.it/50x50/0e0/930?text=1' class='img'>
<img src='http://placehold.it/50x50/930/0e0?text=2' class='img' style='display:none'>
<button class='alt' style='display:block;'>Toggle</button>

Categories