I am learning about JavaScript, and in the text it says you must us locally defined styles for animation. i.e. A HTML style tag. Does this make sense, and if so, why is this necessary? Thanks in advance.
No, this is not necessary.
You can do it in two basic ways.
Dynamically change the style:
<p id="myElement">Here is some text to animate</p>
<script>
var pixels = 10; // e.g., if this were a dynamically changing variable
document.getElementById('myElement').style.width = pixels+'px';
</script>
Dynamically change the class:
<style>
.tiny {width:10px}
</style>
<p id="myElement">Here is some text to animate</p>
<script>
document.getElementById('myElement').className = 'tiny';
</script>
The latter approach is probably a better practice because it gives control to the designer to control everything from CSS, while letting the JavaScript programmer focus on functionality only.
However, in the case of transitions, where you wish to change values dynamically (e.g., incrementing the width by 1 every second), it is not practical to define a class for each possible width along the way. However, it is possible for you to query the stylesheet itself to get this info. CSS Variables will make this easier if they are implemented, but currently you can use something like the function getCSSPropertyValue at https://gist.github.com/990313 to get the begin and end values from classes defined in the stylesheet, while handling the style transitions with the style property.
var beginWidth = parseInt(getCSSPropertyValue('.small', 'width'));
var endWidth = parseInt(getCSSPropertyValue('.large', 'width'));
var itvl = setInterval(function () {
if (beginWidth++ > endWidth) {
clearInterval(itvl);
}
document.getElementById('myElement').style.width = beginWidth + 'px';
}, 10);
They may be referring to changing the style locally in javascript. In order to do that you utilize the style attribute of each element.
element.style.width = "100px";
would change the style to a width of 100px. This is how you change the appearance of elements with javascript.
Perhaps what the text means is that when you do something like call the jQuery animate() function, for instance, passing in CSS properties, those properties are set via the style attribute of the HTML element. This makes sense because you'll want these rules to override any pre-defined rules from your stylesheets.
Example: http://jsfiddle.net/jRKJx/
If you inspect the <div> after the animation runs, you'll see that jQuery set the style attribute on the element.
Related
How can I do this(or something alike this) tooltip in only javascript without linking any template styles (I don't want to implement It to all the tooltips on the whole page). I'm designing the webpage on SharePoint which deletes all the ...
https://www.w3schools.com/css/tryit.asp?filename=trycss_tooltip_top
You can always add inline styles via JS.
var a = document.getElementsByClassName("class-name");
a.forEach(function(e) {
e.style.property = "value";
});
For adding :hover effects however, I think you need to append a stylesheet. Example.
Your other option is to use mouseover effects, but that is ridiculous when :hover exists.
I am making a chrome extension, and I want to find all occurrences of a certain word, and put them inside a new div class so I can change them with CSS.
Right now my content.js file looks like this:
(function() {
function change() {
var words = new Array("color");
var html = document.body.innerHTML;
for(var i = 0; i < words.length; i++) {
var reg = new RegExp(words[i], 'ig');
var html = html.replace(reg, '<div class="colorClass">'+words[i]+'</div>');
}
document.body.innerHTML = html;
}
change();
})();
But when I do that, entire web pages get messed up and become unrecognizable (for example, the "Color" wikipedia page).
When I try something simpler like:
var html = html.replace(reg, '<i>'+words[i]+'</i>');
It works just fine. Why is this whole page getting messed up when I try to add divs?
How can I fix this?
One reason the styles are messed up are because the native web page's CSS is overriding the styles loaded from your content script.
The second reason is that you need to be very careful when modifying HTML. You need be careful only to modify text. The current method you are using - you are possibly modifying html classes, ids, etc.
I've actually built an extension (Source code for reference) that does something very similar. I'll share my learnings:
JS
I had used NodeIterator which is fairly unknown. I discovered this API a year ago from another extension: https://code.google.com/p/chrome-type-ahead/
NodeIterator will help you filter out the true text elements that you want to add styles to. This will help you avoid modifying any valid html(classes, ids, etc.) that matches your regex.
CSS
I would suggest adding a class to the html tag in addition to the html you are inserting. The reason for this is that you'll need to be very specific in your styles.
You want to avoid at all cost any chance of a collision with a selector of an existing page.
In addition you need to make sure to add your own css resets that are not only namespaced but also have !important on each attribute.
You CANNOT assume anything about the html tag that you are inserting. Sites can have very generic selectors that will completely mess up your styles. And also the sites can have very specific selectors (using id) that are more specific than you're styles (hence the need for important)
html.very-specific-class .very-specific-color-class {
/*
padding, margin, border, etc.
difficult to add all properties but add all the common ones at the very least
*/
padding: 0px !important;
margin: 0px !important;
border: 0px !important;
...
}
This is happening because a <div> is a block-level element, and it pushes other elements to a new line.
<i> however, is an inline element, so it will not change the page layout at all.
I would recommend using a <span>,instead of a <div>, as span's have no default styling in browsers.
Because divs are block elements. You can use spans, which are inline elements:
var html = html.replace(reg, '<span class="colorClass">'+words[i]+'</span>');
If you want use div,you can add some css styles,like this:
.colorClass{display:inline-block;}
I have a parent div gal1, inside which there can be further divs and content, but only one img element without an id as you can see below. Now I want to use only Javascript (no jQuery) to change the style of this image, using gal1 as argument (because the rest of the structure inside this div may vary, only this one image will always be there somewhere). I couldn't find any other stackoverflow question that addresses exactly my situation.
<div class="gallery-preview" id="gal1">
<div class="gallery-preview-img" id="gal-img1">
<img src="galleries/kevin-carls/Monks.jpg">
</div>
<div class="gallery-preview-text" id="gal-text1">
<span class="gallery-name" href="">Road to India</span><br/>
<span class="artist-name" href="">Kevin Carls</span>
</div>
</div>
Than you can make use of method called getElementsByTagName('img') than you should get image and update it.
document.getElementById(gal1).getElementsByTagName('img');
get the content by using id, and then query images by using getElementsByTagName
function getImages(contentId) {
var content = document.getElementById(contentId);
// only one image, just return an item; or you can return an array
if (content) return document.getElementsByTagName('img')[0];
}
You can insert CSS which may be more efficient if you have to do this in more than this single case.
http://jsfiddle.net/65Ggv/
var style_rules = [];
style_rules.push("#gal1 img { border: 3px solid green; } ");
var style = style_rules.join("\n");
var el=document.createElement("style");
el.appendChild(document.createTextNode(style));
el.type="text/css";
document.head.appendChild(el);
Unless you absolutely need to pick the colors or border sizes dynamically, which I doubt because you are an admitted beginner, stuffing stylesheets in with Javascript is a Rube Goldberg device. It seems nifty to be able to do this, but if your application is important to you, you will regret it. (You might as well use innerHTML to stuff in a stylesheet in that case -- at least it will be faster than making DOM calls.)
Pranay Rana's answer to use getElementsByTagName is the best option if your constraints are actually stable (only one img). Obtain an element reference el, to gal1, using getElementById, then var myimg = el.getElementsByTagName("img") and you are almost done.
If you insist upon funking with the style nodes, you can stuff whatever properties you want into the style property of myimg. It becomes inline style.
Even so, you almost certainly do not need to stuff in novel rules, and changing inline style is often avoidable. It is more predictable and stable to modify the class attribute on myimg, and use a predefined set of style classes for the cases you need to handle. This will give a nice clean separation of the style from the script, and avoid both the in-lining of the style rules and run-time mutilation of the style tree by code injection.
I have a div that can display 3 images (in the background) each indicating the 'state' of some variable: i.e., partial, full and none. For each of these states I have images: partial.gif, full.gif and none.gif (i.e., these are background images of that div)
Need: Circular queue like toggling effect for changing the images in this order partial -> full -> none -> partial
So if the current image is 'partial.gif' and the user clicks the div the background image changes to the next one in the sequence i.e., full.gif (and if it is currently full.gif it changes to none.gif and that to partial.gif and so on).
Naive solution: have a bunch of if/else's or switch-case and check the current one (image) and then decide based on array look up which is the next one. Is this the best way of doing it? Can I leverage jQuery's toggle function somehow?
(PS: It need not be restricted to images, but could also be for different background color sequences etc., I'd like to know what it is a good 'generic' way of doing it i.e., The example may be specific for background images but if I changed part of that code for background-color or font it should still work. I don't want it to be purely generic, but just enough so it is easy to modify for other attributes. If not, that's fine too. Just a thought :)
http://api.jquery.com/toggle-event/
To be precise http://api.jquery.com/toggle-event/#example-0
does exactly what you wanted...
$("#div1").toggle(
function() {
$(this).css("background-image","url(full.png)")
},
function() {
$(this).css("background-image","url()")
},
function() {
$(this).css("background-image","url(partial.png)")
}
});
UPDATE fn.toggle was removed from jQuery
Here are relevant posts
Where has fn.toggle( handler(eventObject), handler(eventObject)...) gone?
Toggle stopped working after jquery update
As long as it's a CSS-based solution (where you can just switch classes), you could do something like this (untested code):
$('#element').click(function() {
// get current css class value.
var class = $(this).attr('class');
// determine/increment number.
var nextNumber = parseInt(class.charAt(class.length - 1)) + 1;
// if too high, reset to first one.
if (nextNumber > 3) {
nextNumber = 1;
}
// remove old class and add new class.
$(this).removeClass(class).addClass('my_class' + nextNumber);
});
Assumption being made here that you only have one CSS class applied to the element at a time. But if that's not the case, I'm sure you can find a workaround/tweak for this.
And this is just generic enough where you can swap out your CSS class definitions without impacting the script functionality.
I have a search page that is used in multiple places with multiple 'themes' throughout my site. I have a few divs that can have their background color changed based on a radio button selection (whether they are enabled or not). I can do this just fine by changing the css class of the div on the fly with javascript.
However, these themes could potentially change, and the background color is grabbed from a database when the page is created. Right now I do this in the C# codebehind:
string bgStyle = "background-color:" +theme.searchTextHeaderColor +";";
OwnerSearchHeader.Attributes.Add("style", bgStyle);
In the Javascript I need to change this color to make it look disabled, and when the user clicks back to this div I need to re-enable it by changing it back to its original color. But since I only knew this color in the code-behind, I don't know what it was in the Javascript.
So my thought was to create a css class in the resulting HTML page when the page is loaded with the background color I need. Then I could simply switch from the divEnabled and divDisabled class in the javascript. But I'm not exactly sure how to do that.
Alternatively I could create a hidden element, assign it the 'enabled' style, and use that as a reference in the JavaScript when enabling my div. This seems like a hack but maybe its the easiest way. I'm still new to a lot of this, so I'd appreciate any suggestions. Thanks for the input!
So my thought was to create a css class in the resulting HTML page when the page is loaded with the background color I need. Then I could simply switch from the divEnabled and divDisabled class in the javascript. But I'm not exactly sure how to do that.
Yes, this is the anser; do this. In the <head> of your document add a <style> and put your CSS in there like so: (my Asp.NET is a little rusty so forgive me if it has some hicups ;) )
<style>
<!--
.divEnabled {
background-color:<%=theme.searchTextHeaderColor%>;
}
.divDisabled {
background-color:gray; /* or wtv */
}
-->
</style>
You could also put it in an external CSS file, which may be a good idea.
Then write some JavaScript to add/remove the class attribute (I'm going to ask that you don't call is the "CSS Class" ;) )
var ownersearchheader = document.getElementById("<%=OwnerSearchHeader.ClientId%>");
// changing the class attribute to `divDisabled`
var newClassAttribute = ownersearchheader.getAttribute("class").replace(/\bdivEnabled\b/, "divDisabled")
ownersearchheader.setAttribute("class", newClassAttribute);
// ... or,
// changing the class attribute to `divEnabled`
var newClassAttribute = ownersearchheader.getAttribute("class").replace(/\bdivDisabled\b/, "divEnabled")
ownersearchheader.setAttribute("class", newClassAttribute);
This is indeed a mouthfull, so, like #Haydar says, you might want to use jQuery, which offers easy-as-pie addClass(), removeClass() and toggleClass() methods.
You can use the jquery .toggleClass method.
Description: Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument.
Here is the link to the api doc.
Jquery API