JQuery $('#id") does not work - javascript

I'm a noob in JQuery, trying my hands on the basic functionality of it
I have a html, like below.
<html>
<head>
<script type="text/javascript" charset="utf-8" src="js/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="js/start.js"></script>
<script>
$(mainFunction());
$('#label1').prop('innerHTML', "test");
</script>
<title></title>
</head>
<body>
<label id="label1"></label>
</body>
</html>
From start.js, i'm trying to manipulate the elements in this html file like below.
function start(name){
this.iam = name;
this.getName = function(user){
return this.iam;
}
}
function mainFunction(){
var label = $('#label1');
var oStart = new start("test");
label.prop("innerHTML" ,oStart.getName("test"));
}
When I try to lookup whats in the 'label' in the above code, i get [] printed on the console. What am I doing wrong here?

$(mainFunction()); is your issue. Instead provide function reference to document.ready.
Like this:
$(mainFunction);
While doing $(mainFunction()); you are invoking the function mainFunction while setting up the handler, which means it gets executed too early before the DOM tree has been constructed.
Or in order to avoid confusion you could do:
$(function(){
mainFunction();
});
Also remember that this issue will not happen if you move your script just before the end of the body tag. You do not have to listen to document ready handler. Plus as a shorthand you could just do label.html(oStart.getName("test"));

You need to wait for the DOM to be ready before using jQuery.
This is done this way:
$(document).ready(function() {
// All your code touching the DOM in here
});
Also note that this line: $(mainFunction()); uses the return value of mainFunction, it does not trigger it when DOM is ready.

Related

Why use window.onload

I have tried finding an answer to this on my own, but only found instructions on how to use onload events. I seem to be missing the point.
I've been taught that if I want something to happen when the page loads, I should use window.onload like this:
<script>
window.onload = dosomething();
function dosomething()
{
window.alert('hello');
}
</script>
But now that I am thinking on my own I wonder what the point of doing that is. Because this also produces the same result:
<script>
dosomething();
function dosomething()
{
window.alert('hello');
}
</script>
Anything I put at the top inside <script> is going to execute anyway... so what's the point of window.onload?
If you're directly running your code with dosomething();, you're delaying your browser's rendering for the time it takes your JavaScript code to run.
You can try to insert your code to the <head> of your html document:
<!DOCTYPE html>
<html>
<head>
<script>
dosomething();
function dosomething()
{
window.alert('hello');
}
</script>
</head>
<body>
Does not render before the alert is dismissed!
</body>
</html>
You'll see that the page stays blank until you dismiss the alert. So every second the browser takes to run your JavaScript code is a second that your users have to wait for the site to be rendered.
Now if you change the code to be run on body's onload, the page gets rendered before the alert is shown:
<!doctype html>
<html>
<head>
<script>
function dosomething()
{
window.alert('hello');
}
</script>
</head>
<body onload="dosomething()">
This page gets rendered before the alert!
</body>
</html>
Consider these two blocks of code:
<head>
<script>
alert(document.getElementById('foo').value);
</script>
</head>
<body>
<input id="foo" value="hello">
</body>
<head>
<script>
window.onload = function() {
alert(document.getElementById('foo').value);
}
</script>
</head>
<body>
<input id="foo" value="hello">
</body>
In the first example, we'll get an error because the element you are referencing isn't found when the script runs - and so you are trying to get value of null.
In the second example, document.getElementById() will find the element with the id foo, because window.onload will get fired only when the complete DOM has been loaded and so the element is available.
window.onload will fire once the DOM has finished loading. In your example, the DOM is not required. However, the following code will fail if the DOM has not yet loaded:
function doSomething() {
alert(document.getElementById('test').innerText);
}
// Throws: TypeError: Cannot read property 'innerText' of null
Assuming your page contains an element with id test, it will alert its text.
waiting for the onload event assures you that all of your scripts and resources are loaded
Assume you are using jquery in your page and you invoked a function that uses it directly without onload , you can't guarantee that the jquery file has been loaded, which will lead to errors and possibly ruining your whole logic
The onload event is handy to make sure the page is fully loaded before you run a script. For your example above it doesn't make sense, but if your page is still loading an item on the bottom and you try to call it then nothing will run.
I recommend using jQuery and using the ready function. This way you will ensure your page is completely loaded.
$( document ).ready(function() {
// This will only run after the whole page is loaded.
});
If you don't want to load query, just put your javascript at the bottom of the page. It's best practice, and ensures the DOM is loaded in full.
For more info on the jquery ready function go here: https://api.jquery.com/ready/

Getting entire HTML in JavaScript

I'm trying to get the entire HTML of a page, but it seems that the text stops after </head>. The following code is essentially how I tested this. What am I doing incorrectly here?
<html>
<head>
<script>
document.onload = showHTML();
function showHTML() {
html = document.documentElement.innerHTML;
alert(html);
}
</script>
</head>
<body>
<p> This is absolutely useless text. </p>
</body>
</html>
Okay here is a complete working answer... after checking already posted answer I realized it didn't work for multiple reasons..
First you need to put a function in the onload event. The onload event is written without uppercases.
Also! you need to put the event on the window object as such:
window.onload = showHTML;
Here is a fiddle. Notice on the left that it isn't wrapped inside onload. It's unwrapped in head like your code should be.
http://jsfiddle.net/4zsGH/2/
You should have something like this:
<html>
<head>
<script>
window.onload = showHTML;
function showHTML() {
var html = document.documentElement.outerHTML;
alert(html);
}
</script>
</head>
<body>
<p> This is absolutely useless text. </p>
</body>
</html>
Take off the parenthesis from document.onLoad = showHTML();
What's happening is showHTML() is being called right away, before the rest of the document is being loaded. Taking off the parenthesis means the function is being set to the onLoad callback.
Try:
<html>
<head>
<script>
document.onload = showHTML;
function showHTML() {
var html = document.documentElement.outerHTML;
alert(html);
}
</script>
</head>
<body>
<p> This is absolutely useless text. </p>
</body>
</html>
When you wrote document.onLoad = showHTML(); you didn't assign the reference to showHTML function to document.onLoad but you assigned the value returned by that function i.e. undefined (because you called it). I also changed innerHTML to outerHTML.
Also document.onload shouldn't be written in camel case.
Writing var html = … isn't essential but it wouldn't run in strict mode. Without it you create a html property on global object window implicitly.
I think this is what you are looking for:
document.onLoad = showHTML();
function showHTML() {
var html = document.documentElement.innerHTML;
alert(html);
}
http://jsfiddle.net/skhan/4zsGH/

Using document.getElementById() inside object, works in JSFiddle, TypeError in actual. Why?

I have a code that works in JSFiddle but doesn't work when I save the HTML+JS locally and test it locally. I can't figure out what's wrong with the code. Here is my JSFiddle
http://jsfiddle.net/LLUAB/
And here is the actual code, not very long
<!doctype html>
<html>
<head>
<script type="text/javascript" language="Javascript">
function Composer(foobox) {
this.foobox = document.getElementById(foobox);
this.foobox.onkeydown = function(){window.alert("hello")};
}
var myComposer = new Composer("foo");
</script>
</head>
<body>
<textarea id="foo"></textarea>
</body>
</html>
Because in JSFiddle your script is placed inside window.onLoad event handler by default. While in your case getElementById() method is unable to find not yet loaded element.
Put all your script right before closing </body> tag and it will work:
<script type="text/javascript">
// ...
</script>
</body>
It works in Fiddle because of onLoad option specified here. The problem is that when new Composer line is fired, there's no such element in the DOM yet. Wrap this line in DOMReady handler - or move its invokation to the end of <body> element.
It's because your dom is not ready yet
function Composer(foobox) {
this.foobox = document.getElementById(foobox);
alert(this.foobox); --Prints null
this.foobox.onkeydown = function(){window.alert("hello")};
}
Working code here. http://jsfiddle.net/LLUAB/1/

Can't access DOM element

I wrote a web application with a body onload event. I know this isn't optimal so I want to use DOMContentLoaded to trigger my init event.
I have a strange problem, I can't access my DOM element and I don't know why :/.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<div id="test">Hello World</div>
</body>
</html>
JS:
// add event listener
document.addEventListener('DOMContentLoaded', init, false);
function init () {
// pop up
alert(document.getElementById(test).innerHTML);
}
Does somebody see the problem?
You are passing the undefined variable test to the getElementById() function, instead of the string value 'test'.
So
document.getElementById(test); // Incorrect - as an undefined varible
Should in fact be
document.getElementById('test') // Correct - as a string value
Or
var element_id = 'test';
document.getElementById(element_id) // Correct - as a defined variable
Add double quotes around test i.e. "test"
document.addEventListener('DOMContentLoaded', init, false);
function init () {
// pop up
alert(document.getElementById("test").innerHTML);
}
If your init function is executed, then you might add quote arroud your id :
document.getElementById(test)
becomes
document.getElementById('test')

how does a function know where it is located in the DOM?

I'm trying to write a javascript function that adds some DOM nodes to the document in the place it was called, like this:
...
<div>
<script type="text/javascript">
pushStuffToDOMHere(args);
</script>
</div>
...
i try to do it 'cleanly', without using node id property of the div, or innerHTML string manipulation. for that I need to know where in the document the script tag is located.
is there a way to do it?
Talking about cleanly, I don't think your approach is particularly clean. It is a much better idea to give the div a unique id and execute your javascript when the DocumentReady-event fires.
Do you have an overriding reason for doing it this way? If not the suggestion to use a unique id makes the most sense. And you can always use a library like jQuery to make this even easier for yourself.
However, the following quick test shows that if you use document.write() in the function then it writes the value into the place where the function was called from.
<html>
<head>
<script type="text/javascript">
function dosomething(arg){
document.write(arg);
}
</script>
</head>
<body>
<div>The first Div</div>
<div>The
<script type="text/javascript">
dosomething("Second");
</script>
Div
</div>
<div>The
<script type="text/javascript">
dosomething("Third");
</script>
Div
</div>
</body>
</html>
But, again the question, are you sure this is what you want to do?
Although I agree with n3rd and voted him up, I understand what you are saying that you have a specific challenge where you cannot add an id to the html divisions, unless by script.
So this would be my suggestion for inlining a script aware of its place in the DOM hierarchy, in that case:
Add an id to your script tag. (Yes, script tags can have ids, too.)
ex. <script id="specialagent" type="text/javascript">
Add one line to your inline script function that gets the script element by id.
ex. this.script = document.getElementById('specialagent');
...And another that gets the script element's parentNode.
ex. var targetEl = this.script.parentNode;
Consider restructuring your function to a self-executioning function, if you can.
Ideally it executes immediately, without the necessity for an 'onload' call.
see summary example, next.
SUMMARY EXAMPLE:
<script id="specialagent" type="text/javascript">
var callMe = function(arg1,arg2,arg3) {
this.script = document.getElementById('specialagent');
var targetEl = this.script.parentNode.nodeName=="DIV" && this.script.parentNode;
//...your node manipulation here...
}('arg1','arg2','arg3');
</script>
The following TEST code, when run, proves that the function has identified its place in the DOM, and, importantly, its parentNode. The test has division nodes with an id, only for the purpose of the test. They are not necessary for the function to identify them, other than for testing.
TEST CODE:
<html>
<head>
<title>Test In place node creation with JS</title>
</head>
<body>
<div id="one">
<h2>Child of one</h2>
<div id="two">
<h2>Child of two</h2>
<script id="specialagent" type="text/javascript">
var callMe = function(arg1,arg2,arg3) {
this.script = document.getElementById('specialagent');
var targetEl = this.script.parentNode;
/*BEGIN TEST*/
alert('this.script.id: ' + this.script.id);
alert('targetEl.nodeName: ' + targetEl.nodeName + '\ntargetEl.id: '+targetEl.id);
alert('targetEl.childNodes.length: ' + targetEl.childNodes.length);
var i = 0;
while (i < targetEl.childNodes.length) {
alert('targetEl.childNodes.'+i+'.nodeName = ' + targetEl.childNodes[i].nodeName);
++i;
}
/*END TEST - delete when done*/
//...rest of your code here...to manipulate nodes
}('arg1','arg2','etc');
</script>
</div>
</div>
</body>
</html>
Not really sure what your trying to achieve but this would pass the dom element to the function when clicked. You could then use jquery in the function to do what you wanted like so
...
<script type="text/javascript">
function pushStuffToDOMHere(element)
{
$(element).append("<p>Hello</p>"); // or whatever
}
</script>
<div onclick="pushStuffToDOMHere(this);">
</div>
...
my solution is a compbination of the (good) answers posted here:
as the function is called, it will document.write a div with a unique id.
then on document.onload that div's parent node can be easily located and appended new children.
I chose this approach because some unique restrictions: I'm not allowed to touch the HTML code other than adding script elements. really, ask my boss...
another approach that later came to mind:
function whereMI(node){
return (node.nodeName=='SCRIPT')? node : whereMI(node.lastChild);
}
var scriptNode = whereMI(document);
although, this should fail when things like fireBug append themselves as the last element in the HTML node before document is done loading.

Categories

Resources