Assume you have a list item, <li id="foo"> which you want to fade from one color to another when moused over, and that you are using jQuery. This is fairly easy:
$('li#foo').bind('mouseenter' , function(e) {
$(this).animate({backgroundColor: '#F00'} , 300);
});
However, what if you wanted to get the resulting color or other style rules from a class defined in CSS without also declaring them in JavaScript? It seems there's no way to learn style information from CSS rules without having an example of the rule already in the document, which would require you to animate the <li> to the target appearance, then in the animation-finished callback, set the class which leads to redundant style declarations and can foul up your CSS at "runtime".
Sorry if this question's unclear: It doesn't occur in the context of any specific project, I'm just curious how you'd go about this. Also, I know CSS3 hypothetically includes support for such transitions but using CSS for dynamic behavior like this seems such an ugly hack.
I'm pretty sure javascript can't read your style-sheet.
If you want a certain property from the style-sheet that does not occur anywhere on the page, you will have to add an invisible element that has that style applied, either at page-load time in the html or with javascript whenever you want.
It does seem a bit theoretical though, instead of defining styles in your style-sheet that you are not using, you might as well declare the appropriate variable directly in javascript.
You need the color plugin to animate background color.
You should be able to simply do:
$(this).css('background-color')
If you want to get the color AFTER its been updated, add it to the callback, like:
$('li#foo').bind('mouseenter' , function(e) {
$(this).animate({backgroundColor: '#F00'} , 300,function(){
alert($(this).css('background-color'));
});
});
You can then save that to a var, or do whatever you wanted to do with it. You could also change your "bind" to "live" and it will update automatically each time its run:
$(selector).live(event,function(){
alert($(this).css('background-color'));
});
As a side note, you shouldnt do li#foo :) just do #foo speeds up your selection time and its unnecessary as there is only 1 element with that ID.
I've played around a little with Calvin's idea, and this is what I got:
Assuming the following CSS:
#somediv .bar em {
color: #080;
}
You can create the elements virtually and get the style information that way:
$('<div id="somediv"><span class="bar"><em>')
.find('em').css('color')
Watch it in action.
Related
I want to toggle(hide/show) an element when a button is being pressed. I have two ways as to implement this:
Find the element according to its class name, e.g $('.my-content')
Find the element according to its relevant DOM position towards the button, e.g. $('#my-button').parent().next().next().next()
However, none of the above seems to me very reliable since in case someone changes the HTML code, the above approaches should not work. Is there something more reliable I am missing?
If it's a specific element, supply it with an Id value and use that
to find it.
If it's a TYPE of element, use a class name.
Other than that, there's no real conventions. Just try and make sure that somebody reading your code understands what is going on.
A very good practice is to decouple HTML, CSS and JS.
When binding javascript to DOM elements you should use javascript selectors.
Basically classes with some custom prefix (like js-) which will be used only for javascript purposes (not css style).
So whenever the DOM tree structure or the CSS class names are changed, you can still have your working JS selector
HTML
<div class="my-content js-toggle-element"></div>
JS
$('.js-toggle-element')
CSS
.my-content{ ... }
Plus, using Javascript Selectors:
makes HTML highly readable: you can easily find out what will happen to that element with that js class
allows you to easily apply/disapply that behaviour also to other elements in the future, simply by adding/removing that class in your HTML and without affecting CSS at all
<div class="my-content js-toggle-element"></div>
...
<div class="another-content-to-toggle js-toggle-element"></div>
Using jQuery will be much easiest way. Like this -
$( ".target" ).toggle();
The matched elements will be revealed or hidden immediately, with no animation, by changing the CSS display property. If the element is initially displayed, it will be hidden; if hidden, it will be shown.
Reference - jQuery Toggle
If the class or the position of the element in DOM is changing then you can try
selecting it with the inner text
$("button:contains('buttontextgoeshere')")
I have an HTML page containing XML. Using Javascript, the XML attributes can be changed when the user clicks a button. (So far, everything works)
However, the attribute that is changed is used in the linked CSS to determine the background color of the element. When the attribute value is changed, the style is not refreshed, so the color doesn't change.
I can alter the javascript to also change the color, but that would involve hardcoding the color, and partially defeat the point of using CSS.
So, it seems to me, I need to do one of two things, and I can't figure out how to do either:
read the color from the CSS, and then assign it using javascript
somehow use javascript to have the CSS re-applied to the document.
Which approach is better? I assume the 2nd is easier, unless there is a side-effect I haven't thought of. And, whichever approach is better, HOW TO DO IT?
My CSS contains:
*[cleared=true] {
background:lightgrey;
}
My XML looks like this:
<Transfer ID="31266" Date="2015-04-14" Cleared="false">
<AccountCharge Account="Unplus">-826.20</AccountCharge>
<AccountCharge Account="Amex">826.20</AccountCharge>
<TransactionID>1504140662984782</TransactionID>
</Transfer>
My Javascript is:
function Reconcile(Element_ID){
try {
var c=document.getElementById(Element_ID);
c.setAttribute('Cleared','True');
}
catch(e) {
alert(e.description);
}
}
I have tried changing the script from modifying 'Cleared' to 'Date', and I can see the date change. The 'Cleared' attribute is not displayed directly by the CSS, but is used to set the formatting of other elements and/or attributes.
Changing the value of 'Cleared' before the page is loaded has the effect I expect - the CSS causes the formatting I expect. However, after the page is loaded, when the javascript changes the value of 'Cleared', no visible change in formatting takes place.
Did you try to assign classes?
Either with pure Javascript:
document.getElementById('selector').className = 'active';
or with jQuery:
jQuery('#selector').addClass('active');
This way you can use CSS classes and not hardcode the colour in your Javascript code.
See implementation of addClass and removeClass in Javascript:
http://jaketrent.com/post/addremove-classes-raw-javascript/
There's some info about changing style of HTML element with jQuery: jQuery changing style of HTML element
There's some more if you change your mind: How to modify STYLE attribute of element with known ID using JQuery
You can either add some extra styles or just switch the target class/id.
When we want a more reliable way to get the style of an element, we use
document.defaultView.getComputedStyle..
instead of
document.getElmById(x).style.color..
BUT, there is another, and it is
document.styleSheets...
I'm new to JS, I just read about document.styleSheets today. And my question is:
When we want to get just one style property (example: color), which should I use?
What is document.styleSheets for? When should it be used?
When we want to add a method that looks like this:
// it applies multiple properties
elm.setStyle({
color: '#f00',
marginLeft: x,
opacity: 0.5,
background: '#000 url(x.jpg) left top no-repeat'
});
Which should I use to be the base of the function?
Finally, Thanks for all your help!
document.styleSheets is the list of the actual stylesheet or sheets loaded into the page. Fun fact: you can dynamically create new "stylesheets" and add them to this list, without actually loading separate files.
If you are looking up the current style of an element, the question you need to ask is, "do I care more what the stylesheet SAYS the style should be, or do I care more what the actual current (computed) style is?" The circumstances will determine which is more appropriate.
If you care about the original declared styles, you'll want to consult the stylesheets themselves. However, this is quite a bit more complex than it may seem, because you're going to have to parse the files and find all the cascading styles that would apply to the element in question.
If you care about what the current computed styles are, getComputedStyle() is more reliable that .style.
Now, for setting, if you want to apply a style rule directly to a single element, you'd want to use .style, but if you want to create a new rule that applies to many (and future!) elements, you'd want to create a dynamic stylesheet/rule and append it to the .styleSheets collection.
here is my code
<!doctype html>
<html>
<head>
<style>
body {
color:red;
}
</style>
<script>
window.onclick = function(){
document.getElementsByTagName("body").color="blue";
}
</script>
</head>
<body>
here is some text for test
</body>
when i run it in my browser (initially it is red) and click in window it doesn't respond to click i mean it should change the color of text from red to blue but nothing happens. Where am i wrong?
Try this:-
Demo
This will add style attribute to the body element, which will override the css rule.
window.onclick = function(){
document.getElementsByTagName("body")[0].style.color="blue";
}
It should be style.color as color is a property of style property of element and even though it is body .getElementsByTagName returns a collection so you need to use document.getElementsByTagName("body")[0] to get the element and apply style to it.
And yes styles applied the element direclty will override the class css rule
Style property has more precedence over styles applied by class.
document.getElementsByTagName("body").color="blue";
This has more preference
Also color is a property of style attribute.
So your style should have looked something like this as getElementsByTagName returns a node list.
document.getElementsByTagName("body")[0].style.color="blue";
it is a better idea to use classes instead, cause it is lot cleaner.
Inline CSS is more powerful and overrides CSS defined anywhere else.As far as working of your code, I modified it a little bit like this:
window.onclick = function(){
//document.getElementsByTagName("body").color="blue";
document.body.style.color="blue";
}
DEMO here
You have an error in your JS. getElementsByTagName returns a NodeList (which is like an array), not a single element. You need to set the property on an element, not a NodeList. For example:
document.body.color="blue";
Setting the color property of the body element (IIRC, it's been a very long time since I went near that part of HTML) is equivalent to setting the color attribute. This is an obsolete presentational hint attribute.
The CSS specification says:
The UA may choose to honor presentational attributes in an HTML source document. If so, these attributes are translated to the corresponding CSS rules with specificity equal to 0, and are treated as if they were inserted at the start of the author style sheet. They may therefore be overridden by subsequent style sheet rules. In a transition phase, this policy will make it easier for stylistic attributes to coexist with style sheets.
So the style specified in the stylesheet should continue to apply.
On the other hand, setting a style.something property is equivalent to modifying the style attribute on an element.
document.body.style.color="blue";
In the cascade, !important declarations aside, properties set via the style attribute are most specific.
So of those two rules, the blue one would win.
JS inserts the changes inline, giving them pretty much the highest priority, unless you have !important in your css.
Check to see if you code (document.getElementsByTagName("body").color="blue";) works from the dev console (F12 for Chrome). There appears to be a problem with it. I can't help debug, however, as I usually do such actions via jQuery, and vanilla JS color changes are unintuitive for me.
js and css does not compete with each other, what you are doing is essentially javascript applying css to an html element, this means that its still css, that type of css is called inline css, . As others have said inline css has more precendence over normal css except if you use !important in your css rules
As to why your code is not working, because you are doing it wrong.
Change
document.getElementsByTagName("body").color="blue";
To
document.getElementsByTagName("body")[0].style.color = 'blue';
Here's a jsFiddle
http://jsfiddle.net/n2kqd/
I am using mouseenter and mouseleave events on some elements to change their appearance. I am able to do so using either of the following two strategies:
$(this).css('someProperty','someValue') to add and then $(this).removeAttr('style') to remove
$(this).addClass('someClass') to add and then $(this).removeClass('someClass') to remove
What is the best way to do so?
Definitely option 2. Styles should be defined in the stylesheet.
There's also toggleClass, which removes the class if it's there, but adds it if it's missing.
Note: toggleClass also lets you pass in a Boolean as the second argument, telling it whether to add or remove it (regardless of whether it currently has that class applied), so:
$(this).toggleClass('active', true);
is exactly equivalent to:
$(this).addClass('active');
This is very handy when you have a Boolean in your code already. So instead of this:
if (isUserActive()) {
$(this).addClass('active');
} else {
$(this).addClass('active');
}
You could just do this:
$(this).toggleClass('active', isUserActive());
Option 2 if you must do it in JavaScript, but for modern browsers you may be able to achieve what you're after entirely in CSS using :hover pseudo-classes.
I'd strongly recommend addClass()/removeClass(), since you can add, remove and change a whole swathe of properties with minimal jQuery.
Whereas the css() method requires you, or rather the script, to keep track of what should be changed to reflect the aesthetic change(s) to convey programmatic interaction, coupling that with the attr() method and removing the style attribute will remove all styles, even those you want the element to retain, which requires you to reassign those properties.
So, basically, option 2 is efficient, and option 1 creates unnecessary work.
There is, of course, always toggleClass(), which can promote further efficiency.
Unless you need to dynamically generate any of the CSS property values you're better of separating the styles from the javascript. So use classes instead of direct css styles.
.addClass and .removeClass is the best way because you can style you changes with your CSS ...so after a while you can easily redesign your site.
Second one is best because normally style will is common for different elements, it will generic and adding removing is good compared with adding attribute one by one.
$(this).addClass('someClass') to add and then $(this).removeClass('someClass') to remove
If you are calling this function in more than one element I suggest you to use the second one. If you needed to change the appearance again later, then you have to edit only within the css class, not in all elements