/    Sign up×
Community /Pin to ProfileBookmark

Problem to dynamically create a <script> tag

Hello people,

The website I’m working on has a top banner that’s loaded from the database. It may be an image, animation, and even HTML code, including <script> tags. Everything is working fine, HTML is loaded correctly, except when I insert a script tag.

Here’s the code I’m using, which partially makes the <script> work in Firefox, but not in any other browser:

[CODE]var div = document.createElement(‘div’);
div.innerHTML = CODE_TAKEN_FROM_DATABASE;
var children = div.childNodes;
topBanner.innerHTML = “”;
for(var i=0;i<children.length;i++)
topBanner.appendChild(children[i]);[/CODE]

I also tried to

[CODE]topBanner.innerHTML = CODE_TAKEN_FROM_DATABASE;[/CODE]

but this didn’t work anywhere.

This is the code [B]in the database[/B], which I’m using as a test:

[CODE]<script type=’text/javascript’ defer=’defer’>window.alert(‘o banner deve ser carregado aqui’);</script>[/CODE]

On firefox, this alert message is shown normally. Note that I’ve put the defer attribute, which serves to declare the tag as a script to be executed sometime after page loading, and which should make the tag work on IE, but it doesn’t.

I also tried to load this from the database:

[CODE]<div style=’width:728px; height:90px; overflow:hidden;’><script type=’text/javascript’ src=’http://ads.lomadee.com/as/show.html?mdsrc=23015540&dim=728_90&c=BR&si=33410510&pu=22274844′></script></div>[/CODE]

, which is basically a script that writes an <iframe> with ‘src’ pointing to an external *.swf file. Nothing abnormal. But when this script is loaded, the whole page goes blank, and keeps trying to load something from somewhere, never-ending.

That’s why my method still just PARTIALLY works on Firefox.

Thanks in advance,

H&#234;nio

to post a comment
JavaScript

15 Comments(s)

Copy linkTweet thisAlerts:
@yamaharussFeb 07.2011 — The short answer is, you can't. At least not the way you are attempting.

Try replacing script with scr"+"ipt
Copy linkTweet thisAlerts:
@GraniteauthorFeb 07.2011 — I can't? But why's that? Security matters?

You mean to put <scr"+"ipt> directly in the database, instead of <script>, and then use eval(), or something?

I'd have to do something like
[CODE]var strHTML = "var banner = "+CODE_TAKEN_FROM_DATABASE;
eval(strHTML);[/CODE]
, is that what you mean?

Thanks for the answer. ?
Copy linkTweet thisAlerts:
@yamaharussFeb 07.2011 — NO, do the replace when READING the code.. not when writing to the db.
Copy linkTweet thisAlerts:
@GraniteauthorFeb 09.2011 — Well, I've done this:
[CODE]var bannerCod = CODE_TAKEN_FROM_DATABASE;
var iosc = bannerCod.indexOf("script")+3;
var ious = bannerCod.indexOf("/script")+4;
var bit1 = bannerCod.substr(0,iosc);
var bit2 = bannerCod.substr(iosc,(ious)-(iosc));
var bit3 = bannerCod.substr(ious);
divTop.innerHTML = bit1 + bit2 + bit3;
[/CODE]
, which didn't work at all. The scripts don't run.

But I guess this is still not exactly what you mean, is it?

Also, I did this
[CODE]alert("bit1: "+bit1+"nnbit2: "+bit2+"nnbit3: "+bit3)[/CODE], and it shows
bit1: <div><scr

bit2: ipt type='text/javascript' defer='defer'>window.alert('o banner deve ser carregado aqui');</scr

bit3: ipt></div>[/QUOTE]
, as expected.
Copy linkTweet thisAlerts:
@yamaharussFeb 09.2011 — I meant to do the replace server-side, not with Javascript
Copy linkTweet thisAlerts:
@GraniteauthorFeb 09.2011 — alright...

