All Javascript line not executed - javascript

I have a simple html page is as-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(e) {
var s = $("#d").get(0).getElementsByTagName("a");
for(var x=0;x<s.length;x++){
document.writeln(s.length);
}
var k=document.createElement("a");
k.innerHTML="hello";
var q=document.getElementById("d");
q.appendChild(k);
});
</script>
</head>
<body>
<div id="d">
<a><img class="zzz"/></a>
<a><img class="zzz"/></a>
</div>
</body>
</html>
Javascript executes only up to for loop (element k is not appended). If for loop is removed then only element k got appended. Isn't code below for loop is supposed to be executed after for loop execution?

Welcome to StackOverflow! A few suggestions to help you as you are learning to develop:
Always use meaningful variable names, it's hard to keep track of what
single letter variables represent
Don't use document.write for
debugging, use the console for that
If you are using a library like
jQuery, try to use it as much as you can when you are beginning to
learn it. Only fall back to basic javascript if you have a compelling
reason to do so
Your function can be rewritten in pure jQuery like so:
$(function() {
var container = $('#d');
console.log(container.find('a').length);
container.append('<a>hello</a>');
});
I haven't run your code, but your error probably has to do with this statement: $("#d").get(0).getElementsByTagName("a");. The eq() method returns a jQuery object, which does not have a getElementsByTagName() method on it.
If you want a plain DOM object without the jQuery wrapper you can address the jQuery object like an array: $('#d')[0].getElementsByTagName("a");, though like I said, it's best to stick with the jQuery library if you are going to use it.
Good luck as you learn!

you can't use writeln (or write) after the document has been loaded(or I better say: you shouldn't, because it will overwrite the complete document, including #d , what will force the error, because this element isn't available anymore after the usage of writeln )
I guess you want something like this:
$(document).ready(function(e) {
$('a').prepend(function(i){return i;});
$('#d').append('hello');
});
Demo: http://jsfiddle.net/stRBU/2/

Related

How do I overwrite an entire document with JavaScript

This is not a duplicate question for these reasons:
I am asking about how to replace the entire HTML document with JavaScript without jQuery or any other fancy extensions to JavaScript. Some of the other questions that are similar to this question deal with specific things like AJAX or jQuery.
I am NOT asking about why document.write() only appends to the page. Perhaps the pure JavaScript solution I am looking for may incorporate that function, but it cannot only be that since it is inadequate by itself.
What I am looking to do is overwrite a webpage as it is displayed in the browser with only HTML. The function document.write() only appends whatever argument is passed to it to the document's body. The property document.documentElement.outerHTML can be read from, but unlike when it is used on a page's child elements, cannot be written to, and even if it could, it would leave the DOCTYPE untouched.
I am working on a bookmarklet, so this JavaScript would not run in the page, meaning there is no problem with the script being overwritten while it is running. It could also be run in the browser's developer tools.
As an example, suppose I have about:blank opened in my browser. The contents of the DOM would look like this:
<html>
<head></head>
<body></body>
</html>
I want to be able to overwrite it with whatever string I want. So, for instance, I could make it look like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example</title>
</head>
<body>
<p>This is an example.</p>
</body>
</html>
How can I achieve that sort of overwrite of a document?
Try this:
function one() {
document.write('<html><body><pre>the first html</pre></body></html>');
document.close(); // this makes the difference
}
function two() {
document.write('<html><body><pre>the second html</pre></body></html>');
document.close();
}
Refer to linstantnoodles' answer in question document.write() overwriting the document?, the document.open is implicitly called before the document.write is called, but the document.close doesn't, and
document.write() when document is closed = rewrite the document;
document.write() when document is open = append to the document.
You can use document.implementation.createDocumentType to rewrite the doctype and document.getElementsByTagName to get the DOM elements, then rewrite with innerHTML and setAttribute.
var newDoctype = document.implementation.createDocumentType('html','-//W3C//DTD XHTML 1.0 Transitional//EN','http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtdd');
document.doctype.parentNode.replaceChild(newDoctype,document.doctype);
document.getElementsByTagName('html')[0].setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
var doc = document.getElementsByTagName('html')[0];
doc.getElementsByTagName('head')[0].innerHTML = '<title>Example</title>';
doc.getElementsByTagName('body')[0].innerHTML = '<p>This is an example.</p>';
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>
Edit:
Updated to include comments by Xweque and xmlns attribute.
document.write('Some Text')
document.write rewrites the page's code.

