Is this jQuery line of a tutorial necessary? - javascript

I'm working with the German book (mediated title) "jQuery the practice book".
In one of the first tutorials the given JS code is like this:
$(document).ready(function()
{
$("#box p").click
(
function()
{
$("#box p").removeClass("green");
$(this)
.addClass("green")
.parent()
.removeClass()
.addClass("boxColor-" + $("#box p").index(this));
}
);
});
the CSS is like this:
<style type ="text/css">
p {
cursor:pointer;
}
.green{
color:#009933;
background-color:#E2FFEC;
cursor:default;
}
</style>
and the HTML is this:
<body>
<div id="box">
<p>Erster Absatz</p>
<p>Zweiter Absatz</p>
<p>Dritter Absatz</p>
</div>
</body>
What makes me stuck is this line of the jQuery script:
.addClass("boxColor-" + $("#box p").index(this));
The Tutorial of the book explains this with a reason like "On which way else we could get the p box related Class?"
But I don't get the point what is happening in that line?
And even if I remove this line, the result I'm seeing keeps being the same.
so, what does happen here? and is it really necessary in any way?

That line is adding a boxColor-N class to the #box element, where N is the index of the <p> you just clicked.
Since there is nothing in the CSS that targets such a class and also no script code that works with it, there are no observable effects.

This line adds a class name. The value that is added is a concatenation of the string boxColor- and the index of the relevant paragraph element.
The index of the element is extracted by using the jQuery index() function.
Regarding your question if it is needed at all really depends on what that class name does. All it's really doing here is adding a class name. If that class name has any other uses such as changing CSS properties then yes, it is needed. In your example, there is no CSS rule for that value - so nothing really changes or happens.
To see this actual doing something, you can add a CSS rule like this:
boxColor-0 {
background:red;
}
boxColor-1 {
background:green;
}
boxColor-2 {
background:blue;
}
With these rules, when you click on a <p> element, it's background color will change.

I don't know if it was an error but as the other explained this will add a class something like "boxColor-" + the index of the element.
But the code
$("#box p").removeClass("green");
$(this)
.addClass("green")
.parent()
.removeClass();
has a closing ; on .removeClass();
In jQuery the Chaining is used to call multiple functions on an element selected but because you are ending the chaining with this line. Otherwise you will add the class to the parent of the <p> tag
.removeClass();
You're not applying the addClass to any object try removing the ; and then use something like
$("#box p").removeClass("green");
$(this)
.addClass("green")
.parent()
.removeClass()
.addClass("boxColor-" + $("#box p").index(this));
Here is an example of how it should work.
JSFiddle

Related

Jquery put elements in div

