I'm working with Angular and JQuery on a site, and set the header and footer as partials in order to maximize re-use. The issue I have is that I need some javascript to be handled within the footer upon load, but that is not supported by Angular via the ng-include tag or JQuery with the $.load() method.
I have multiple 3rd party scripts that I want to run, but the one I'm working on right now is one of those Verisign scripts which returns an image, which is loaded using the <script src=""></script> pattern. I know that at least presently there is no way for Javascript to pull in external scripts, so my thought was to simply create a container div where I want the image to appear, to run the 3rd party script from the main page, and to then take that content and populate the container div via reference, conceptually looking like this:
//footer.html
<div id="siteVerify"></div>
//index.html
//call a method that takes 3rd party that i can point to siteVerify
Is it possible to point that 3rd party script to the siteVerify div without having the script run inside the div?
Conversely, if there is an alternative preferred method for html code re-use so that I can simply edit changes in one place and have them propegate throughout the site?
edit:
I put:
// If you know these dead scripts will be in a certain container, refine your jQuery selector
$(document).ready(function(){
// If you know these dead scripts will be in a certain container, refine your jQuery selector
$('.deadScriptContainer script').each(function(){
// If a script has content, we want to execute it
if($(this).html().length > 0){
// Eval() will execute any JavaScript it is passed
eval($(this).html());
}else{
// If this script has no content, let's see if it has a src
if($(this).src){
// Create a new script tag
var newScript = document.createElement("script");
newScript.type = "text/javascript";
newScript.src = $(this).src;
// Append new script to the head
document.querySelector("head").appendChild(newScript);
}
}
});
});
into a js file, and call it at the bottom of my index.html file. Meanwhile in my footer, I have something like this:
<div class='deadScriptContainer'><span id='siteseal'>
<script type="text/javascript" src="https://seal.godaddy.com/getSeal?sealID=...."></script></span>
</div>
so it should be finding the script tag within the div with the class 'deadScriptContainer', and looking up its src, which should be the https:.... I put an alert in the code and it indeed appears to be finding the script tag, but when i check to see what the src value is, it always returns 'undefined'.
I have a feeling my selectors are probably wrong, but I can't see what it is about them.
When you load in script tags using AJAX, the problem is they're brought in as placed where you want it, hence why it doesn't fire. There is an easy way to revive these dead scripts though, so you're in luck!
Once you have your data back from your AJAX request, evaluate any internal JavaScript.
For external JavaScript, what you need to do is create a new <script> tag and give it the dead script's source.
The entire process should look something like this once you've loaded in your new data:
// If you know these dead scripts will be in a certain container, refine your jQuery selector
$('deadScriptContainer script').each(function(){
// If a script has content, we want to execute it
if($(this).html().length > 0){
// Eval() will execute any JavaScript it is passed
eval($(this).html());
}else{
// If this script has no content, let's see if it has a src
if($(this).src){
// Create a new script tag
var newScript = document.createElement("script");
newScript.type = "text/javascript";
newScript.src = $(this).src;
// Append new script to the head
document.querySelector("head").appendChild(newScript);
}
}
});
I'm using featherlight to call a file with ajax. It only consists of:
<script>
alert();
</script>
The scripts runs, I see the alert but it also renders it in plain text:
alert();
I can't figure out why.
Digging into it, featherlight adds a featherlight-inner class to every element of "first level" that it finds on the page.
So solution is to put the script tag into the main tag.
If you want to execute something when it opens, use afterOpen.
i want to put the content from a database field to the tinyMCE editor on page load. For that i've got a php function like this:
public function __loadTinyMCE($jobscopeIntroText) {
print '
<script type="text/javascript">
function loadDefaultTinyMCEContent(){
tinyMCE.activeEditor.setContent("'.$jobscopeIntroText.'", {format : "raw"});
}
</script>
';
$jobscopeIntroText is the html content i previously wrote into the tinyMCE editor and comes from the database.
When i write e.g.:
<p>Hello< /p>< p>This is a new line< /p>
it doesnt work and the html code in setContent() is broken after the first closing p-tag. In chrome developer tools the text before the first closing p-tag is red and after that it's black. Even if there are no " or ' within the html.
With only one closing p-tag it works.
Anyone knows the problem here?
I think you should use this code once all contents will be loaded. Therefore there can be ways to achieve desire result:
You can place your database value within editor element and then
initialize tinyMCE editor. (if page is loading)
You can above function just before the before the body tag ends.
You can use document load event or jQuery document.ready() function and just function within it.
I hope this will work for you. Please do let me know for specific scenario.
I have a div on my page defined as follows:
<div id="scripts">
</div>
I want to dynamically change the contents of the div and load in some scripts using jQuery. I am doing it like this:
$('#scripts').html('<script language="JavaScript">pn = "landing page"; '+
'cms_1 = "content"; '+
'cms_2 = "promotional "; '+
'cms_3 = "campaign"; '+
'cms_s = "blk:us:dc"; '+
'cms_env = "dev"; '+
'cms_country = "USA"; '+
'<\/script>');
This is in the document.Ready function. However, when I view the source after the page is loaded, the div appears empty and I do not see the script tags. I thought that the script wasn't getting added but when I add alert("done"); to the script. I get the alert which tells me that the code is executed.
Why can't I see the changes made when I view the source? Is the Source html rendered before the document.ready function?
The html function from jquery internally uses the innerHTML property of the browser when available. In general, script blocks inserted via innerHTML don't get executed almost in any browser.
Try creating a script tag with the content and appending it to the document instead, e.g.
var script=document.createElement('script');
script.type='text/javascript';
script.html(...);
$("#scripts").append(script);
After seeing your motivation in the comment, I have to add : although you can later physically remove a script tag from the site, this won't have the effect of unloading its content (e.g. functions defined in the script). The only way to achieve that without refreshing the page is to encapsulate the objects defined in it and delete them manually. This is of course only possible if the content of the script was designed upfront in such a way.
I am currently loading a lightbox style popup that loads it's HTML from an XHR call. This content is then displayed in a 'modal' popup using element.innerHTML = content This works like a charm.
In another section of this website I use a Flickr 'badge' (http://www.elliotswan.com/2006/08/06/custom-flickr-badge-api-documentation/) to load flickr images dynamically. This is done including a script tag that loads a flickr javascript, which in turn does some document.write statments.
Both of them work perfectly when included in the HTML. Only when loading the flickr badge code inside the lightbox, no content is rendered at all. It seems that using innerHTML to write document.write statements is taking it a step too far, but I cannot find any clue in the javascript implementations (FF2&3, IE6&7) of this behavior.
Can anyone clarify if this should or shouldn't work? Thanks.
In general, script tags aren't executed when using innerHTML. In your case, this is good, because the document.write call would wipe out everything that's already in the page. However, that leaves you without whatever HTML document.write was supposed to add.
jQuery's HTML manipulation methods will execute scripts in HTML for you, the trick is then capturing the calls to document.write and getting the HTML in the proper place. If it's simple enough, then something like this will do:
var content = '';
document.write = function(s) {
content += s;
};
// execute the script
$('#foo').html(markupWithScriptInIt);
$('#foo .whereverTheDocumentWriteContentGoes').html(content);
It gets complicated though. If the script is on another domain, it will be loaded asynchronously, so you'll have to wait until it's done to get the content. Also, what if it just writes the HTML into the middle of the fragment without a wrapper element that you can easily select? writeCapture.js (full disclosure: I wrote it) handles all of these problems. I'd recommend just using it, but at the very least you can look at the code to see how it handles everything.
EDIT: Here is a page demonstrating what sounds like the effect you want.
I created a simple test page that illustrates the problem:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Document Write Testcase</title>
</head>
<body>
<div id="container">
</div>
<div id="container2">
</div>
<script>
// This doesn't work!
var container = document.getElementById('container');
container.innerHTML = "<script type='text/javascript'>alert('foo');document.write('bar');<\/script>";
// This does!
var container2 = document.getElementById('container2');
var script = document.createElement("script");
script.type = 'text/javascript';
script.innerHTML = "alert('bar');document.write('foo');";
container.appendChild(script);
</script>
</body>
</html>
This page alerts 'bar' and prints 'foo', while I expected it to also alert 'foo' and print 'bar'. But, unfortunately, since the script tag is part of a larger HTML page, I cannot single out that tag and append it like the example above. Well, I can, but that would require scanning innerHTML content for script tags, and replacing them in the string by placeholders, and then inserting them using the DOM. Sounds not that trivial.
Use document.writeln(content); instead of document.write(content).
However, the better method is using the concatenation of innerHTML, like this:
element.innerHTML += content;
The element.innerHTML = content; method will replace the old content with the new one, which will overwrite your element's innerHTML!
Whereas using the the += operator in element.innerHTML += content will append your text after the old content. (similar to what document.write does.)
document.write is about as deprecated as they come. Thanks to the wonders of JavaScript, though, you can just assign your own function to the write method of the document object which uses innerHTML on an element of your choosing to append the supplied content.
Can I get some clarification first to make sure I get the problem?
document.write calls will add content to the markup at the point in the markup at which they occur. For example if you include document.write calls in a function but call the function elsewhere, the document.write output will happen at the point in the markup the function is defined not where it is called.
Therefore for this to work at all the Flickr document.write statements will need to be part of the content in element.innerHTML = content. Is this definitely the case?
You might quickly test if this should work at all by adding a single and simple document.write call in the content that is set as the innerHTML and see what this does:
<script>
var content = "<p>1st para</p><script>document.write('<p>2nd para</p>');</script>"
element.innerHTML = content;
</script>
If that works, the concept of document.write working in content set as the innerHTML of an element might just work.
My gut feeling is that it won't work, but it should be pretty straightforward to test the concept.
So you're using a DOM method to create a script element and append that to an existing element and this then causes the content of the appended script element to execute? That sounds good.
You say that the script tag is part of a larger HTML page and therefore cannot be singled out. Can you not give the script tag an ID and target it? I'm probably missing something obvious here.
In theory, yes, I can single out a script tag that way. The problem is that we potentially have dozens of situations where this occurs, so I am trying to find some cause or documentation of this behavior.
Also, the script tag does not seem to be a part of the DOM anymore after it gets loaded. In our environment, my container div remains empty, so I cannot fetch the script tag. It should work, though, because in my example above the script does not get executed, but is still part of the DOM.