I've created an XSL stylesheet that has some embedded JavaScript. It calls functions that in turn call document.write() to print the results of these functions to the page.
<xsl:foreach...>
<div class="directionBlock">
<script type="text/javascript">writeDirection('<xsl:value-of select="Direction"/>');</script>
</div>
</xsl:foreach...>
Unfortunately, in firefox, document.write() is not supported. What to do?
Why do you need both XSLT and Javascript to output HTML? If your aim is to output something in the div containing the script element then consider to do it with XSLT alone. If you really need to use Javascript to create contents then consider to use methods like createElement and appendChild instead of document.write.
That is as far as a general answer can help, if you need specific help then we need to see details of your code like that writeDirection function and the argument you pass to it.
To give you some outline of sample code, if you writeDirection function needs to add content to the div then put an id on the div e.g. <div id="db1" class="directionBlock">...</div>, then pass it to the writeDirection function e.g. <script type="text/javascript">writeDirection('<xsl:value-of select="Direction"/>', document.getElementById('db1'));</script>, then in that function simply do
function writeDirection(dir, elementToWriteTo) {
// instead of document.write(stuff) use
var span = document.createElement('span');
span.innerHTML = stuff;
elementToWriteTo.appendChild(span);
}
The way I implemented a solution is to call a function and pass the row number:
<xsl:foreach...>
...
<div class="directionBlock">
<script>myJsFunction('<xsl:value-of select="Direction"/>', <xsl:value-of select="position()"/>);</script>
</div>
...
</xsl:foreach...>
This in turn used JQuery to access the element in question, using nth-child(position) to get the row, find a selector and use .html() to insert code into that element.
Thanks for all your help!
Related
Good day! Newbie here. I just want to know if it's possible to change the whole content of an html using javascript? I got some codes here. (not mine but whoever did this, thank you so much!) I don't know where to put/insert all the codes of the new layout like when you click a button then the whole content will change. Thank you very much for helping me.
<script language="Javascript">
<!--
var newContent='<html><head><script language="Javascript">function Hi()</script></head><body onload="Hi();"><p id="p">hello</p></body></html>';
function ReplaceContent(NC) {
document.write(NC);
document.close();
}
function Hi() {
ReplaceContent(newContent);
}
-->
</script>
The easiest way to do this is with jQuery.
function insertHtml()
{
var newHtml = '<div><span>Hello World</span></div>';
$('body').html(newHtml);
}
Something like that will replace the entire contents of body with newHtml. You can also do this with pure javascript using the .innerHtml property but jQuery has many advantages.
EDIT: If you want to add something to the DOM rather than replacing the entire thing, use
$('body').append(newHtml)
instead. This will add the content to the end of the body. This is very often used for things like adding rows to a table.
Yes it is possible but this code is not valid unless you remove the comment tags however don't use the document.write() after page load unless you want to overwrite everything in page including the script
Is it possible to get in some way the original HTML source without the changes made by the processed Javascript? For example, if I do:
<div id="test">
<script type="text/javascript">document.write("hello");</script>
</div>
If I do:
alert(document.getElementById('test').innerHTML);
it shows:
<script type="text/javascript">document.write("hello");</script>hello
In simple terms, I would like the alert to show only:
<script type="text/javascript">document.write("hello");</script>
without the final hello (the result of the processed script).
I don't think there's a simple solution to just "grab original source" as it'll have to be something that's supplied by the browser. But, if you are only interested in doing this for a section of the page, then I have a workaround for you.
You can wrap the section of interest inside a "frozen" script:
<script id="frozen" type="text/x-frozen-html">
The type attribute I just made up, but it will force the browser to ignore everything inside it. You then add another script tag (proper javascript this time) immediately after this one - the "thawing" script. This thawing script will get the frozen script by ID, grab the text inside it, and do a document.write to add the actual contents to the page. Whenever you need the original source, it's still captured as text inside the frozen script.
And there you have it. The downside is that I wouldn't use this for the whole page... (SEO, syntax highlighting, performance...) but it's quite acceptable if you have a special requirement on part of a page.
Edit: Here is some sample code. Also, as #FlashXSFX correctly pointed out, any script tags within the frozen script will need to be escaped. So in this simple example, I'll make up a <x-script> tag for this purpose.
<script id="frozen" type="text/x-frozen-html">
<div id="test">
<x-script type="text/javascript">document.write("hello");</x-script>
</div>
</script>
<script type="text/javascript">
// Grab contents of frozen script and replace `x-script` with `script`
function getSource() {
return document.getElementById("frozen")
.innerHTML.replace(/x-script/gi, "script");
}
// Write it to the document so it actually executes
document.write(getSource());
</script>
Now whenever you need the source:
alert(getSource());
See the demo: http://jsbin.com/uyica3/edit
A simple way is to fetch it form the server again. It will be in the cache most probably. Here is my solution using jQuery.get(). It takes the original uri of the page and loads the data with an ajax call:
$.get(document.location.href, function(data,status,jq) {console.log(data);})
This will print the original code without any javascript. It does not do any error handling!
If don't want to use jQuery to fetch the source, consult the answer to this question: How to make an ajax call without jquery?
Could you send an Ajax request to the same page you're currently on and use the result as your original HTML? This is foolproof given the right conditions, since you are literally getting the original HTML document. However, this won't work if the page changes on every request (with dynamic content), or if, for whatever reason, you cannot make a request to that specific page.
Brute force approach
var orig = document.getElementById("test").innerHTML;
alert(orig.replace(/<\/script>[.\n\r]*.*/i,"</script>"));
EDIT:
This could be better
var orig = document.getElementById("test").innerHTML + "<<>>";
alert(orig.replace( /<\/script>[^(<<>>)]+<<>>/i, "<\/script>"));
If you override document.write to add some identifiers at the beginning and end of everything written to the document by the script, you will be able to remove those writes with a regular expression.
Here's what I came up with:
<script type="text/javascript" language="javascript">
var docWrite = document.write;
document.write = myDocWrite;
function myDocWrite(wrt) {
docWrite.apply(document, ['<!--docwrite-->' + wrt + '<!--/docwrite-->']);
}
</script>
Added your example somewhere in the page after the initial script:
<div id="test">
<script type="text/javascript"> document.write("hello");</script>
</div>
Then I used this to alert what was inside:
var regEx = /<!--docwrite-->(.*?)<!--\/docwrite-->/gm;
alert(document.getElementById('test').innerHTML.replace(regEx, ''));
If you want the pristine document, you'll need to fetch it again. There's no way around that. If it weren't for the document.write() (or similar code that would run during the load process) you could load the original document's innerHTML into memory on load/domready, before you modify it.
I can't think of a solution that would work the way you're asking. The only code that Javascript has access to is via the DOM, which only contains the result after the page has been processed.
The closest I can think of to achieve what you want is to use Ajax to download a fresh copy of the raw HTML for your page into a Javascript string, at which point since it's a string you can do whatever you like with it, including displaying it in an alert box.
A tricky way is using <style> tag for template. So that you do not need rename x-script any more.
console.log(document.getElementById('test').innerHTML);
<style id="test" type="text/html+template">
<script type="text/javascript">document.write("hello");</script>
</style>
But I do not like this ugly solution.
I think you want to traverse the DOM nodes:
var childNodes = document.getElementById('test').childNodes, i, output = [];
for (i = 0; i < childNodes.length; i++)
if (childNodes[i].nodeName == "SCRIPT")
output.push(childNodes[i].innerHTML);
return output.join('');
I have this code: [it is a rough example with poor coding, but it illustrates what I want to do.]
<html>
<body>
<script type="text/javascript">
function fun()
{
var divs = document.getElementById('hi');
divs.innerHTML = divs.innerHTML.replace("cake","jump");
alert(divs.innerHTML);
}
</script>
<div id="hi">
<span onclick="fun('cake');">Mer<span onclick="fun('cake');">Mer</span></span>
</div>
<a onclick='fun()';)>Click</a>
</body>
</html>
When I click on the <a> i want to change the onclick parameter within fun() from 'cake' to 'jump'. I do not want to use the setAttribute() method as my real example has several nested tags and I want to replace 'cake' in several different places.
I want the innerHTML.replace() function to work to do this but, alas it doesn't function as I want it to. How do I replace text within innerHTML?
Forget it. Never hack around with the innerHTML, there's no guarantee it will be in any particular format, you're very likely to mess up the markup by replacing the wrong thing, and even if it works, you're serialising the document content into a string, hacking it and then recreating the entire content from the string again, instead of just replacing a particular thing you're interested in. This is slow and loses all non-serialisable data (like form field values, JS references and assigned event handlers).
In general DOM methods are much more reliable for altering page content. It's what they were designed for. Use them, and use the DOM Level 1 HTML properties in preference to setAttribute which is badly broken in IE. This goes double for event handler attributes. Trying to hack at JavaScript code inside an attribute value inside an HTML string is insanity, even if it worked.
There is no need whatsoever to replace any page content. You could implement your example much more easily with a simple variable:
<div id="hi">
<span>Mer<span>Mer</span></span>
</div>
<a id="foo">Click</a>
<script type="text/javascript">
var potato= 'cake';
document.getElementById('foo').onclick= function() {
potato= 'jump';
return false;
};
var spans= document.getElementById('hi').getElementsByTagName('span');
for (var i= spans.length; i-->0;) {
spans[i].onclick= function() {
alert(potato); // do whatever with the variable
};
}
</script>
First, you have an error in your HTML:
<a onclick='fun()';)>Click</a>
What's with the ;) outside the attribute value?
Next...
[...] method as my real example has several nested tags and I want to replace 'cake' in several different places.
This means you really, really don't want to use innerHTML and replace(). It will screw up. Use an HTML parser of sorts; walk the DOM recursively... anything other than replace.
Within the scope of your specific example, I suggest using a variable to hold the value of cake and jump instead.
Change your replace call to use the RegEx "global" flag:
divs.innerHTML = divs.innerHTML.replace(/cake/g,"jump");
That said, if you're using this for more than a quick test, you should use DOM objects to accomplish what you would like to do. Otherwise, this will get ugly really fast.
Also, it wouldn't hurt to change your <a> tag code:
<a onclick='fun(); return false;')>Click</a>
(The return false; is optional, but good practice.)
The easiest way to change the onclick parameter is to make it a variable instead of a string literal. Here I'm using a variable called food:
<script type="text/javascript">
var food = "cake";
function change()
{
food = "jump";
}
</script>
<div id="hi">
<span onclick="alert(food);">Mer<span onclick="alert(food);">Mer</span></span>
</div>
<a onclick='change()'>Click</a>
Firstly, is there a way to use document.write() inside of JQuery's $(document).ready() method? If there is, please clue me in because that will resolve my issue.
Otherwise, I have someone's code that I'm supposed to make work with mine. The catch is that I am not allowed to alter his code in any way. The part that doesn't work looks something like this:
document.write('<script src=\"http://myurl.com/page.aspx?id=1\"></script>');
The script tag is referencing an aspx page that does a series of tests and then spits out something like so:
document.write('<img src=\"/image/1.jpg\" alt=\"Second image for id 1\">')
The scripts are just examples of what is actually going on. The problem here is that I've got a document.write() in the initial script and a document.write() in the script that get's appended to the first script and I've got to somehow make this work within JQuery's $(document).ready() function, without changing his code.
I have no idea what to do. Help?
With the requirements given, no, you can't use document.write without really hosing up the document. If you're really bent on not changing the code, you can override the functionality of document.write() like so and tack on the result later:
var phbRequirement = "";
$(function() {
document.write = function(evil) {
phbRequirement += evil;
}
document.write("Haha, you can't change my code!");
$('body').append(phbRequirement);
});
Make sure you overwrite the document.write function before it is used. You can do it at anytime.
The other answers are boring, this is fun, but very pretty much doing it the wrong way for the sake of fulfilling the requirements given.
picardo has the approach I would've used. To expand on the concept, take a read:
$('<script/>')
.attr('src', 'http://myurl.com/page.aspx?id=1')
.appendTo('body');
Alternate style:
var imgnode = $('<img alt="Second image for id 1"/>')
.attr('src', "image1.jpg");
$('#id1').append(imgnode);
Be sure to use the attr method to set any dynamic attributes. No need to escape special symbols that way.
Also, I'm not sure what the effectiveness of dynamically generating script tags; I never tried it. Though, it's expected that they contain or reference client-side script. My assumption is that what page.aspx will return. Your question is a little vague about what you're trying to do there.
jQuery has a ready substitute for document.write. All you need to use is the append method.
jQuery('<img src=""/>').appendTo('body');
This is fairly self-evident. But briefly, you can replace the with whatever html you want. And the tag name in the appendTo method is the name of the tag you want to append your html to. That's it.
picardo's answer works, but this is more intuitive for me:
$("body").append('<img src=\"/image/1.jpg\" alt=\"Second image for id 1\">');
Also, for the script part that is being inserted with document.write(), check out jQuery's getScript() function
Using a ajax request I want to change content of my div.
<div id="d1">202</div>
So I want to change the content to a different number.
$('d1').InnerText???
Also, say I wanted to increment the number, how could I do that? Do I have to convert to int?
$("#di").html('My New Text');
Check out the jQuery documentation.
If you wanted to increment the number, you would do
var theint = parseInt($("#di").html(),10)
theint++;
$("#di").html(theint);
P.S. Not sure if it was a typo or not, but you need to include the # in your selector to let jQuery know you are looking for an element with an ID of di. Maybe if you come from prototype you do not expect this, just letting you know.
This would changed the inner text of your HTML element.
$('#d1').text(parseInt(requestResponse)++);
Unless you're embedding html like <b>blah</b> I'd suggest using $("#di").text() as it'll automatically escape things like <, > and &, whereas .html() will not.
Use the text function:
$("#d1").text($("#d1").text() + 1);
$('#d1').html("Html here");
jQuery('#d1').html("Hello World");
if your value is a pure text (like 'test') you could use the text() method as well. like this:
$('#d1').text('test'); Or $('#d1').html('test');
anyway, about the problem you are sharing, I think you might be calling the JavaScript code before the HTML code for the DIV is being sent to the browser. make sure you are calling the jQuery line in a <script> tag after the <div>, or in a statement like this:
$(document).ready(
function() {
$('#d1').text('test');
}
);
this way the script executes after the HTML of the div is parsed by the browser.
$("#div1").innerHTML="your text goes here..";