You need to put items in a div - <div style = 'flex-direction: column;'>.
Div needs to be created after p withid = "billing_city_field"
and closes after the p withid = "apartment_field".
Tried to do it with this function:
jQuery (document) .ready (function ($) {
$ ("# billing_city_field"). after ("<div style = 'flex-direction: column;'>");
$ ("# apartment_field"). after ("</ div");
});
But the div immediately closes. What should I do?
The issue is because you cannot append start/end tags separately. The DOM works with elements as a whole, so you need to create the entire div element in a single operation.
Given the description of your goal it looks like you're trying to wrap the existing content in a new div. As such you can use nextUntil() (assuming the target elements are siblings) and then wrapAll(). Try this:
jQuery($ => {
let $contents = $("#billing_city_field").nextUntil('#apartment_field').add('#apartment_field');
$contents.wrapAll('<div class="column" />');
});
Note the use of a class attribute in the above example, instead of applying inline style rules.
Question is not super clear but from what I can tell.
I think you have small misunderstanding what .after does with jQuery. After in this case is "structural" and not "time" related. If you check jQuery docs (https://api.jquery.com/after/) for this you can see basically what you need to do.
Simplest way to do this, if these things needs to created and don't exist already on body for example.
$(function(){
var p = $("<p id='apartment_field'>Paragraph test</p>");
$("body").append("<div id='billing_city_field' style='flex-direction: column;'></div>");
$("#billing_city_field").html(p);
});
I've added Paragraph test so result is visible easier.
And one more thing, not sure if it's error with copy/paste but make sure that # and id don't have space in-between like this.
$("#billing_city_field")
$("#apartment_field")
Edit: Looking at the comments maybe something like this, if they exist already? You should clarify the question more.
$("#billing_city_field").append($("#apartment_field").detach());

Using html text as selector for CSS with JS?

I'm sure others have asked this but I just cant' find anything that helps me.
Have a look at this code on jsfiddle.
Both Person1 and Person2 have
class="from"
And the CSS selector is .from so it applies to both but I'm trying to achieve that it only applies to Person1 with JavaScript/jQuery.
I've tried numerous things such as
$( "span.from:contains('Person1')" )
with no success. How should I do this?
Help would be much appreciated :)
In your case you can use filter()
$("span.from").filter(function(){ return this.innerHTML == "Person1"; })
to remove the animation of the item remove the from class using removeClass()
$("span.from").filter(function(){
return this.innerHTML == "Person1";
}).removeClass('from');
$( "span.from:contains('Person1')") works just fine. But in css you are still affecting all elements with .from class. After you get the element with Javascript, you should do something with it, like add a new class, and change the css so that the animation runs only on the new class.
$( "span.from:contains('Person1')").addClass('newClass')
CSS:
.newClass{
-webkit-animation: color-change 1s infinite;
...
}
Your code can work
$("span.from:contains('Person1')").text()
See this fiddle
If you are using straight up CSS you should be able to select just the first item using the nth-child selector:
.from:nth-of-type(1) { /* styles here */ }
If you wanted to select the first item via JS you would simply need to use eq() to grab the first item by index. This is chainable, so you could continue to set set CSS on this item similar to this (so in this example I'm adding an extra class on the first .from, and also setting its background color):
$(".from").eq(0).addClass("first-item").css("backgroundColor", "orange");
You can try with .not()
$(".from:not(span:contains('Person2')):eq(0)")

Javascript/jQuery .each and syntax issue

I'm having some trouble writing a function to change a background image on a div on document.ready
I haven't made a jsfiddle as i think the problem is just my poor (but improving) jQuery skills. Please let me know if you think one is needed.
Background Info ->
I have a collection of div's with a class of portlet-visible or portlet-hidden, each of these div's will have another class of red-arrow (or a different color, but once i have one color it should be easy to extrapolate). When the page loads i would like a function that can find all divs with a class of portlet-hidden or portlet-visible and see if those have a class of red-arrow. If they do then change the background image src to a different value.
Im really struggling to work this one out, and any help is much appreciated.
My HTML
<div class="portlet-visible red-arrow"></div>
My CSS
div.portlet-visible
{
position:absolute;
top:12px;
right:10px;
background-image:url(../images/red-arrow-up.png);
width:14px;
height:14px;
}
And finally my javascript
$(document).ready(function() {
$(".portlet-hidden" && ".portlet-visible").each(function() {
if ($("this").hasClass(".red-arrow")) {
$(this).css(background-image, url('"url(../images/blue-arrow-up.png)"')
};
});
});
Multiple selectors should be separated by a comma(,) and also css method takes a string or a map. Try this.
$(document).ready(function() {
$(".portlet-hidden, .portlet-visible").each(function() {
if ($(this).hasClass("red-arrow")) {
$(this).css('background-image', "url('../images/blue-arrow-up.png')")
};
});
});
I would have written the selector this way
$(".portlet-hidden, .portlet-visible")
Unless there's a specific reason you want to do this with jQuery you should just use CSS...
div.portlet-visible
{
background-image:url(../images/red-arrow-up.png);
width:14px;
height:14px;
}
div.portlet-visible.red-arrow
{
background-image:url(../images/blue-arrow-up.png);
}
Any div with the class "portlet-visible" is defined in the first block, and any div with the classes "portlet-visible" and "red-arrow" will use the same css, but also apply the new background image.
http://jsfiddle.net/johncmolyneux/gcm5b/
First... Archer's answer is spot on-- what you're trying to do with jQuery can be done with CSS alone.
But if for some reason you do need jQuery, a few things are wrong here.
First, as justtkt said in his answer, your selector is wrong. There is no need (and is syntactically wrong) to use conditional operators like && or || in a jQuery selector. This is simply because there is already conditional syntax built in to CSS, upon which jQuery selectors are directly based.
.this-class.that-class
Selects all elements with both .this-class, and .that-class.
#this-id.that-class
Is a very (possibly overly) specific declaration that select an element (there should only be one ID per page) with both #this-id and .that-class
For more on selectors, please read this very thorough, complete, and educational link http://www.w3.org/TR/selectors/
Additionally and importantly
This line:
$("this").hasClass(".red-arrow")
Is wrong! hasClass does not require a selector (the ".") because it only takes a class. It should be
$("this").hasClass("red-arrow")
Also!!
$(this).css(background-image, url('"url(../images/blue-arrow-up.png)"')
This line has some errors... should be:
$(this).css("background-image", "url(../images/blue-arrow-up.png)")
although I think the following syntax is easier:
css({'background-image' : 'url(../images/blue-arrow-up.png)'})
Your selector is just incorrect. If you want to match things with both classes, it'd be:
$('.portlet-hidden.portlet-visible').each( ...
If you want to match either of the classes:
$('.portlet-hidden, .portlet-visible').each( ...
The expression ".portlet-hidden" && ".portlet-visible" will always evaluate to just ".portlet-visible".
Instead of && two selectors together, use the multiple selector like $(".portlet-hidden, .portlet-visible") or the .add() method to build up your jQuery.
Your current line is actually anding the two strings together, which I believe will return boolean true in Javascript.
if ('$("this").hasClass(".red-arrow")') { <--- this condition is a string here
Should be:
if ($(this).hasClass(".red-arrow")) {
change in selector ".portlet-hidden,.portlet-visible"
change if condition to boolean from string
change in css.
$(".portlet-hidden,.portlet-visible").each(function(){
if ($("this").hasClass("red-arrow")){
$(this).css("background-image", "url('../images/blue-arrow-up.png')");
}
});

How to change a css class style through Javascript?

According to the book I am reading it is better to change CSS by class when you are using Javascript. But how? Can someone give a sample snippet for this?
Suppose you have:
<div id="mydiv" class="oldclass">text</div>
and the following styles:
.oldclass { color: blue }
.newclass { background-color: yellow }
You can change the class on mydiv in javascript like this:
document.getElementById('mydiv').className = 'newclass';
After the DOM manipulation you will be left with:
<div id="mydiv" class="newclass">text</div>
If you want to add a new css class without removing the old one, you can append to it:
document.getElementById('mydiv').className += ' newClass';
This will result in:
<div id="mydiv" class="oldclass newclass">text</div>
Since classList is supported in all major browsers and jQuery drops support for IE<9 (in 2.x branch as Stormblack points in the comment), considering this HTML
<div id="mydiv" class="oldclass">text</div>
you can comfortably use this syntax:
document.getElementById('mydiv').classList.add("newClass");
This will also result in:
<div id="mydiv" class="oldclass newclass">text</div>
plus you can also use remove, toggle, contains methods.
If you want to manipulate the actual CSS class instead of modifying the DOM elements or using modifier CSS classes, see
https://stackoverflow.com/a/50036923/482916.
I'd highly recommend jQuery. It then becomes as simple as:
$('#mydiv').addClass('newclass');
You don't have to worry about removing the old class then as addClass() will only append to it. You also have removeClass();
The other advantage over the getElementById() method is you can apply it to multiple elements at the same time with a single line of code.
$('div').addClass('newclass');
$('.oldclass').addClass('newclass');
The first example will add the class to all DIV elements on the page. The second example will add the new class to all elements that currently have the old class.
use the className property:
document.getElementById('your_element_s_id').className = 'cssClass';
There are two ways in which this can be accomplished using vanilla javascript. The first is className and the second is classList. className works in all browsers but can be unwieldy to work with when modifying an element's class attribute. classList is an easier way to modify an element's class(es).
To outright set an element's class attribute, className is the way to go, otherwise to modify an element's class(es), it's easier to use classList.
Initial Html
<div id="ID"></div>
Setting the class attribute
var div = document.getElementById('ID');
div.className = "foo bar car";
Result:
<div id="ID" class="foo bar car"></div>
Adding a class
div.classList.add("car");// Class already exists, nothing happens
div.classList.add("tar");
Note: There's no need to test if a class exists before adding it. If a class needs to be added, just add it. If it already exists, a duplicate won't be added.
Result:
<div id="ID" class="foo bar car tar"></div>
Removing a class
div.classList.remove("car");
div.classList.remove("tar");
div.classList.remove("car");// No class of this name exists, nothing happens
Note: Just like add, if a class needs to be removed, remove it. If it's there, it'll be removed, otherwise nothing will happen.
Result:
<div id="ID" class="foo bar"></div>
Checking if a class attribute contains a specific class
if (div.classList.contains("foo")) {
// Do stuff
}
Toggling a class
var classWasAdded = div.classList.toggle("bar"); // "bar" gets removed
// classWasAdded is false since "bar" was removed
classWasAdded = div.classList.toggle("bar"); // "bar" gets added
// classWasAdded is true since "bar" was added
.toggle has a second boolean parameter that, in my opinion, is redundant and isn't worth going over.
For more information on classList, check out MDN. It also covers browser compatibility if that's a concern, which can be addressed by using Modernizr for detection and a polyfill if needed.
document.getElementById("my").className = 'myclass';
You may also be interested in modifying it using jQuery:
http://api.jquery.com/category/css/
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("div").addClass(function(){
return "par" ;
});
});
</script>
<style>
.par {
color: blue;
}
</style>
</head>
<body>
<div class="test">This is a paragraph.</div>
</body>
</html>

Select all elements that have a specific CSS, using jQuery

How can I select all elements that have a specific CSS property applied, using jQuery? For example:
.Title
{
color:red;
rounded:true;
}
.Caption
{
color:black;
rounded:true;
}
How to select by property named "rounded"?
CSS class name is very flexible.
$(".Title").corner();
$(".Caption").corner();
How to replace this two operation to one operation. Maybe something like this:
$(".*->rounded").corner();
Is there any better way to do this?
This is a two year old thread, but it was still useful to me so it could be useful to others, perhaps. Here's what I ended up doing:
var x = $('.myselector').filter(function () {
return this.style.some_prop == 'whatever'
});
not as succinct as I would like, but I have never needed something like this except now, and it's not very efficient for general use anyway, as I see it.
Thank you, Bijou. I used your solution, but used the jQuery .css instead of pure javascript, like this:
var x = $('*').filter(function() {
return $(this).css('font-family').toLowerCase().indexOf('futura') > -1
})
This example would select all elements where the font-family attribute value contains "Futura".
You cannot (using a CSS selector) select elements based on the CSS properties that have been applied to them.
If you want to do this manually, you could select every element in the document, loop over them, and check the computed value of the property you are interested in (this would probably only work with real CSS properties though, not made up ones such as rounded). It would also would be slow.
Update in response to edits — group selectors:
$(".Title, .Caption").corner();
Similar as Bijou's. Just a little bit enhancement:
$('[class]').filter(function() {
return $(this).css('your css property') == 'the expected value';
}
).corner();
I think using $('[class]') is better:
no need to hard code the selector(s)
won't check all HTML elements one by one.
Here is an example.
Here is a clean, easy to understand solution:
// find elements with jQuery with a specific CSS, then execute an action
$('.dom-class').each(function(index, el) {
if ($(this).css('property') == 'value') {
$(this).doThingsHere();
}
});
This solution is different because it does not use corner, filter or return. It is intentionally made for a wider audience of users.
Things to replace:
Replace ".dom-class" with your selector.
Replace CSS property and value with what you are looking for.
Replace "doThingsHere()" with what you want to execute on that
found element.
Good luck!
Custom CSS properties aren't inherited, so must be applied directly to each element (even if you use js to dynamically add properties, you should do it by adding a class), so...
CSS
.Title
{
color:red;
}
.Caption
{
color:black;
}
HTML
You don't need to define a rounded:true property at all. Just use the presence of the 'Rounded' class:
<div class='Title Rounded'><h1>Title</h1></div>
<div class='Caption Rounded'>Caption</div>
JS
jQuery( '.Rounded' ).corner();

Categories

Resources