[code=php]$whole = htmlentities($bannerTop[0]['ban_codigo']);
$scrPos = strpos($whole,"script")+3;
$uscrPos = strpos($whole,"/script")+4;
$bit1=substr($whole,0,$scrPos);
$bit2=substr($whole,$scrPos,$uscrPos-$scrPos);
$bit3=substr($whole,$uscrPos);
$xml .= "<codigo>".$bit1.""+"".$bit2.""+"".$bit3."</codigo>n";[/code]


and now, what do I do with that?

eval()uate it with javascript?
Copy linkTweet thisAlerts:
@GraniteauthorFeb 09.2011 — So... with the above php code, I did this now with javascript:
[CODE]var bannerCod = bannerT.getElementsByTagName("codigo")[0].firstChild.nodeValue; //the XML's <codigo> content
var toBeEvaluated = "divTop.innerHTML = ""+bannerCod+"";";
eval(toBeEvaluated);[/CODE]


And[CODE]alert(toBeEvaluated)[/CODE] shows divTop.innerHTML = "<div><scr"+"ipt type='text/javascript' defer='defer'>window.alert('o banner deve ser carregado aqui');</scr"+"ipt></div>";[/QUOTE]

Still not working. ?
Copy linkTweet thisAlerts:
@yamaharussFeb 09.2011 — There's no need to eval now since technically you are not embedding the script.
Copy linkTweet thisAlerts:
@yamaharussFeb 09.2011 — You do need to escape tho.. should read:

divTop.innerHTML = "<div><scr"+"ipt type='text/javascript' defer='defer'>window.alert('o banner deve ser carregado aqui');</

scr"+"ipt></div>";
Copy linkTweet thisAlerts:
@GraniteauthorFeb 09.2011 — Ok, did as you said and now I have this server-side
[code=php]$whole = htmlentities($bannerTop[0]['ban_codigo']);
$scrPos = strpos($whole,"script")+3;
$uscrPos = strpos($whole,"/script")+4;
$bit1=str_replace("/","/",substr($whole,0,$scrPos));
$bit2=str_replace("/","/",substr($whole,$scrPos,$uscrPos-$scrPos));
$bit3=str_replace("/","/",substr($whole,$uscrPos));
$xml .= "<codigo>".$bit1.""+"".$bit2.""+"".$bit3."</codigo>n";[/code]
, escaping the closing tags

and this client-side
[CODE]var bannerCod = """+bannerT.getElementsByTagName("codigo")[0].firstChild.nodeValue+""";
alert(bannerCod);
divTop.innerHTML = bannerCod;[/CODE]

, which is writing the code in the target div, but as text, not as html tags.

the alert now shows
[CODE]"<div><scr"+"ipt type='text/javascript' defer='defer'>window.alert('o banner deve ser carregado aqui');</scr"+"ipt></div>"[/CODE]

Doing
[CODE]var toBeEvaluated = "divTop.innerHTML = ""+bannerCod+"";";
eval(toBeEvaluated);[/CODE]
inserts the code correctly into the target, but still, does not make it run.
Copy linkTweet thisAlerts:
@yamaharussFeb 09.2011 — Are you trying to make the alert fire when it's written to the div??

If that's the case then it's not gonna happen. An event must have a firing mechanism of some sort. Simply "laying" it on the page will do nothing once the page has loaded.

You may need to explain the event in more detail. Is the banner being loaded with the page or after the page has loaded like in rotation with AJAX?
Copy linkTweet thisAlerts:
@GraniteauthorFeb 10.2011 — This alert is there just for debugging.

I'm using JQuery's ready() event to handle banners() function, which is responsible for starting the AjAX object, make the request, and then call function ApplyBanners(), which actually gets the data from XML and inserts it in the due places. banners() is called again and again each 30 secs.

Here:
[CODE]$(document).ready(function(){ banners("banner_topo","banner_lateral"); window.setInterval(function(){ banners("banner_topo","banner_lateral"); },30000); });[/CODE]

