Basic jQuery: Can't get an appropriate result using 'this' - javascript

My goal is to make alert the user that whichever shape they click on will correspond with an appropriate message.
My problem at the moment is that I am using an if statement that if the user clicks on something with the background color of blue, it will alert them saying they clicked on a circle. Otherwise they have clicked on a square.
The results are that clicking on the blue circle will alert that we have clicked on a square.
$("div").click(function() {
if ($(this).css("background-color") == "blue") {
alert("This is a circle!");
} else {
alert("This is a square!");
}
});
#circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: blue;
margin: 10px;
}
.square {
width: 100px;
height: 100px;
background-color: green;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="circle"></div>
<div class="square"></div>
<div class="square"></div>

.css() returns an RGB value for background colors.
$("div").click(function() {
if ($(this).css("background-color") == "rgb(0, 0, 255)") {
alert("This is a circle!");
} else {
alert("This is a square!");
}
});
#circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: blue;
margin: 10px;
}
.square {
width: 100px;
height: 100px;
background-color: green;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="circle"></div>
<div class="square"></div>
<div class="square"></div>

You get response back as rgb values, not the actual English word.
$("div").click(function() {
if ($(this).css("background-color") == "rgb(0, 0, 255)") {
alert("This is a circle!");
} else {
alert("This is a square!");
}
});
#circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: blue;
margin: 10px;
}
.square {
width: 100px;
height: 100px;
background-color: green;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="circle"></div>
<div class="square"></div>
<div class="square"></div>

$("div").click(function() {
console.log($(this).css("background-color"));
if ($(this).css("background-color") == "rgb(0, 0, 255)") {
alert("This is a circle!");
} else {
alert("This is a square!");
}
});
#circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: blue;
margin: 10px;
}
.square {
width: 100px;
height: 100px;
background-color: green;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="circle"></div>
<div class="square"></div>
<div class="square"></div>

To make it even more extensible, you could use the class name as the thing you alert:
$("div").click(function() {
alert('This is a ' + $(this).prop('class'))
}

The CSS is assigned by the class not directly, the .css("background-color") will returns the rgb() value, It's better to check the class or the id attributes in your condition instead, check the sample below :
$("div").click(function() {
if ( $(this).hasClass("square") ) {
alert("This is a square!");
} else {
alert("This is a circle!");
}
});
Hope this helps.
$("div").click(function() {
if ( $(this).hasClass("square") ) {
alert("This is a square!");
} else {
alert("This is a circle!");
}
});
#circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: blue;
margin: 10px;
}
.square {
width: 100px;
height: 100px;
background-color: green;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="circle"></div>
<div class="square"></div>
<div class="square"></div>

# is not the same as . in CSS, nor their corresponding HTML properties. This is not a distinction that is here to make problems for you, it is one introduced intentionally with a purposeful design that you must reflect in your applications to benefit from.
# or the id attribute is only for user-defined identifiers that are unique within the document. The behavior of the document element's namespace dictionary allows one to address sub-document fragments with URIs. If you want generalities in presentation or behavior, id is not the attribute one should use in the document's markup. The level at which this anti-pattern emerges as an error is arbitrary, and your case is an example.
The class atrribute of an element is for user-defined identifiers that distinguish between elements of the same semantic meaning for the purpose of behavior or presentation. The unordered collection of class identifiers that pertain to an element is not bounded, in theory. Thus, when you are designing your application and have to distinguish between elements, there is a simple, linear process for deciding whether a user-defined identifer is necessary and/or which attributes are involved:
Is there an element or attribute other than id or class that semantically makes this distinction already? The HTML standard rigorously defines many tags and attributes, and by using them in a way that is consistent with the definitions, your application gains the benefits of all new related advances without duplication of work. If new advances break your work, you will know when this will happen in advance by keeping up with the standard.
Is there any possibility that the distinction will not be applicable in a given document or will be applicable to two or more elements? The id attribute is defined as one per document; if it is useful in the static document, it could be referenced in a URI, but it must respect that one-to-one mapping or it just is not an id. The shape of an element is thus appropriate if and only if the document relates some quality one-to-one with various shapes.
If the above 2 clauses are ruled out, the distinction belongs to the class or data attribute. If a distinction may have some representational correspondence that can be expressed in CSS, the class attribute is attractive. If, however, the distinction is more quantifiable, continuous, or abstract, it may be better expressed as a data attribute.
In your case, the distinctions are shape of element and user-clicked. Because shape of element is explicitly defined as not covered by HTML but deferred to CSS, a CSS construct is required to make that distinction. This means there are few paths in your design: style attribute, class attribute, or entirely CSS implementation. Since there is more logic involved than what CSS does and you are perhaps not wanting to define shapes in geometric terms, we can rule out style and pure CSS. The class attribute is where both shapes of element should be distinguished.
Because the HTML standard does define the DOM concept of user-clicked and you have no further complications in time, your application should make use of the onclick event directly or through jQuery or your other favorite API.
Part of the evil magic of $ is that learning it is much easier than learning the underlying parts, allowing you to succeed with incomplete understandings of the system up to a finite depth, then dumping you into the arms of stackoverflow.com when you first exceed that depth. You must read the actual standards now. Write up a working app without $ at all and the mistake will be glaring so brightly that it will be seared into your eyeballs forever. $ is for people who have written enough DOM-based code to know that there just has to be a simpler easier way. It should come as a relief when first used, not as a milder introduction to HTML app design. Once you reach this epiphany, you are ready to get back to $ and whatever else, but the DOM is not a black box or a class you can skip with footnotes.

Related

animate the removal and attaching of DOM elements

I want an interactive experience for my users.. AND I want to remain responsiveness. I try to learn the web by making a card game.
What I have is things to click on, which are supposed to be appearing somewhere else on the page. (Im using jQuery so far)
The (simplified) use-case is:
var card = $('[card=X]').remove();
$('.board').append(card);
Now I want to add some animation to it.
I am failing in choosing an appropriate framework.
In the ones that I tried I couldn't time the removal, or the animation was gone, when I tried to call the removal, in a callback. Which was horrible, because the removal either fired before the callback or not at all. Or there was nothing left to be reattached..
So it should be more then just 'blur' or 'fade'.
So I want to detach a thing with an animation, place it somewhere else, and make it 'appear' there with an animation.
As a superb bonus, those animations would have an orientation, so that the 'from' and 'where to' are visible appearing to the end user. (Like an arrow or a line drawn between those 2 locations.)
(Sry for not being more specific, but asking that question for all the frameworks/ libs out there appears not that appealing..)
edit:
Nick pointed me in the right direction. My issue was the boilerplate code. I adjusted the code he provided. (added fade in animation + have the things 'reappearing' with event handler)
..thus I marked his answer as correct. (even that it wasn't, he didn't append the original thing, instead he created a new one.)
$('.cards ').on('click', '[card-id]', function() {
$(this).fadeOut(1000, function() {
var old = $(this).remove();
$('.cards').append(old);
old.fadeIn();
});
for(var i = 0; i < 6; i++) {
$('.cards').append('<div class="card" card-id="'+i+'"></div>');
}
$('[card-id]').click(function() {
$(this).fadeOut(2000, function() {
$(this).remove();
$('.cards').append('<div class="card" card-id="'+$(this).attr('card-id')+'"></div>');
});
});
.card {
position: relative;
display: inline-block;
width: 120px;
height: 180px;
background-color: #F4F4F4;
border: 1px solid #E8E8E8;
border-radius:5px;
margin: 15px;
cursor: pointer;
}
.card:after {
content: attr(card-id);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
font-weight: 700;
font-family: courier, serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cards"></div>
Consider using .animate() from Jquery. There is a lot you can do with it.
Take a look at the API: http://api.jquery.com/animate/

Javascript - Adding Class and Style Prescience

I'm trying to make little progress indicators for a form that change depending on the page you are on. I thought the easiest way to do this would be to create the circle ID's, style them, and then just add a class list with one or two stylistic changes to show something different as a specific page was brought up.
When my function executes, the new class with the changes is being added -- the dom is proving that -- but, the style is not overtaking the original.
I've tried classList.Add, classList.toggle, className.add/Classname.toggle. Nothing seems to work.
Why might that be?
function nextPage()
{
var step2 = document.getElementById("step2");
step2.classList.toggle("newClass");
};
#step2
{
height: 27px;
width: 27px;
border: 1px solid #e5e5e5;
background: linear-gradient(#f2f2f2, #e9e9e9);
border-radius: 50%;
content: "";
margin-left: 95.5px;
float: left;
}
.newClass
{
background: linear-gradient(#f2f2f2, #8c66ff);
}
<div id="step2"></div>
<br />
<p id="next" onclick="nextPage()">Next</p>
Calculating CSS Specificity Value:
As we know, it was because simply using the class name by itself had a lower specificity value and was trumped by the other selector which targeted the unordered list with the ID value. The important words in that sentence were class and ID. CSS applies vastly different specificity weights to classes and IDs. In fact, an ID has infinitely more specificity value! That is, no amount of classes alone can outweigh an ID.
For more info https://css-tricks.com/specifics-on-css-specificity/
So, more specificity use Class aswell as IDs.
!importent, also works but it note a good practice.
Hope this will help you..
Your id step2 will always override your class newClass.
Easiest solution is just to change .newClass { ... } to #step2.newClass { ... } in your CSS to make it more specific
function nextPage()
{
var step2 = document.getElementById("step2");
step2.classList.toggle("newClass");
};
#step2
{
height: 27px;
width: 27px;
border: 1px solid #e5e5e5;
background: linear-gradient(#f2f2f2, #e9e9e9);
border-radius: 50%;
content: "";
margin-left: 95.5px;
float: left;
}
#step2.newClass
{
background: linear-gradient(#f2f2f2, #8c66ff);
}
<div id="step2"></div>
<br />
<p id="next" onclick="nextPage()">Next</p>

Toggling Active States

Easy question for a lot of you but I'm still learning. I'm trying to get better at toggling between active and inactive states of simple objects.
I have a square div:
<div id = "square"></div>
With the following css to, onclick, make the div extend
#square
{
height: 50px;
width: 60px;
border: 1px solid red;
transition: height 2s ease;
}
#square:active
{
height: 100px;
}
And the following javascript to set up the click event:
var square = document.getElementById("square").addEventListener("click", function()
{
this.classList.toggle("active");
}, false);
But nothing seems to happen when I click. I'm including JS in this because I'm also new to learning JS as well, and I'm trying to get used to simple logic principles.
Here is the fiddle: https://jsfiddle.net/theodore_steiner/fsk6y50k/4/
Any help would be wonderful
The way that you used the class selector is wrong,
#square.active{
height: 100px;
}
It should precede with a dot not a colon
DEMO

Can you partial match classes in Less?

I am new to less and would like to do a partial match with classes to pre-process the CSS without writing a bunch of redundant classes.
e.g. Less:
#blue: #1f6ea9;
#white: #f5f5f5;
.square(#size, #color) {
width: #size;
height: #size;
background-color: #color;
}
CSS:
div[class^="square-"] {
div[class*="-150"] {
div[class*="-white"] {
.square(150px, #white);
}
div[class*="-blue"] {
.square(150px, #white);
}
}
div[class*="-200"] {
div[class*="-white"] {
.square(200px, #white);
}
div[class*="-blue"] {
.square(200px, #white);
}
}
}
HTML:
<div class="square-150-white"></div>
<div class="square-200-blue"></div>
<div class="square-250-blue"></div> // this would not work
Doing it this way seems like it can get convoluted very easily, and is not dynamic or manageable. Ideally I would like to define one primary, so perhaps we have .square() and .circle(). Then take the rest of the class to define the variables passed to that function.
div[class^="square-"](#size, #color) {
.square(#size, #color);
}
div[class^="circle-"](#size, #color) {
.circle(#size, #color);
}
<div class="circle-150"></div> // generate 150px circle, default color
<div class="circle-300-blue"></div> // generate 300px blue circle
<div class="square-blue"></div> // generate blue square, default size
<div class="square-50-white"></div> // generate 50px white square
Any help on this matter is appreciated.
I think you may be over engineering. One strength of CSS is to have different styles that can be combined, rather than doing all the combinations by less functions. Lets say you have 3 shapes, 3 dimensions, and 3 colors. Using plain old css, this would require 9 selectors with rules:
.square { border-radius: 0; }
.rounded { border-radius: 5px; }
.oval { border-radius: 50%; }
.dim-150 { width: 150px; height: 150px; }
.dim-200 { width: 200px; height: 200px; }
.dim-250 { width: 250px; height: 250px; }
.bg-red { background-color: #ff2020; }
.bg-white { background-color: #f5f5f5; }
.bg-blue { background-color: #1f6ea9; }
If we were to create 3 less functions, then generated the combinations, we would have 3^3 = 27 rules (not including the functions themselves). It becomes an exponential problem. Just adding 1 shape, 1 dimension, and 1 color would come up with 256 rules, yet separating the pieces would be 12 rules!
Another idea to consider that when naming classes, authors are encouraged to describe the content, rather than the presentation of the content.[1][2] The idea is that in the future, styles are more likely to change than the classes.
For example, Lets say you had a notification that was red and an oval. You could give it the class="oval bg-red" classes. But what if you later wanted to make these notifications yellow, and a rounded square? You could modify the css, but then the class name wouldn't match the style (.bg-red giving a yellow background), and other elements who reuse the same class would change color without you desiring so. That wouldn't work, so you would have to go to every place on your site in the HTML and change the classes.
Instead, what if we gave the notification the class="notification warning" classes. Notification now describes all notifications on the site, and warning describes all of your warnings. At first you want to change them from oval to square, so you modify the single css rule. You decided to repalette your site, and change all warnings from red to yellow, with the one rule. I believe the same should go for less variables. Instead of #blue, #white which wouldn't make sense to ever change, make them #accept-color, #bg-theme, etc.
You could do it like this in less
LESS:
#blue: #1f6ea9;
#white: #f5f5f5;
.square(#size, #color) {
width: #size;
height: #size;
background-color: #color;
}
.square {
&-150{
&-white{
.square(150px, #white);
}
&-blue{
.square(150px, #blue);
}
}
&-200{
&-white{
.square(200px, #white);
}
&-blue{
.square(200px, #blue);
}
}
}
This is the css that it generates
CSS:
.square-150-white {
width: 150px;
height: 150px;
background-color: #f5f5f5;
}
.square-150-blue {
width: 150px;
height: 150px;
background-color: #1f6ea9;
}
.square-200-white {
width: 200px;
height: 200px;
background-color: #f5f5f5;
}
.square-200-blue {
width: 200px;
height: 200px;
background-color: #1f6ea9;
}

Javascript "object" not retaining css values

I'm defining a javascript "object" via the following function:
function Window(vars) {
this.div = $("<div/>", {
id: vars.id,
class: vars.styles + " box text",
css: {
top: vars.top,
left: vars.left
}
});
this.div.appendTo( $("body") );
// more stuff happens..
As you can see, the Window has a div property, which is a jQuery object. In it's instantiation, I declare the CSS classes box and text. text is not important, it's just font stuff. Here's the CSS for box, however.
.box {
z-index: 1;
position: absolute;
background: #222222;
min-width: 10%;
text-align: center;
padding: 5px;
}
.nav-extension {
z-index: 3;
padding: 8px;
background: #000000;
position: absolute;
-moz-border-radius-bottomright: 5px;
-moz-border-radius-topright: 5px;
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
}
box is absolute at z-index 1, and another div with nav-extension is somewhere else on the page, also absolute and at z-index 3. However, when I add the Window object to my page, it appears above anything with nav-extension. All other CSS attribues, like background, still work.
I've tried altering the z-index where I instantiate the div in the "css" section I'm already using, but that didn't work either. What gives?
Edit
Also, I've inspected both the div with box and the one with nav-extension with Firefox, and the "Style" tab indicates they still have their intended z-index (not overridden).
#2: Changed vars.class to vars.styles.
Could you give us some DOM, please? It appears that that your box and the nav-extension-div are in different contexts. A non-static position sets up a new context, relatively to which all z-indexes inside are processed. A simple fiddle to demonstrate: http://jsfiddle.net/3KTyz/
<body>
<style>
.box { z-index:1; }
.nav-extension { z-index:3; }
</style>
...
<div id="context" style="position:relative"><!-- or absolute or fixed -->
...
<div class="nav-extension"><!--
will be positioned +3 relatively to other elements in #context
-->...</div>
</div>
<div class="box"><!--
will be above #context, which has (implicit) z-index:0
-->...</div>
</body>
To make nav-extension appear above the box, you will either
set #context (or one of its parents) to a z-index higher than the one of box or
move the nav-extension-div outside any context
class is a reserved word in JavaScript and cannot be used as a property or a variable name, maybe this is the culprit.

Categories

Resources