Problems getting even basic javascript to work [noob here] - javascript

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/

Related

Losing a node reference? (javascript)

So I have this JS code :
var pElt = document.createElement("p");
var aElt = document.createElement("a");
aElt.textContent = "Text";
aElt.href = "#";
pElt.appendChild(aElt);
aElt.style.color = "red";
pElt.innerHTML += "<span> and more text</span>";
//aElt.style.color = "red";
document.getElementById("content").appendChild(pElt);
console.log(aElt); // always show the red attribute
There's probably some answer around here, but I cannot even describe the problem ; so I went with "losing node reference", even though it's not what happens here. (edit: in fact, that's what happens here, silly :))
So... Please try the code as it is. It works, the link is red, everyone is happy. Now comment the "aElt.style.color = "red";" line, then uncomment the other one, two lines below.
...
It does not work, the link still appear in black. What I thought is that the pointer linked to my node was either not valid anymore or the aElt was moved to a different memory address. But when I type "console.log(aElt)", it outputs the node correctly (well... I think it does), so I don't get why I can't access it after the .innerHTML change.
What interests me is what happens under the hood :)
Thanks!
index.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Question!</title>
</head>
<body>
<div id="content"></div>
<script src="script.js"></script>
</body>
</html>
When you overwrite the content of the <p> element by setting it's innerHTML, you're effectively turning the <a> back into HTML text, appending the <span> (as text), and then recreating new DOM nodes in the <p>. Your old reference still refers to the original <a> you created.
You could instead create that <span> the same way you created the <a>, and append that node to the <p> instead of overwriting .innerHTML.

font,font size, and color change javascript

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>

Deleting and inserting Code in a DIV via jQuery

I know this has been adressed before, but I can't seem to get it working for me.
I am trying to create a football pitch with editable players via HTML/JavaScript/jQuery.
I can produce the field the first time when loading the page without any problems. The code looks like this:
<div id="pitch" class="updateAble">
<script type="text/javascript">
appBuilder(team1, team2);
</script></div>
appBuilder() looks like this:
var appBuilder = function (team1, team2) {
team1.Display();
team2.Display(); }
It simply creates the players on the pitch for both teams. As it does. I now want to push an input-button to call a function appUpdate(), which deletes the content of #pitch and puts the appBuilder()-part in again as to renew it (if I changed or added players):
var appUpdate = function () {
var newContent = "<script type='text/javascript'>appBuilder(team1, team2);</script>";
var updateItem = $('#pitch');
updateItem.empty();
updateItem.append(newContent);}
Here is what drives me nuts: It seems to work just fine up to and including the empty()-function. So the code has to be fine.
But when I try to append newContent to the #pitch-DIV, the programm seems to completely delete everything inside <head> and <body> it recreates a clean html-file (with empty html-, head-, body-tags) and inserts my players inside <body>.
Any ideas as to why it is doing that?
Thanks in advance!
UPADTE: The solution was a rookie mistake (which is fitting, since I'm a rookie). The Team.Display()-method was trying to do a document.write() call. As I learned: If you call document.write once the document is fully loaded, it will delete your site. Thanks to jfriend for the solution! :)
If you call document.write() AFTER the document has finished loading, then it will clear the current document and create a new empty one.
What you need to do is use DOM insertion operations rather than document.write() to add/change content in the DOM once the document has already loaded.
My guess is that the .Display() method is using document.write() and you need to change the way it works to insert content into a parent node rather than write it into the current position.
Some ways to insert content:
var newNode = document.createElement("div");
node.appendChild(newNode);
node.innerHTML = "<div>My Content</div>";
Or, if you're using jQuery, you can use it's wrappers for this:
obj.append("<div>My Content</div>");
obj.html("<div>My Content</div>");
.html() would empty and fill the div at once. Have you tried that ?
updateItem.html(newContent);
I proposed a JQuery replacement for your code that does what you want, ion the style of your own typing.
Note that I kept the .html() call to mimic your "empty()" function, but it is not necessary. Simply put he code in the append, straight into the html() et get rid of the extra unnecessary remaing bit of code.
My code replacement, as a 100% functioning .html file. Hope it helps, cheers.
<html>
<header>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
var appBuilder = function (team1, team2) {
//team1.Display();
//team2.Display();
}
var team1, team2;
</script>
</header>
<body>
<div id="pitch" class="updateAble">
<script type="text/javascript">
appBuilder(team1, team2); // Original code to be updated
</script>
</div>
<script>
var appUpdate = function () {
$("#pitch").html("<!-- Old javscript code has been flushed -->").append($("<script />", {
html: "appBuilder(team1, team2); // brand new, replaced code"
}));
}
appUpdate();
</script>
</body>
</html>

Changing paragraph style using childNodes in JavaScript

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.

Search for div classes with regex

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>

Categories

Resources