Manipulating DOM with (framework-less) javascript - javascript

Ok, I haven't been using JavaScript without JQuery for quite some time now... But, as coding goes, I have to do without it's power for a project where I can't be sure that JQuery is provided.
The thing I'm trying to do would be the following using JQuery:
$(document).ready(function() {
$('#myDiv').append('<ul><li>a</li><li>b</li></ul>');
});
Now to the non-jquery thing, this is what I have and I really can't understand why it isn't working:
<html>
<head>
<script type="text/javascript">
function load() {
var s = '<ul><li>a</li><li>b</li></ul>';
var element = document.getElementById("myDiv");
element.innerHtml += s;
}
</script>
</head>
<body onload="load()">
<div id="myDiv"></div>
</body>
</html>
Thing is, nothing happens (the function gets called though). Could it be that the DOM isn't ready when load() is called?. I vaguely remember this code working in the firefox 2.x IE7 era ...
What would be the (a) right solution?

It's innerHTML not innerHtml. Notice the upper case HTML. Change that and it should work fine! Here's a working example.
By using innerHtml you are simply creating a new property on the element object and giving it the value of s.

<html>
<head>
<script type="text/javascript">
function load() {
var s = '<ul><li>a</li><li>b</li></ul>';
var element = document.getElementById("myDiv");
element.innerHTML += s;
}
</script>
</head>
<body onload="load()">
<div id="myDiv"></div>
</body>
</html>
JS is case sensitive

I think you want element.innerHTML += s;.

Related

Neither jQuery's .text() nor JavaScripts .innerText works?

I'm currently trying to animate some text on my website and set up a little test website to fiddle around with.
This is what my test website looks like:
<head>
<title>Test</title>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
//What I tried with jQuery
console.log("Content: " + $('p').text());
//What I tried with JavaScript
var text = document.getElementsByClassName('test').item(0);
console.log(text.innerText);
//This returns the HTMLCollection object, text[0] is undefined
var text = document.getElementsByClassName('test');
console.log(text);
</script>
</head>
<body>
<p class="test">Hello World!</p>
</body>
//What I tried with jQuery
console.log("Content: " + $('p').text());
//What I tried with JavaScript
var text = document.getElementsByClassName('test').item(0);
console.log(text.innerText);
//This returns the HTMLCollection object, text[0] is undefined
var text = document.getElementsByClassName('test');
console.log(text);
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<p class="test">Hello World!</p>
Here I'm already trying to use jQuery instead of JavaScript, because it seemed to be easier to use. But if I visit my website (locally) it only prints Content: inside the console (JavaScripts .innerText would return undefined).
If it is important: I'm using Ubuntu 19.10 to develop and test my website.
You need to wait for the page to load (DOM) before the script runs. As I see it now, your script runs before the paragraph (<p>) element is created.
You can either:
1) Make it so that the code runs once the page has loaded. (recommended) ... or
2) Move the script after the paragraph (<p>) tag.
Method 1
// jQuery
$(document).ready(function() {
console.log("Content: " + $('p').text());
});
// JavaScript
document.addEventListener("DOMContentLoaded", function(){
// Handler when the DOM is fully loaded
var text = document.getElementsByClassName('test').item(0);
console.log(text.innerText);
});
Method 2: Please refer to #Edit's answer.
Your script needs to be at the bottom of your body. Here's the result:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<head>
<title>Test</title>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
<p class="test">Hello World!</p>
<script>
//What I tried with jQuery
console.log("Content: " + $('p').text());
//What I tried with JavaScript
var text = document.getElementsByClassName('test').item(0);
console.log(text.innerText);
//This returns the HTMLCollection object, text[0] is undefined
var text = document.getElementsByClassName('test');
console.log(text);
</script>
</body>

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/

Javascript: Can't get element using getElementById [duplicate]

This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 6 years ago.
Ok. I need fresh eyes because I'm still on this s***d problem for one hour!
Here is my simple HTML code (testssio.html) that include javascript script:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var ssio = document.getElementById('ssio');
ssio.html = "it finally works!";
</script>
</head>
<body>
<div id="ssio"></div>
</body>
</html>
But it doesn't work! Using the debugger, I get:
Uncaught TypeError: Cannot set property 'html' of null /testssio/:6
Does anyone get it? I know it's not the correct place to look for debugging help, but I'll be crazy if I don't get it! So please, any help?
Tahnks in advance.
The reason for this is that scripts in the head load before the page is rendered. This means your content is not yet rendered and therefore not a part of document.
If you want to see this work, try moving your script below the element renders, like this:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="ssio"></div>
<script type="text/javascript">
var ssio = document.getElementById('ssio');
ssio.innerHTML = "it finally works!";
</script>
</body>
</html>
A more standardized way of doing this is with events. Many people use jQuery but it can be done with plain js. This would mean changing your script like this:
<script type="text/javascript">
function WinLoad() {
var ssio = document.getElementById('ssio');
ssio.innerHTML = "It finally works!";
}
window.onload = WinLoad;
</script>
This way you can still leave it in the <head>.
Also, using .html is from jQuery. It is generally used as .html(content). If you want to use the plain javascript version use .innerHTML = content.
I mention jQuery so much because it is a highly used API. This quote is from their site:
jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.
Your code is running too early before the DOM is loaded and thus document.getElementById() doesn't find the element in the document yet.
You can either move your script tag down to right before the </body> tag or you can wait for the DOM to load before running your code with either the window onload event or a DOMReady event.
There are two errors here. First, you need to put the SCRIPT tag after the element. Second, it's not .html, but .innerHTML. So here is the corrected code:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="ssio"></div>
<script type="text/javascript">
var ssio = document.getElementById('ssio');
ssio.innerHTML = "it finally works!";
</script>
</body>
</html>
you can use something like this
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
document.onload= function(){
var ssio = document.getElementById('ssio');
ssio.html = "it finally works!";
}
</script>
</head>
<body>
<div id="ssio"></div>

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