I have made a multiple choice quiz and when there is one on a single page it works exactly as I want it to. The issue is that I need to have multiple quizzes appear on one page and the behaviour on one quiz is affecting the behaviour of any other quizzes that appear on that same page
I've been looking online to see if there's a way for the function to handle each quiz ID separately (as if they each had their own separate function) but nothing I've found so far looks to be something I can apply to the function I already have.
Here's the Javascript
jQuery(document).ready(function(){
jQuery('.answer').click(function(event){
jQuery('.active').removeClass('active');
jQuery(this).addClass('active');
event.preventDefault();
});
});
Here's the HTML
<div id="Quiz1" class="quiz">
<div class="question">Is this a really good question?</div>
<div class="interaction">
<div class="answer" data-answer="correct">
<div class="answer-content">
<span>Answer 1</span>
</div>
</div>
<div class="answer" data-answer="wrong1">
<div class="answer-content">
<span>Answer 2</span>
</div>
</div>
<div class="answer" data-answer="wrong2">
<div class="answer-content">
<span>Answer 3</span>
</div>
</div>
<div class="response-text correct">Correct</div>
<div class="response-text wrong1">Wrong 1</div>
<div class="response-text wrong2">Wrong 2</div>
</div>
</div>
<div id="Quiz2" class="quiz">
<div class="question">Is this a really good question?</div>
<div class="interaction">
<div class="answer" data-answer="correct">
<div class="answer-content">
<span>Answer 1</span>
</div>
</div>
<div class="answer" data-answer="wrong1">
<div class="answer-content">
<span>Answer 2</span>
</div>
</div>
<div class="answer" data-answer="wrong2">
<div class="answer-content">
<span>Answer 3</span>
</div>
</div>
<div class="response-text correct">Correct</div>
<div class="response-text wrong1">Wrong 1</div>
<div class="response-text wrong2">Wrong 2</div>
</div>
</div>
Here's the CSS
.answer[data-answer="correct"] ~ .correct {
display:none;
}
.answer.active[data-answer="correct"] ~ .correct {
display:block
}
.answer[data-answer="wrong1"] ~ .wrong1 {
display:none;
}
.answer.active[data-answer="wrong1"] ~ .wrong1 {
display:block
}
.answer[data-answer="wrong2"] ~ .wrong2 {
display:none;
}
.answer.active[data-answer="wrong2"] ~ .wrong2 {
display:block
}
So, with one quiz on the page everything works as expected - Clicking each bubble will give the user a corresponding response: Correct, Wrong, Wrong2. As each bubble is clicked the css takes whichever .answer element has the .active class and displays the corresponding answer response based on the data-attribute given.
This is wonderful until I have more than one quiz on the page
When there are two quizzes on one page and you click the bubbles in the second quiz it will remove the last answer response from the quiz above it.
I need each quiz to act independently and not have one quiz affecting the others.
I hope this makes sense, I'm terrible at explaining myself.
I've set up a fiddle so you can see it in action - https://jsfiddle.net/g8qpvtcz/1/
If I understand you, you just want to be able to display more than one "response box"?
If so, this might do the job for you:
In your fiddle, change line 3 of the javascript:
jQuery('.active').removeClass('active');
to
jQuery(this).parent().children('.active').removeClass('active');
This gets the parent element of the clicked answer (i.e. the div.interaction) for the given quiz and only removes the active class in its children.
Edit
You could also just use the siblings() method. Which would be even prettier. Don't really know why I forgot about that one.
jQuery(this).siblings('.active').removeClass('active');
Related
I'm having trouble getting an image to show up that has been written within in a body. The specific image being the <img src="Images/Attachments/Shining.gif">
Not too sure if the script needs to be altered or if I would have to put it inside its own class. When I tried to append, the image showed up in both emails instead of the one I wrote it in. I'm coding this using Twine, Sugarcube btw!
<div class="header">
<div class="hamburgerWrapper">
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
<div class="EmailsWrapper">
<div class="ExtendMsg">
<p>Extended Messages will be placed under here.</p>
</div>
</div>
<div class="Email">
<div class="ImgWrapper">
<img src="Images/Phone Icons/User.png>
</div>
<div class=" EmailTitle">
<p class="EmailTime">9:31 PM</p>
<h1>Sender</h1>
<h2>Subject Title</h2>
<p class="EmailPreview">Email content to be filled out here.</p>
</div>
</div>
<div class="Email">
<div class="ImgWrapper">
<img src="Images/Phone Icons/User2.png">
</div>
<div class="EmailTitle">
<p class="EmailTime">9:29 PM</p>
<h1>Sender2</h1>
<h2>Subject Title</h2>
<p class="EmailPreview">Here is a gif for your memeing pleasure. <img src="Images/Attachments/Shining.gif"></p>
</div>
</div>
<<done>>
<<script>>
$(".Email").on("click", function() {
$(this).addClass("active");
$(".Email").not(".active").addClass("deactive");
$(".ExtendMsg").addClass("active");
$(".ExtendMsg").html($('
<div />').html($(".EmailPreview", this).text()));
$(".headerLabel h1").text("MESSAGES");
});
$(".hamburgerWrapper").on("click", function() {
$(".Email.active").removeClass("active");
$(".Email.deactive").removeClass("deactive");
$(".ExtendMsg").removeClass("active");
$(".headerLabel h1").text("MESSAGES");
});
<</script>>
<</done>>
I'm not totally sure what you are trying to achieve.
But I'd guess that you want to show and image, when ever you click something above?
If that is so, the classes are not met to handled that kind of jobs in Javascript. You might do so, if you assign the image to a Class property background-image: url("heregoesyourimages.png") but there are better ways to handle that kind of behavior.
If you have to use JQuery, you can use simply the method: "Show" or "Hide" that will display in and out an element:
First assign an identifier to your element to toggle (class or id):
<div class="ImgWrapper">
<img class="User2Image" src="Images/Phone Icons/User2.png">
</div>
Then, use the method $(".User2Image").Hide(); to make the image appear or disappear (what this do actually is that adds the property Display:none, to the element (correct me if I'm wrong its been a while since I used JQuery) or $(".User2Image").Show(); to show again the image.
I am having trouble with a little site I have been working on; I want a sort of "stream" container that holds "cards" of "content," where this "content" is some "text" as well as some "stats."
This is the HTML I currently have:
<div id="stream">
<div class="card">
<div class="content">content
<div class="text">
blahblahblah
</div>
<div class="stats">
blahblahblah
</div>
</div>
</div>
<div class="card">
<div class="content">content
<div class="text">
blahblahblah
</div>
<div class="stats">
blahblahblah
</div>
</div>
</div>
<div class="card">
<div class="content">content
<div class="text">
blahblahblah
</div>
<div class="stats">
blahblahblah
</div>
</div>
</div>
</div>
Eventually, I want users to be able to prepend "cards" to this "stream" as well.
Now, however, I am trying to implement some jQuery function to hide the "stats" of a card until it is clicked on. So after setting display to none in CSS of the stats, I made this in a javascript file:
$(document).ready(function(){
$("#stream, div.card").click(function() {
$(this).find($("div.stats")).show();
});
});
It sort of works; the stats of a card are hidden until I click on a card. When I click on a card, however, all the cards' stats divs are shown.
I was hoping to somehow make it that the specific card clicked is also the (only) one that gets shown. Obviously, the current way I am doing this opens all of them as jQuery I have selects all the cards at once; how can I remedy this?
Again, I apologize if this question has been asked; I could not seem to find something similar, and I really want this to work . . .
P.S. I tried to search for this particular instance; alot of suggestions were to just give divs ids, but this feels inconvenient when I eventually want users to prepend cards?
Your selector ->
"#stream, div.card"
was basically asking for all #stream and all div.card..
But what you really meant was, find all div.card inside #stream. and this would be, (aka without the ,).
"#stream div.card"
Also you jquery find doesn't require you to convert into a jquery object, so find("div.stats") will do the trick.
I have a scenario somewhat like this,
<div>
<div class="check">
<p class="user-name">
<a href=url>name</a>
</p>
<i class="user-icon"></i>
<div class="activity">
<p class="status">Status</p>
<p class="stream">Stream</p>
</div>
</div>
<div class="check">
<p class="user-name">
<a href=url>name</a>
</p>
<i class="user-icon"></i>
<div class="activity">
<p class="status">Status</p>
<p class="stream">Stream</p>
</div>
</div>
</div>
and, I'm to .slideToggle() the div with classname activity of that particular div whenever user clicks upon any element inside div with classname check.
I've came up with this one,
$(document).ready(function(){
$(".check").click(function(){
$(".activity").slideToggle();
});
});
And, as it's seen, its should not work, as it acts upon all the divs with classname activity.
And I can't change the classnames into ids, as these are auto populated through another function, and easier for styling through css and maintenance.
I want it to act upon only that div on which user will click.
How can I do so?
Thanks :)
Just select it properly, and make sure you use .activity instead of .user-activity (which doesn't exist):
$(".activity", this).slideToggle();
or
$(this).find(".activity").slideToggle();
See it in action here:
$(document).ready(function(){
$(".check").click(function(){
$(".activity", this).slideToggle();
});
});
.check .activity {display: none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="check">
<p class="user-name">
<a>name</a>
</p>
<i class="user-icon"></i>
<div class="activity">
<p class="status">Status</p>
<p class="stream">Stream</p>
</div>
</div>
<div class="check">
<p class="user-name">
<a>name</a>
</p>
<i class="user-icon"></i>
<div class="activity">
<p class="status">Status</p>
<p class="stream">Stream</p>
</div>
</div>
</div>
The event handler will be called in the context of the element upon which it was fired, so just use this to access it.
You can combine that with jQuery's find method to look for the associated descendant element.
You can use find selector to find activity element in currently clicked div:
$(".check").click(function(){
$(this).find('.activity').slideToggle();
});
You may also use this Demo:
$(document).ready(function(){
$(".check").click(function(){
$(this).children('.activity').slideToggle();
//OR you may also use $(this).find('.activity').slideToggle();
});
});
I am writing a script to show/hide a section within a div. I have 3 of these divs with hidden sections but was hoping to use one function to control all 3.
Here's what I have right now:
$('.rates, .hours, .otherinfo').click(function() {
$('.expand').toggle();
});
Here's the HTML:
<div class="rates">
<h2>Rates</h2>
<div class="expand">
<p>Text in here is hidden by default.</p>
</div>
</div>
<div class="hours">
<h2>Hours</h2>
<div class="expand">
<p>Text in here is hidden by default.</p>
</div>
</div>
<div class="otherinfo">
<h2>Other Info</h2>
<div class="expand">
<p>Text in here is hidden by default.</p>
</div>
</div>
And CSS:
.expand {
display:none;
}
Obviously, this shows the "expand" div for all 3 of the divs when you click on any of them. Is there a way to incorporate this into the selector. Something like this'.expand'?
Thanks!
$(this).find('.expand').toggle()
You should add a fiddle for better answer. But something like this should work.
$("#something").click(function(){$(this).children("section").toggle();});
Which one is the better way for performance to set a hover event on a div with class 'con'?
Is there any difference?
$('.con').hover(func(){});
$('.content0.content.%etc%.con').hover(func(){});
var con = $('.con'); con.hover(func(){});
<script>
$('.con').hover(func(){});
</script>
<div class="content0">
<div class="content">
<div class="fl grad">
<div class="fl bor_rad bor_gray adver1">
<div class="clear">
<div class="fl left_ot">
<div class="bor_orang h150">
<div class="w130 bgfff txc pab10 con">
More
</div>
<div class="w130 bgfff txc pab10 con">
More
</div>
<div class="w130 bgfff txc pab10 con">
More
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
There's no significant difference between the three ways you listed, provided the two different selectors you've given select the same elements.
Note that the element lookup is done once, when you do the $("selector here") part. It's not repeated when the hover occurs.
Side note: Probably 95% of what I've seen people do in hover event handlers can, on modern browsers (e.g., not IE7 and earlier), be better achieved with CSS using the :hover pseudoclass. The other 5% can't, and you haven't said what you're doing and it may well be in that 5%, but I thought I'd point it out... :-)
1. $('.con').hover(func(){});
2. $('.content0.content.%etc%.con').hover(func(){}); var con =
3. $('.con'); con.hover(func(){});
all three work but they take time
because every time jQuery search in all document(DOM) then come to your selector
so use context by this we tell in jQuery that search not in all document but search form this element like below..
in your html
<div class="content0">
<div class="content">
<div class="fl grad">
<div class="fl bor_rad bor_gray adver1">
<div class="clear">
<div class="fl left_ot">
<div class="bor_orang h150">
<div class="w130 bgfff txc pab10 con">
More
</div>
<div class="w130 bgfff txc pab10 con">
More
</div>
<div class="w130 bgfff txc pab10 con">
More
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
now if you write
$('.con').hover(func(){});
then it reach your selector by following way
first go to
document
|
body
|
content0(class)
|
content (class)
|....
...
then at last your selector '.con'
so it will take time
to get better result define context by this it know from where it search your selector like
$('.con','.content0').hover(func(){});
now it reach your selector by following way
first go to
content0(class)
....
...
then at last your selector '.con'
Context really helps when you have a much larger DOM that you are searching through. Searching for IDs is already very fast and context doesn't really help that much in that case. Where context can really make a difference is when you are selecting by tag name or class.
Try testing like this: http://jsbin.com/aciji4/4
you can really see the timing get better for context when you bump up number of items in the DOM like this: http://jsbin.com/aciji4/6
reference Performance of jQuery selector with context