I'm not sure if I answered your question.
Copy linkTweet thisAlerts:
@TcobbFeb 12.2011 — I don't know if this will be any help to you, but here is a stripped down version of something I wrote that was used for such a purpose as you describe. The example doesn't use AJAX, but it can if you adapt it to. Just run the responseText (in JSON format) through the incoming() method. You send up both the HTML you want to have in your 'banner' as well as all the javascript functions needed to manipulate the page, all in one data structure.

[CODE]<html>
<head>

<title>Untitled Document</title>
<script type="text/javascript">
function makeMaster(idTag, container){ //send the magic ID tag and the id of the container as args
var k = { ff: [],
ref: [],
tag: '',
cont: null
};

k.cont = document.getElementById(container);
k.tag = idTag;

k.incoming = function(jsonStr){
var set= jsonStr;
k.cont.innerHTML = ''; //destroy existing content
k.cont.innerHTML = set.inner; //put in the new HTML content

k.ff.length = 0; k.ref.length = 0; //empty the arrays

var i, tmp, len = set.command.length; //translate the strings in the set.command array into working functions
for(i = 0; i < len; i++){
tmp = 'tmp = ' + set.command[i];
eval(tmp);
k.ff[i] = tmp;
}

// now find the references to the elements which have the magic id's

for(i = 0; i < len; i++){
tmp = k.tag + i;
k.ref[i] = document.getElementById(tmp);
}
}

k.activate = function(e){
var targ;
if (!e){
var e=window.event;
}
if (e.target){
targ=e.target;
}
else if (e.srcElement){
targ=e.srcElement;
}
if (targ.nodeType==3){
targ = targ.parentNode;
} // we have the reference of the element that was clicked
var i, flag = -1;
for(i = 0; i < k.ref.length; i++){ //determine if it is one of the magic elements
if(targ == k.ref[i]){
flag = i;
break;
}
}
if(flag == -1) return; //not a magic element
k.ff[flag](); // fire the corresponding function
}


return k;
}

//create global named fred
var fred;

window.onload = function(){
fred = makeMaster('AA', 'banner');
var x = { inner: '<h3 id="AA0">Hello, click me for an alert box</h3><span id ="AA1">Click me to change the font color</span>',
command: ["function(){alert('Hello There');}","function(){document.body.style.color = 'red';}"]
}
fred.incoming(x);
}

function simulate(){
var x = {"inner":"<span id="AA0">Click here to set the font color to black</span><br /><span id ="AA1">Click here for two alerts</span>","command":["function(){document.body.style.color = 'black';}","function(){alert('alert 1');alert('alert 2');}"]};
fred.incoming(x);
}


</script>



</head>
<body>
<div id = "banner" onclick="fred.activate(event)" style ="background-Color: gray">
</div>
<div> the banner should be in gray</div>
<input type = "button" value=" " onclick="simulate()" /> Click this button to simulate an AJAX response from the server.
<p>Note that the data which is used is a JSON object that has two properties: "inner" which contains the innerHTML that the
banner will be set to, and '"command" which is an array each element of which is text used for writing a javascript
function. The functions correspond in order with the elements that have the "magic" ids. Here the magic id is "AA" If an
element has the HTML id "AA0" clicking on it will fire the function that is defined in element[0] of the command array.</p>
<p>In this example the data structures are hardwired in, but it would be easy to adapt it so that the responseText from the
AJAX request was sent to the incoming() method of the 'fred' object</p>

</body>
</html>
[/CODE]
Copy linkTweet thisAlerts:
@GraniteauthorFeb 13.2011 — Mmmm... gonna try to adapt your idea to my code... that is, as soon as I understand it.

Thanks for the suggestion, man. I was already without ideas.

If I get this to work, I'll post again. Otherwise, I'll post anyway.
Copy linkTweet thisAlerts:
@GraniteauthorFeb 16.2011 — Oh, now I undestand the problem.

Insertion of inline scripts work fine.

But I can't load .js from other domains, right? Security reasons... As I asked in my second post...

Critical failure in my investigation throw. :rolleyes:

I feel embarassed that it has taken me so much time to figure this out. :o

Thanks for your goodwill. :p
×

Success!

Help @Granite spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.17,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...