can't understand this jquery code - javascript

I am new to web development and am referring following link-
tic tac toe javascript
Please find below js, css and html file respectively.
We are not having any element with class="selected" but still project is running perfectly
$(".level").each(function() {
var $this = $(this);
$this.click(function() {
$('.selected').toggleClass('not-selected');
$('.selected').toggleClass('selected');
$this.toggleClass('not-selected');
$this.toggleClass('selected');
ai.level = $this.attr("id");
});
});
.level {
margin: 0 15px;
color: lightskyblue;
cursor: pointer;
}
.not-selected {
opacity: 0.5;
text-decoration:none;
}
.not-selected:hover {
opacity:1;
}
<div class='difficulty'>
<span class='level not-selected' id="blind">Blind</span>
<span class='level not-selected' id="novice">Novice</span>
<span class='level not-selected' id="master">Master!</span>
</div>
I am unable to understand this js.
Please clear my two doubts- 1.use of click inside each 2.how .selected work in jquery
The snippet won't work cause i didn't add jquery to it.

Toggle behavior - if the element has a class, the class will be removed. If the element hasn't got the class, the class will be added. In this case there are no elements with .select class, but it will be added after toggleClass('selected') executes. I commented every js line for you.
$(".level").each(function() { // for each element with class .level
var $this = $(this); // save the current jQuery object in the loop in the $this variable
$this.click(function() { // add a click event to the current object
$('.selected').toggleClass('not-selected'); // for the elements with .selectd class toggle .not-selectd class
$('.selected').toggleClass('selected'); // for the elements with .selectd class toggle .selectd class
$this.toggleClass('not-selected'); // for the current elements toggle .not-selectd class
$this.toggleClass('selected'); // for the current elements toggle .selectd class
ai.level = $this.attr("id"); // ai not defined in current context, will give an error, but if was defined you would save current element id in ai.level
});
});
This code could be written much easier and do the same. You don't need .selected class since there is no style for it in css
$(".level").click(function(){ // click event for elements with class .level
$(".level").addClass("not-selected"); // add .not-selected class to all .level elements
$(this).removeClass("not-selected"); // remove not-selected class from the CURRENT clicked element
});
.level {
margin: 0 15px;
color: lightskyblue;
cursor: pointer;
}
.not-selected {
opacity: 0.5;
text-decoration:none;
}
.not-selected:hover {
opacity:1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='difficulty'>
<span class='level not-selected' id="blind">Blind</span>
<span class='level not-selected' id="novice">Novice</span>
<span class='level not-selected' id="master">Master!</span>
</div>
Edit duo comments:
1.use of click inside each
In your case you are getting objects $(".level") and iterating through them. Inside the loop you are assigning to the current element a click event listener. this is unneeded you can just do $('.level').click(function(){}); with out iterating.
how .selected work in jquery
This is just a HTML class with no special behavior. You can just manage elements by it class. You can use any class you want like .my-super-class-name and use it. It's just a HTML attribute.

Related

How can I add a CSS class to the button that is clicked among multiple buttons using jQuery?

My motive is when someone will click on a particular button then will show the particular cards and will add a class named category_btn_active that clicked. Suppose Services will be clicked then the service cards will be shown. Here the filtering is working well, the problem is here $(this).addClass('category_btn_active').siblings().removeClass('category_btn_active'). The category_btn_active class adds when clicked but when I clicked another button it stays in both buttons. I want the class will be added to just the last clicked button. Where is the problem? give a relevant solution...
index.html:
<li>Services</li>
<li>Static Website</li>
<div class="Services service_itembox">
<img src="Assets/pic-1.jpg" alt="service image">
</div>
<div class="Static service_itembox">
<img src="Assets/pic-2.jpg" alt="service image">
</div>
index.js:
$(function () {
$(".category_btn").click(function () {
$(this).addClass('category_btn_active').siblings().removeClass('category_btn_active')
const value = $(this).attr('data-filter');
if(value == "Services"){
$('.service_itembox').show('slow');
}else{
$('.service_itembox').not('.'+value).hide('slow');
$('.service_itembox').filter('.'+value).show('slow');
}
});
});
style.css:
.category_btn_active{
color: white;
border-color:gray;
border-style:solid ;
border-width:0px 0px 1px 0px;
background-color: #019587;
padding: 8px;
font-size: 14px;
text-transform: uppercase;
}
This is not the most elegant way to do this, but it illustrates use of parent() and sibling(), which you were struggling with:
https://jsfiddle.net/v5fg3qwh/2/
$(function () {
$(".category_btn").click(function () {
$(this).addClass('category_btn_active').parent().siblings().find("a.category_btn").removeClass('category_btn_active')
const value = $(this).attr('data-filter');
$(`.${value}.service_itembox`).show('slow');
$(`.service_itembox`).not('.'+value).hide('slow');
$(`.service_itembox`).filter('.'+value).show('slow');
});
});
Note that I removed your if/else because you don't need it. Your classes and JS logic are defined in such a way that you can specify your intent w/out those conditionals.
I also defaulted one of your images to be hidden at initialization, which I assume is what you'd want:
div.Static.service_itembox {
display: none;
}

I need to remove a class after adding it clicking on same checkbox, not the document

I'm clicking on a checkbox to add some animation to a div, but when I want this animation to disappear I can only make it happen through $(document) click. Checkbox must add and then remove the class.
JS
$('#inOrder').click(function(e) {
$('.border').addClass('colorsborder');
e.stopPropagation();
$(document).click(function(e) {
$('.border').removeClass('colorsborder');
});
});
$('#inOrder').click(function(e) {
e.stopPropagation();
});
HTML
<input id="inOrder" type="checkbox" />
You may call toggleClass() method on the jQuery object (element) that you want to add or remove the class from. The method toggleClass will either:
add the desired class when the element doesn't have it.
or remove that class when the element has it already.
Here's a basic, live demo to illustrate the functionality:
const checkbox = $('#inOrder'),
relatedDiv = $('#related');
checkbox.on('change', () => relatedDiv.toggleClass('custom'))
/** just for demo purpose */
#related {
margin: 15px 0;
padding: 10px;
border: 1px solid #ccc;
}
#related.custom {
border-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="inOrder" type="checkbox" />
<div id="related">My appearnace will change on checkbox click</div>
The above demo is pnly meant as a showcase of a possible solution that could be applied to your current problem and it WON'T do the exact thing you want to have unless you apply the required changes you need to suit your actual code/structuring.
Then you want to toggle the class not add it when you click on checkbox
$('#inOrder').click(function(e) {
$('.border').toggleClass('colorsborder');
....

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>

How to apply style to the correct tag with JQuery

I'm trying to add more logic to my code but it's not working. I have to wrap my icon around a span tag so I get the line height properly. I'm using google font:
html.erb
<!-- inside a loop -->
<span class="wish-flex cursor" data-id="wish">
<i class="material-icons cursor">favorite_border</i> Add Wishlist
</span>
<input type="hidden" class="wish-cls" value="<%= product.id %>" />
SCSS
...
span.wish-flex{
display: inline-flex;
vertical-align: middle;
padding-top: 10px
}
.material-icons.red { color: $hotRed; }
span .material-icons{
margin-top: -2px
}
JavaScript
$("[data-id=wish]").click(function(e){
e.preventDefault();
var value = $(this).next(".wish-cls").val();
console.log("Clicked: " + value);
/* Applying the css when clicked
*
* We use toggleClass instead of addClass
* TODO: Ajax
*/
$(this).toggleClass("red");
});
The code is applying the class red to the span. Correct but how to get it to apply the class to the i tag? If the user clicks the heart or the word (Add Wishlist), the script runs.
Maybe I could change up the css to get the inline style with the icon and the text and remove the span?
In your case the this inside of the event handler will point to the span element, But what you are trying to select is the i element inside of it. So you have to use either find() or children() to be invoked from $(this) to get it.
$("[data-id='wish']").click(function(e){
e.preventDefault();
var value = $(this).next(".wish-cls").val();
$("i", this).toggleClass("red");
});
This signature $("selector", elem) is similar to $(elem).find("selector").

How to change class named active into link's active attribute in javascript

I'm using superfish for menu.Since it doesn't come with active class to denote current page tab.I added the following javascript.
<script type="text/javascript">
var path = window.location.pathname.split('/');
path = path[path.length-1];
if (path !== undefined) {
$("ul.sf-menu")
.find("a[href$='" + path + "']") // gets all links that match the href
.parents('li') // gets all list items that are ancestors of the link
.children('a') // walks down one level from all selected li's
.addClass('active');
}
</script>
I also added a class named active in css as the script requires.
.sf-menu a.active{
margin-top:-5px;
height: 51px;
padding-top: 15px;
z-index: 100;
background-color:#072438;
}
It worked just fine.However for some reason I would like to change the css from
a.active into a:active
But how do I change this part in javascript to suit the css please?
.addClass('active');
You can't add a pseudo-class on an element using javascript in the same way that you can't add a pseudo-class in an inline style='' attribute.
What you can do is alter your stylesheet with javascript to add the rule you want:
document.styleSheets[0].insertRule('a:active { color: red; }', 0);

Categories