Why isn't this javascript node traversal working?

I'm primarily a C#, Java, PHP Developer; associated databases encapsulated. Seemingly irrelevant, but a valid precursor to the statement that I feel like I'm 15 again; glaring at this... disappointingly simple javascript, that doesn't seem to be turning up anything for me.
My intention here is to loop through the nodes in my current document, evaluate their attributes, and perform actions on particular nodes. My code is as follows ( again... so simple I feel like a dunce ), but the output is rather inconsistent.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
function TraverseDocument()
{
var Root = document.documentElement;
for( Element in Root.childNodes )
{
document.writeln(Element);
}
}
</script>
</head>
<body onLoad="javascript: TraverseDocument();">
<div id="test" testAttr="testData">
</div>
</body>
</html>
Now; consider that this is just my fifth pass at this ( tutorials, examples, etc ), and I've tried a few permutations on this code:
// document.writeln(Element.nodeType);
// document.writeln(Element.nodeName);
// document.writeln(Element.nodeValue);
All of which come up short; displaying 'undefined'. The current code ( as shown in my first code block ) outputs the following:
0 1 2 length item
Can anyone point me at where I'm going wrong here? Rookie question; but one that I still can't manage to put my finger on. Thanks ahead of time.
Simple enough, the for loop you've written iterates the properties of the object, rather than the items in the array, what you probably want is actually:
function TraverseDocument()
{
var Root = document.documentElement;
for(var i = 0; i < Root.childNodes.length; i++ )
{
document.writeln(Root.childNodes[i]);
}
}

How to think of Javascript-is this accurate?

I'm working through some javascript examples, and I just did this one:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Page title</title>
<script type="text/javascript">
function displayText()
{
document.getElementById('targetDIV').innerHTML = "You're using Javascript";
}
</script>
</head>
<body onload="displayText()">
<h2>This should be before the other text.</h2>
<div id="targetDIV">
</div>
</body>
</html>
OK. Very basic, I know-but I realized I was confused about the "why" of some things. Could it be accurate to say that:
Function=WHAT will happen.
The call (the body onload...)= WHEN it will happen.
and div id="targetDIV" = WHERE it will happen
I know this is the case in this example, but in general is that the way things work in Javascript?
Yes, that's a pretty good working model to carry in your head.
onload for the body is called an Event and many objects issue events. Your function displayText is called in response to the onload Event and is therefore an event handler.
The code inside your function can do anything, but in this case it dynamically loads some text into a tag on your page.
There are a couple of other things worth pointing out at this point. You access the tag using document.getElementById. document is variable available to you in Javascript which contains a model of the page called the DOM or document object model. This is extremely powerful as it presents a hierarchical layout of everything on your page and allows you to manipulate the contents.
getElementById() is a very useful function which searches the DOM tree and returns the object which has the ID that you specify, it's a sort of search. The text gets to your tag because you added the targetDIV id to the DIV tag and therefore you could find it via the DOM function.
Welcome to programming in Javascript. Now you have a goood working model you'll find loads of really clever things you can do and your life as a web programmer will never be the same again.
Sound good to me.

How to get scripts to fire that are embedded in content retrieved via the jquery load() method?

