homepage Welcome to WebmasterWorld Guest from 54.197.108.124
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
document.write in jsonp callback
document.write dows not work in in jsonp callback function
yogesh




msg:4401937
 3:42 pm on Dec 28, 2011 (gmt 0)

I am making a cross domain request using script tag hack and jsonp. In the callback function, I want to write the data received to DOM using document.write().

I know that I should use appendChild/innerHTML instead of doc.write(). My constraint is I do not have a class/id hook to the element I want to write to. I can only rely on document.write() to write "in place".

Following code is included in HTML div in a script tag.:


function request_jsonp(){
var script = document.createElement('script');
var server_path = 'http://somedomain.com/?q=querystring&callback=request_callback';
script.setAttribute('src', server_path);
document.getElementsByTagName('head')[0].appendChild(script);
console.log('data requested');
// document.write('hello world'); // this gets written
}


function request_callback(data){
console.log('data received');
document.write(data);
}


request_jsonp();

window.onload = function(){
console.log('onload fired');
}


/*
above code prints

data requested
data received
onload fired
*/


Basically document.write does not work even with a static string inside the callback function. I thought that if docment.write is called before onload, it inserts text in the page as noted here [javascript.crockford.com ]

What is preventing the document.write() to write to DOM?

Instead of writing to DOM, I tried to write it to iframe but even that does not seem to work.

Is there a better approach to do this?

 

penders




msg:4401948
 5:36 pm on Dec 28, 2011 (gmt 0)

I think the document is already complete by the time you attempt to document.write(), hence why it fails. The onload event fires after everything has finished loading, including all your images etc. This is a long time after the DOM itself is complete.

If this was to work, where in the document do you envisage the text being written?

How are you attempting to write it to an iframe?

I think you will need to write to the DOM using the conventional methods you mention. You do not necessarily need a specific id or class in which to target the element. Providing you can reliably traverse the DOM to get to the required element then you can write to it.

yogesh




msg:4402080
 6:11 am on Dec 29, 2011 (gmt 0)

Hello penders, Thanks for replying.

If I understand correctly, document should get overwritten with new content if document.write was called after onload. This however, does not happen and I can't figure out why this is the case.

I have following div where I expected it to get written.

<div>
<script type='text/javascript' src="myscript.js"></script>
<!-- Myscipt has the jsonp code and callback function listed above -->
</div>


I am writing the iframe in following manner.

var iframe = document.createElement("iframe");
/*I do not want to append to body though. I want to append to div */
document.body.appendChild(iframe);
var doc = iframe.document;
if(iframe.contentDocument){
doc = iframe.contentDocument; // For NS6
}
else if(iframe.contentWindow){
doc = iframe.contentWindow.document; // For IE5.5 and IE6
}
doc.open();
doc.write(data);
doc.close();

astupidname




msg:4402094
 7:49 am on Dec 29, 2011 (gmt 0)

My constraint is I do not have a class/id hook to the element I want to write to.

I will assume for the sake of less argument that this is beyond your control and you do not have the ability to add an id? I will ignore the iframe bit for this response, and go back to the beginning here.
The good news is that as the page is being loaded document.getElementsByTagName('div').length changes with each div read in to the page. So if your "myscript.js" linked script absolutely must be placed in the appropriate div where the 'data' is to appear, then the code within it can just read getElementsByTagName('div') and the last one is the one "myscript.js" is in (at the time of the read). So I believe this scheme should work:

var divs = document.getElementsByTagName('div');
var DATA_RECEIVER_DIV = divs[divs.length - 1]; //the current div this script is within at time of page load

function request_callback(data){
console.log('data received');
DATA_RECEIVER_DIV.innerHTML = data;
}

request_jsonp();

yogesh




msg:4402099
 8:41 am on Dec 29, 2011 (gmt 0)

Thanks for the resopnse astupidname. Appreciate that you ignored my constraint. This page resides at a client and I do not have control over it.

I have tried this approach. It fails when you add another div after the target div on the page. It should find the last div of the currently parsed ones, target div being the last. However, when I get the divs array, it has the subsequent div on the page as well.

I think this is because jsonp request is asynchronous and browser moves on to parsing the next element. Maybe you can shed more light on why this happens.

astupidname




msg:4402103
 10:26 am on Dec 29, 2011 (gmt 0)

I have tried this approach. It fails when you add another div after the target div on the page. It should find the last div of the currently parsed ones, target div being the last. However, when I get the divs array, it has the subsequent div on the page as well.


Are you saying you have implemented EXACTLY as I showed? I don't believe so. The definition of DATA_RECEIVER_DIV must be standalone global code as I showed to be read as the page is loaded, as opposed to in a function call later on or anything like that. Yes, the div which is at divs.length - 1 will change with each div read in to the page of course, and even divs[1] may actually change later if other code injects divs prior to the one in question. The array-like object which is returned by getElementsByTagName is sort of an oddity (a "live animal", if you will) as it actually will be updated/changed live as other divs are added. But this is not an issue if you do exactly as I showed, as the definition of DATA_RECEIVER_DIV will be evaluated at point of definition and capture the correct div which may then be referenced at a later time.
A simple example:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Some Title</title>
<script type="text/javascript">
window.onload = function () {
DATA_RECEIVER_DIV.innerHTML = ' (this is div 2, aka: DATA_RECEIVER_DIV)';
};
</script>
</head>
<body>
<div>div 1</div>
<div>div 2
<script type="text/javascript">
var divs = document.getElementsByTagName('div');
var DATA_RECEIVER_DIV = divs[divs.length - 1];
</script>
</div>
<div>div 3</div>
<div>div 4</div>
</body>
</html>

yogesh




msg:4402124
 12:45 pm on Dec 29, 2011 (gmt 0)

Are you saying you have implemented EXACTLY as I showed? I don't believe so. The definition of DATA_RECEIVER_DIV must be standalone global code as I showed to be read as the page is loaded, as opposed to in a function call later on or anything like that


You are right. I was defining it in a function. Hence it did not work as expected.

I will add that above method does not work in jsonp callback because jsonp is asynch. By the time you get your data back, parsing may have moved onto next div depending on browser or network connections. This is ok since it is inherently characteristic of jsonp.

Thanks a ton for your help on this. It has cleared a few things for me.

Regards,
Yogesh

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved