I'm new at JavaScript. I have an html document and I want to change to fontsize of paragraphs that are inside a div but I'm having a problem. I got this error in the console:
Uncaught TypeError: Cannot set property 'fontSize' of undefined codigo.js:5
This is my html:
<!DOCTYPE html>
<html leng="es">
<head>
<meta charset="UTF-8">
<title>Mi ejercicio DHTML</title>
<link rel="stylesheet" type="text/css" href="css/estilos.css">
<script type="text/javascript" src="js/codigo.js" ></script>
</head>
<body>
<div id="parrafos">
<p>
Your bones don't break, mine do. That's clear. Your cells react to bacteria
</p>
<p>
Your bones don't break, mine do. That's clear. Your cells react to bacteria
</p>
<p>
Your bones don't break, mine do. That's clear. Your cells react to bacteria
</p>
<p>
Your bones don't break, mine do. That's clear. Your cells react to bacteria
</p>
<p>
Your bones don't break, mine do. That's clear. Your cells react to bacteria
</p>
</div>
</body>
</html>
This is my js:
window.addEventListener('load', inicio);
function inicio(){
var parrafos = document.getElementById('parrafos');
parrafos.childNodes[0].style.fontSize='10px';
}
What I want is by using the childNodes on the div called parrafos change the style of every paragraph by accessing its index parrafos.childNodes[2].style.... etc etc
[EDIT]
I ended with this code:
window.addEventListener('load', inicio);
function inicio(){
var parrafos = document.getElementById('parrafos');
parrafos.childNodes[1].style.fontSize='1.5em';
parrafos.childNodes[3].style.fontSize='1.3em';
parrafos.childNodes[5].style.fontSize='.5em';
parrafos.childNodes[7].style.fontSize='1em';
parrafos.childNodes[9].style.fontSize='.2em';
}
and I found that because of space en html documents it doesn't follows a consecutive order it seems weird because I thought it should go consecutive.
Try this:
window.addEventListener('load', inicio);
function inicio(){
var parrafos = document.getElementById('parrafos');
for (var i=0; i<parrafos.children.length; i++) {
parrafos.children[i].style.fontSize = '10px';
}
}
In your example you should set the fontSize to '10pt' instead of '10px' (or '1em') see: http://jsfiddle.net/K9Uhn
var parrafos = document.getElementById('parrafos');
parrafos.childNodes[1].style.fontSize='10pt';
Also, You should also look into using jQuery for this. It would save you a ton of headaches as it handles the element iteration and dom issues itself. For example, the jQuery code to change all the font sizes for the above example would be
$("#parrafos").css("font-size", "10pt");
No need to do the for loop yourself, jQuery handles all this. And, it's compatible with all browsers (something you will find is a huge plus): www.jquery.com
Tweaking the styles like this on a per-element basis is not a good idea. Stylesheets and element clases are your friend!
Please think about the next guy who picks up your code. They need to change the font size. They look in the stylesheet, where you would expect to find that value, and it's not there. After a few hours they find it in the JavaScript, where you wouldn't expect it. Then they get off work, drink heavily and botch about your code to their friends because of how hard you just made their day.
Maintanability is the thing that minimizes how often this scenario occurs.
So instead, how about you give your body class a tag, and have some styles that change font sizes based on that?
/* Stylesheet */
p {
font-size: 16px
}
body.small p {
font-size: 10px
}
Now your JS function that takes the action simply becomes this:
// Javascript
function inicio(){
document.body.className = 'small';
}
Which is far easier to manage.
See it work here: http://jsfiddle.net/s6BAf/
In general, dont use inline styles in your HTML, or set CSS values directly in your javascript if you can avoid it. Instead, manipulate the classes of elements on your page, and let your stylesheet do what it does: style your content.
Related
I am trying to make this code change the pre-written text font, font size, and color with an onclick button but am unable to make it work this is what i have so far and im stuck. anyone have any ideas?
<html>
<head>
<meta charset=utf-8 />
<title>Change Paragraph Text</title>
</head>
<body>
<p id ='text'>I am going to change this text, I hope.</p>
<div>
<button id="jschange" onclick="DoAll">Style</button>
</div>
<script type="text/javascript">
var style = 'text';
function DoAll() {
One(document.write.style.big());
Two(document.write.style.fontsize(7));
Three(document.write.style.fontcolor("red"));
}
</script>
</body>
</html>
Try this, it's a much simpler approach and won't make anyone's eyes bleed:
<button onclick="restyle()">Click me to see some results</button>
<p id="changeable">Text that will change.</p>
<script>
function restyle() {
var element = document.getElementById("changeable");
element.style.fontsize(7);
element.style.fontcolor("red");
element.innerHTML = "changed text";
}
</script>
I'm still learning Javascript too, so if there are any experts out there I'd love to hear what they think! :)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p id="style-target">This is the element which will change.</p>
<button id="change-styles">Change Styles</button>
<script>
window.onload = function () {
var changeStyles = query("#change-styles");
var target = query("#style-target");
changeStyles.onclick = function () {
style(target, "fontSize", "18px");
style(target, "color", "blue");
style(target, "fontWeight", "bold");
};
};
function style (el, property, value) {
el.style[property] = value;
}
function query (selector) {
return document.querySelector(selector);
}
</script>
</body>
</html>
Have a look;
I've taken the liberty of adding the rest of the "required" HTML bits and pieces, there (especially the DOCTYPE). You don't need to know what it's there for, right now, but it will solve a lot of problems in the future, if you always include it at the top of every HTML page you write, if you intend real people to use that page (basically, it makes Internet Explorer < IE10 suck less).
I've broken this down into bits that are a little more sensible, in terms of real-world JavaScript.
In most programming languages, you want to break your code down into smaller bits, to make it easier to read and work with.
JavaScript isn't really much different.
I have broken apart apart the act of setting the style, into its own helper function
el.style.color = "purple"; // takes `el` and makes an el{color:purple} rule
The catch here is that any CSS "style" that has a hyphen ("font-size", "background-color") needs to use camelCase, when setting the value in JavaScript.
el.style.backgroundColor = "black";
I've created a helper function called style, which I then refer to inside of my window.onload code.
In this particular case, I'm not saving a lot, in terms of what I'm typing (in fact, I'm typing more), but what it would be saving me, in a more complex case, is the chance of missing something, in repeating myself, or in copy/pasting...
So by calling style(el, "fontWeight", "bold"); I don't have to remember how to set the style for old-browsers, versus new browsers, versus styles that have been set using JS earlier on, versus those that haven't (a topic for people concerned with professional websites that have to work on ancient browsers).
If you look inside of the definition for style that I wrote, you'll see that I'm calling el.style[property]; normally, when we know the name of the thing we're looking for, on an object, we use a dot to separate them person.name; //"Bob".
In circumstances where we might want to look for different properties, we use [<property-name>] to separate them.
var property = "age";
person[property]; // 32
Next, I am using document.querySelector( selector ); to find the elements that I want, by passing it a CSS-style selector.
document.querySelector works on practically all browsers made in the past 6 years.
I'm grabbing the element I want to change the styles of, and I'm grabbing the element I'm listening to (waiting for a user to click).
Then I'm setting the onclick of the button to a function which will fire off a bunch of changes that I specify.
In this case, the onclick will change some styles.
You don't typically want to use onclick or similar properties; normally, you want to use a process called event-registration or "listening", but that goes a little too far, for such a simple example.
For now, grab the elements, separate your "how you do it" implementation details from "when 'X' do 'Y'" runtime details, and watch magic happen.
Funny enough, this isn't much more code than the jQuery suggestion provided in another answer...
...but that's a whole, gigantic library that you'd have to load (if you were even allowed), just to select a thing and change its styles.
Also, by using the "jQuery solution" to common problems, you frequently learn bad habits, or alternatively, don't learn good habits which you would need to learn, had you not had the quick and easy solution in front of you.
jQuery, as used by most people, is particularly bad about reference-caching (or a lack thereof). If widely used jQuery patterns are employed on a production website, without thought put into them (especially if you're not using jQuery, but some other library like it), you can murder your website's performance.
Try this instead that js code:
var sstyle = 'text';
function DoAll() {
var elem = document.getEelementById(sstyle);
elem.style.fontSize = "7px";
elem.style.color= "red";
}
I think you should do it like this:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<p id ='text'>I am going to change this text, I hope.</p>
<div>
<button id="jschange" onclick="DoAll()">Style</button>
</div>
<script>
function DoAll() {
$('#text').css('font-size', '7').css('color', 'red');
}
</script>
</body>
</html>
You can try this:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to display a string in a specified size.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
var str = "Hello World!";
var result = str.fontsize(7);
document.getElementById("demo").innerHTML = result;
}
</script>
</body>
</html>
Sounds simple, huh. Lot's of answers i found but all use jQuery or ProtoType. I want plain JavaScript. It shouldn't be that hard, but JavaScript is not my thing; no central documentation means searching for ages and not finding what i want.
Consider the following HTML code snippet:
<div class="central_0"> .. </div>
<div class="central_1"> .. </div>
<div class="central_2"> .. </div>
Now I want to use JavaScript to do things with those DIVs.
function processDivElements()
{
// search for relevant DIV classes
var divArray = document.getElementsByClass.regex('/^central_.*$/');
// do stuff with the DIV elements found
foreach (divArray as divElement)
{
divElement.style.background = '#f00';
};
}
Can anyone help me translate this to proper plain JavaScript? I use classes, not IDs. I prefer using a regular expression.
The jQuery solution is really nice:
var $divs = $('div[class^="central_"]');
If you only want to support newer browsers, you can use document.querySelectorAll() to do essentially the same thing:
var divs = document.querySelectorAll('div[class^="central_"]');
If you want to support older browsers, the code gets horrible:
var all_divs = document.getElementsByTagName('div');
var divs = [];
for (var i = 0; i < all_divs.length; i++) {
var div = all_divs[i];
if (div.className.match(/^central_\d+$/) {
divs.push(div);
}
}
Also:
I use classes, not IDs. I prefer using a regular expression.
Your classes are unique and are really functioning like IDs, which isn't really the intended use of classes. Structure your HTML like this instead:
<div id="central_0" class="central">...</div>
<div id="central_1" class="central">...</div>
<div id="central_2" class="central">...</div>
Now, the JavaScript becomes simpler:
var $divs = $('.central'); // jQuery
var divs = document.querySelectorAll('.central'); // Newer browsers
var divs = document.getElementsByClassName('central'); // Older browsers
As the others have mentioned you can't directly support a regex select on the getElementsByClassName method call.
But I will point out these other issues with your code, since you are new to javascript.
Using classes is fine, but your making more work for yourself by writing up your html like that.
Instead of the central_0....central_2 if they are all basically operating on the same css rules, you should write them like this central zero....central two then your central class can have identical rules, while you can assign any differences to the # classes. This way your also adhering to the DRY principle.
Also you should really consider sticking to the best practices for the language. If your not assigning css rules to your elements with those classes then you should be using id's, plus it makes your life much easier.
There is no way to get the matched elements by regex directly, the only thing you could do is to get all the elements by something (like: TagName, Name, etc..) and then filter the elements by regex.
With your html sample, you could only get all the element by TagName, and use regex to check the className by regex.
One quicker way to do so is to create a simple <style> as follows:
<style>
div[class^="central_"] {
background-color: #f00;
}
</style>
Therefore, as you look for plain javascript, useless to say that you can add <style> tags at will, by using javascript. A whole HTML example as follows:
<html>
<head>
</head>
<body>
<div class= "central_1">
central 1
</div>
<script>
var css = "<style>div[class^=\"central_\"] {background-color: #f00;}</style>";
var list = document.querySelector("head"); list.innerHTML += css;
</script>
</body>
</html>
I have been looking with no success to see if I can dynamically apply a css style to JSF component or div using javascript. Is this possible.
This is pseudo code
<div style="myJSStyleFunction("#{myBean.value}")"> stuff </div>
And the function would return something like "position:relative;left:25px;"
I've had no luck and maybe it can't be done but would like a second opinion.
Edit:
I'm trying to see if I can keep a separation / reduce the coupling between the presentation/view and the model/controller. This is for indenting commenting or product reviews (to nest replies to comments or reviews). The most I really want to track is an integer on how deep a reply is. First level = 0 second level = 1, and so on. So a comment or product review would be 0 deep, a reply to the comment or review would be 1 and so on.
Then in the EL I wanted to call a javascript function and do something like
<script>
myJSStyleFunction(depth){
if(depth<=5){
var nest=20*depth;
var style="position:relative;left:" + nest + "px;";
return style;
}
}
</script>
And then then say for a third level comment (a reply to a reply) it would look like this:
<div style="position:relative;left:40px;"> stuff </div>
where
#{myBean.value}
evaluates to 2
I suspect like Daniel says I'll have to tightly couple the view but I'd rather not have to. I'd think there has to be a way. But maybe not.
I don't know where there are cleaner solutions for this. However this is one suggestion.
Assume your page looks like below and myBean.getValue() method returns an integer.
<h:form id="frm">
<div style="#{myBean.value}"> div1 </div>
<div style="#{myBean.value}"> div2 </div>
</h:form>
So you can do something like this at 'window.onload'.
<head>
<script>
window.onload = function() {
var childList = document.forms['frm'].childNodes;
for(var i = 0; i < childList.length; i++) {
if(childList[i].nodeName == 'DIV') {
var _div = childList[i];
var depth = _div.getAttribute('style');
_div.setAttribute('style', 'position:relative;left:' +(depth *20)+ 'px;');
}
}
}
</script>
</head>
Note: 1. In above sample code I assume all the DIVs inside the form should be indented.
2. For IE you may need to use _div.style.setAttribute('cssText','position:relative;left:' +(depth *20)+ 'px;')
3. Another solution for your question is using <script> tags immediately after your divs and putting the js part inside them. In this way you don't have to use fake styling style="#{myBean.value}" or window.onload event because you can directly call #{myBean.value} in your script.
I decided to skip the javascript approach and settled on a simpler and I think cleaner method to create the dynamic css classes for my situation. I already capture/calculate the depth value for each comment when it is entered. So I am just returning that value in EL and concatenating it to a 'base name' for the css class like so:
<div class="indent_#{(comment.commentDepth le 5) ? comment.commentDepth : 5}" >
comment comment blah blah blah
</div>
"indent_" is the base name for the css class. So for a 0 level comment it will have a class="indent_0". A reply to that comment will have class="indent_1".
I use the ternary so that if there are lot of replies under a given comment it doesn't indent right off the right hand side of the page. Even though you can keep going deeper, it will only indent up to 5 levels.
For my case at the moment, this is a simpler and cleaner method of adding some dynamically generated css class names. Right now I have to define 6 classes for this in the css file, but perhaps I'll figure out how to nest the boxes but it isn't a priority this works just fine for me for now.
Is there any way you can set an element to be a master and have all other elements on a page appear and behave in exactly the same, same style, same code, same attributes, same values?
<input id="btnBack" name="btnBack" type="button" value="Back" disabled="disabled" style="margin-right: 10px" />
$('#btnBack').click(...do stuff);
<input master="btnBack" />
Or failing this is there any technique to concisely achieve the same result?
I'm half expecting there to be a Javascript library out there that copies all the attributes.
Same style = css
Same attributes, values, etc = JS
See this fiddle for an example to get you started or this code snippet...
The CSS
input {
width: 200px;
background-color: yellow;
}
The JS
var value = 'myval';
var disabled = 'disabled';
var myElements = document.getElementsByTagName('input');
for(var i = 0; i < myElements.length; i++){
myElements[i].value = value;
myElements[i].disabled = disabled;
}
Yes with CSS classes. Create a master class and then use the class="master" on all your elements.
However I think you'll find you don't really want to do this once you get into it. But it will be easy to change the class on the elements you want to change so it won't hurt you to get started this way.
You can read about CSS here: http://www.w3schools.com/css/ though there are better resources w3schools covers a lot of ground.
If you're interested in building a consistent feel to a site and don't mind using jquery (which I love!) then you should checkout the jquery UI themeroller:
http://jqueryui.com/themeroller/
I don't know if this is what you're referring to, but best bet is use a class on all the elements you want to style and behave the same.
E.g.
File: index.html
Awesome Link
<button class="master-class">Awesome Button</a>
File: style.css
.master-class {
color: black;
background: white;
more of your styles...
}
File: scripts.js
$(function() {
$(".master-class").click(function() {
alert("This is from one of the many elements with the class 'master-class'");
});
});
Team Treehouse is a great place to really learn all about everything web. I've been using them for a while even though I knew most of the stuff on there, but I always pick up a few new things. http://teamtreehouse.com/
W3Schools ( http://www.w3schools.com ) is also great. It's where I learnt a lot of stuff in the beginning.
There is also a large amount of podcasts and vodcasts out there to teach you too, just search iTunes for web design.
So I am trying to learn javascript. I've gone through a few tutorials and guides, however often they don't teach you how to write javascript to work with web pages.
What I want to learn how to do is provide some basic interactivity with websites I've been making recently. While they contain dynamic content, I still would like some of the interactivity of javascript. All of my attempts have been futile, however, as nothing works. My end goal is to get my websites feeling more professional, and maybe also get a node.js server up and running with some ajax or websockets going to perhaps build a 2d game with canvas, but that is much much later.
The following code is some basic things I've written based on some HTML DOM tutorials I've read. The problem is it doesn't work at all. So can anyone tell me what is going on here, about why it doesn't work at all. And yes, I do have javascript turned on in my browser.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>SomeText</p>
<script type="text/javascript">
var ptag = document.getElementById('p');
function alertclick() {
alert(this);
}
for (i = 0; i < ptag.length; i++){
var attach = ptag[i];
attach.addEventListener("click", alertclick, false);
}
</script>
</body>
</html>
That's because you're using getElementById and the is no element with the id p. Instead use getElementsByTagName to get all p elements.
var ptags = document.getElementsByTagName('p');
for (var i = 0; i < ptags.length; i++){
var element = ptags[i];
element.addEventListener("click", alertclick, false);
}
Have some confidence! You are almost there. This is the behavior I understood you want: click on a paragraph to alert its contents.
We like showing a working demo in both questions and answers: http://jsfiddle.net/bxvny/
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>SomeText</p>
<p>SomeText2</p>
<p>SomeText3</p>
<script type="text/javascript">
var ptag = document.getElementsByTagName('p');
function alertclick() {
alert(this.innerHTML);
}
for (i = 0; i < ptag.length; i++){
var attach = ptag[i];
attach.addEventListener("click", alertclick, false);
}
</script>
</body>
</html>
There's a few things that will catch you out as a beginner.
When the JavaScript runs before the page has loaded.
The order in which you include JavaScript files in the page is important.
The number of ways in which you can do something.
Plain JavaScript:
In your code i'm assuming that you're trying to access all <p> tags, you can use getElemenysByTagName('p').
If you would like to access a single element I recommend assigning an ID to it as so <p id="me">SomeText</p> and then use getElementsById('me').
If you wan't to access a set of elements, but not all of a certain type you should apply a class <p class="group">SomeText</p>... you can use getElementsByClassName('group') but it's only supported in more modern browsers.
For Selection of elements I strongly recommend using jQuery, it makes the process much easier and more flexible. http://jquery.com/
jQuery:
Once using jQuery you can access elements as so:
$('#me'); //Individual Element by ID
$('.group'); //Group of elements by Class
$('<p>'); //All P elements
jQuery is also very good when creating event handlers because of it's simplicity and cross-browser compatibility. For your onClick:
http://api.jquery.com/click/