I have found several other questions here on S.O. (and the web in general) that ask roughly this same question, but the answers always seem to suggest other ways of structuring code that avoid the need for addressing this underlying issue.
For example, many people suggest (and a good suggestion, I agree) to put your code in the jquery load method's callback, on the calling page and not the called page. However I have unique scripts that may appear in certain resources, so I would not want to do that for every load and nor do I necessarily know what these scripts will be.
Here is a test setup to demonstrate what I'm trying to do. The short summary is that when I load partial.htm from main.htm, its script does not fire.
main.htm:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>main file</title>
</head>
<body>
<ul id="links">
<li>some page1</li>
<li>some page 2</li>
<li>some other partial page</li>
</ul>
<div id="panel" style="display:none; padding:20px; background-color:#CCC;">
LOADED CONTENT WILL GO HERE
</div>
<script type="text/javascript" src="/path/to/jquery-1.3.2.min.js"> </script>
<script type="text/javascript">
$(function(){
$('#links a').click(function() {
var $panel = $('#panel');
$panel.show();
$panel.html('Please wait...');
var href = $(this).attr('href');
$('#panel').load(href + ' #content');
return false;
});
});
</script>
</body>
</html>
OK, very simple functionality on this page. Imagine there are many more links, and some of them may require scripting while others do not.
Here is partial.htm:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>partial file</title>
</head>
<body>
<div id="content">
<p>Hey, I am the partial file!</p>
<script type="text/javascript">
alert('I am some JS in the partial file! But sadly I do not execute...');
</script>
</div>
<div>
I am some other content on the page that won't be included by jquery.load()...
</div>
</body>
</html>
Notice that my script in partial.htm does not fire. So, my question remains: how to get this to fire, excluding any answers that tell me to put this in the .load() method's callback. (This would be because I may not have the fore-knowledge of which scripts these partial pages may contain or require!)
Thank you!
Update #1:
I suppose an acceptable answer is simply "you can't." However, I'd like to know if this is definitively the case. I haven't been able to find anything that officially states this yet.
Also, when I use firebug to inspect the panel region afterwards, there is no script element present at all. It is as if it is being parsed out by load.
Update #2:
I've narrowed this down to be a problem only when using the selector as part of the href. Loading the entire "somepage.html" will execute the script, but loading "somepage.html #someregion" does not.
$panel.load('somepage.html'); // my script fires!
$panel.load('somepage.html #someregion'); // script does not fire
I'm going to try and hunt down why this may be the case in the jquery source...
Well it seems that this is by design. Apparently to make IE happy, the rest of us suffer. Here's the relevant code in the jquery source:
// See if a selector was specified
self.html( selector ?
// Create a dummy div to hold the results
jQuery("<div/>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
// Locate the specified elements
.find(selector) :
// If not, just inject the full result
res.responseText );
I'm wondering if, instead of just stripping out the scripts, I could modify the jquery source to include them in some other way that makes IE happy? I still have yet to find anything else on the web discussing this matter, I'm sure I'm not the only person stumped by this?
I have run across issues before with IE not running injected <script>s that didn't contain the defer attribute. This discussion thread has some good information about the topic: innerHTML and SCRIPT tag

Shoud these two JQuery functions produce the same behavior?

Assuming I have the following two JQuery functions -
The first, which works:
$("#myLink_931").click(function ()
{
$(".931").toggle();
});
and the second, which doesn't work:
$("#myLink_931").click(function ()
{
var class_name = $(this).attr("id").split('_')[1];
$("."+class_name).toggle();
});
I want to replace the first with the second, which is more generalizable, but can't find any obvious syntactical problem with the second which might be preventing it from working.
My guess is there's a problem with the syntax:
"."+class_name
Is this bad syntax?
They work the same.
Working Demo
This is what debuggers are for. Step through the code and make sure class_name is calculated as you expect. The debugger should let you view the result of "."+class_name as well.
I created a sample page and dropped your example code in and it worked as expected. Perhaps there is another issue on the page? Can you post a link to the actual site?
Here is the code I used:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script src="scripts/script.js" type="text/javascript"></script>
</head>
<body>
<div id="myLink_931">Click Me</div>
<div class="931">HI</div>
</body>
</html>
and the script file:
(function($) {
$(document).ready(function() {
$("#myLink_931").click(function() {
var class_name = $(this).attr("id").split('_')[1];
$("." + class_name).toggle();
});
});
})(jQuery);
Class names and IDs aren't allowed to start with numbers - doesn't explain why one works and the other doesn't though. Give us a bit more info as above.
Is it possible you're not wrapping your 2nd example in the ready syntax [i.e. $(function(){ })] which would mean that the elements haven't been created in the DOM yet?

Categories

Resources