Javascript appendChild(script) works only one time - javascript

I'm trying to create two separate HTML documents: main.html and sufler.html. Idea is to control sufler.html page from main.html . So far I succeeded to write text and change it's font style. But font style changes only ONE time...
I need it to be able to change many times, can't understand what is going on,
because, as I understanding, every time I calling function writing(), I'm clearing all new document's content with newDoc.body.innerHTML = ''... but it seems that not... although text is changing every time.
main.html
<html>
<head>
<script type="text/javascript">
var HTMLstringPage1 = '<!DOCTYPE html><html><head><link href="stilius.css" rel="stylesheet" type="text/css" /></head><body>',
HTMLstringPage2 = '</body></html>',
HTMLstringDiv1 = '<div id="sufler"><div id="mov"><p id="flip">',
HTMLstringDiv2 = '</p></div></div>';
//NEW WINDOW OPEN--------------------------------------------------------------------------------------------------------
var newWindow = window.open('suffler.html','_blank','toolbar=no, scrollbars=no, resizable=no, height=615,width=815');
var newDoc = newWindow.document;
newDoc.write(HTMLstringPage1,HTMLstringDiv1+'Text'+HTMLstringDiv2,HTMLstringPage2);
var script = newDoc.createElement("script");
script.type = "text/javascript";
//=======================================================================================================================
//WRITING----------------------------------------------------------------------------------------------------------------
function writing(){
newText = document.getElementById("sel-1").value.replace(/\n/gi, "</br>");
fontas= document.getElementById("textFont").value;
size= document.getElementById("textSyze").value;
stylas= document.getElementById("textStyle").value;
syntax= document.getElementById("textSyntax").value;
newDoc.body.innerHTML = '';//clears old text (should clear old scripts and functions too)
newDoc.write(HTMLstringPage1,HTMLstringDiv1,newText,HTMLstringDiv2,HTMLstringPage2);//writes new text (and new scripts and functions)
var text = newDoc.createTextNode('document.getElementById("flip").style.font="'+stylas+' '+syntax+' '+size+'px '+fontas+'";');
script.appendChild(text);
newDoc.getElementsByTagName("body")[0].appendChild(script);
}
//=======================================================================================================================
</script>
</head>
<body>
<button type="button" style="background-color: #F5FF25;" onclick="writing()">Apply text</button>
</body>
</html>

Any one node can only be added to the document once. You only define script once but trying to add it to the DOM multiple times. Put the var script = ... line inside writing().

Related

To print a div with the css style

I made a script to print just a div, but when I see the preview, it doesn't "format" the page using the CSS added.
HTML Part:
<center>Do not print this</center>
<div>Hi mom!</div>
<center>Print this</center>
<div id="content" class="print">Hi dad!</div>
<input type='button' value='Print' onClick='Print()' />
JS part
function Print(){
var corpo = document.getElementById('content').innerHTML;
var a = window.open('','','width=640,height=480');
a.document.open("text/html");
a.document.write("<html><head><link rel=\"stylesheet\" href=\"./style.css\"></head><body><div class=\"print\">");
a.document.write(corpo);
a.document.write("</div></body></html>");
a.document.close();
a.print();
}
A live version: https://codepen.io/Pop1111/pen/Vwabbzd
It looks like it load the css only AFTER.
Any tips?
Your code will create invalid HTML
Try
function Print() {
var corpo = document.getElementById('content').innerHTML;
const html = [];
html.push('<html><head>');
// assuming the first stylesheet on the parent page - use a different selector if not
// or use +location.protocol+'//'+location.host+'/style.css">'
html.push('<link rel="stylesheet" href="' + document.querySelector("link[rel=stylesheet]").href + '">');
html.push('</head><body onload="window.focus(); window.print()"><div>');
html.push(corpo);
html.push('</div></body></html>');
console.log(html)
/* this will not work in the snippet - uncomment on your server
var a = window.open('', '', 'width=640,height=480');
a.document.open("text/html");
a.document.write(html.join(""));
a.document.close();
*/
}
<html>
<head>
<link rel="stylesheet" href="test.css" />
</head>
<body>
<center>Do not print this</center>
<div>Hi mom!</div>
<center>Print this</center>
<div id="content" class="print">Hi dad!</div>
<input type='button' value='Print' onClick='Print()' />
</body>
</html>
Your new document is unsaved, so does not have your expected path, so the relative reference of the CSS file is not finding the CSS.
To get this to work as expected, you would need to change the CSS reference to absolute reference, or add code to save the new HTML file first.
Is this just how you have tested it, or will your production version function like this as well? (New file, not saved, then print).
You could always inject the actual CSS itself into the head of the new document between style tags, instead of just a reference to the CSS file. Try that.

Change the inner HTML with another HTML code block of a div and a script

I have been struggling with this so hopefully someone can help!
So I am looking to change the inner html of a paragraph to another html element containing a div and script when my frame receives a message from the page code. I have this working only for when the inner html is set to replace with a normal string
like this
document.getElementById('demo').innerHTML = "testing" ;
the correct replacement shows up here
<p id="demo">testing</p>
but when I try and pass in the other html to replace that section like this:
document.getElementById('demo').innerHTML =
'<div id="tlkio" data-channel="regerhtrh" data-theme="theme--night" style="width:100%;height:400px;"></div><script async src="https://tlk.io/embed.js" type="text/javascript"></script>';
it does not work. I don't think it is a quotation issue because I wrapped the outsides of it with single quotes. not sure what else to try. Below is the full html and I would appreciate any help!
<!doctype html>
<html>
<head>
<script type="text/javascript">
function init () {
// when a message is received from the page code
window.onmessage = (event) => {
if (event.data) {
console.log("HTML Code Element received a message!");
insertMessage(event.data);
}
}
}
// display received message
function insertMessage(msg) {
document.getElementById('demo').innerHTML =
'<div id="tlkio" data-channel="regerhtrh" data-theme="theme--night" style="width:100%;height:400px;"></div><script async src="https://tlk.io/embed.js" type="text/javascript"></script>'
;
}
</script>
</head>
<body onload="init();" style="background-color:lightgray;">
<h1>HTML Component Test</h1>
<p id="demo">
should put html here
</p>
</body>
</html>
The major issue is the </script> closing tag in your code. It closes YOUR block, not the block you are inserting.
You have to do so:
var myHtml = "<div id='tlkio' data-channel='regerhtrh' data-theme='theme--night' style='width: 100%; height:400px;'></div><script async src='https://tlk.io/embed.js' type='text/javascript'></scr"+"ipt>";
Second, script you insert with innerHTML wont run. Use document.createElement('script') instead
UPDATE
Here is the jsFiddle: https://jsfiddle.net/ArtyomShegeda/62fdybc0/21/
You may consider swapping the Quotes used:
function insertMessage(msg) {
var myHtml = "<div id='tlkio' data-channel='regerhtrh' data-theme='theme--night' style='width: 100%; height:400px;'></div><script async src='https://tlk.io/embed.js' type='text/javascript'></script>";
document.getElementById('demo').innerHTML = myHtml;
}
This may add it, yet may not render it. You might consider creating the elements and appending them.
function insertMessage(msg) {
var tlkio = document.createElement("div");
tlkio.style.width = "100%";
tlkio.style.width = "400px";
tlkio.setAttribute('data-channel', 'regerhtrh');
tlkio.setAttribute('data-theme', 'theme--night');
var tlkScript = document.createElement("script");
tlkScript.src = 'https://tlk.io/embed.js';
tlkScript.type = 'text/javascript';
tlkScript.async = true;
document.getElementById('demo').append(tlkio, tlkScript);
}
Based on some research here: load scripts asynchronously, it may be best to append the script to the <head>.
Hope that helps.
Update 1
Per your fiddle, once updated, it is working as you suggested: https://jsfiddle.net/Twisty/62fdybc0/7/
The following is added to #myDIV element:
<div style="width: 100%; height: 400px;" data-channel="regerhtrh" data-theme="theme--night"></div><script src="https://tlk.io/embed.js" type="text/javascript" async="async"></script>

Concatenate Strings in JavaScript

I Have edited the code, the updated code is below, This code is not able to fetch the keywords meta tag, hence it is not working.
old description: I am trying to concatinate the strings to get the finalUrl, but I am not able to do so becuase of the tags variable. I need to fetch the keywords meta tag of the page and append it to get the finalUrl. Any help?
<script type="text/javascript">
var tags=$('meta[name=keywords]').attr("content");
var gameurl = "http://xyz/abc/details/";
var jsn = ".json?callback=showGameDetail";
var finalUrl= gameurl.concat(tags).concat(jsn);
function loadJSON(url) {
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = url;
headID.appendChild(newScript);
}
function showGameDetail(feed){
var title = feed.title;
var game_url = feed.pscomurl;
var packart_url = feed.Packart;
$("#bnr-ads-box").html("<img src='"+"http://abc.com/"+packart_url+"'>");
}
loadJSON(finalUrl);
</script>
<div id="bnr-ads-box"></div>
<!DOCTYPE html>
<html>
<head>
<meta id="metaK" name="keywords" content="customizable software for QuickBooks, QuickBooks-integrated, Method customization, CRM accounting, Method for QuickBooks, Method CRM, Method blog, Salesforce automation, Method online platform, QuickBooks customization, web-based platform, industry-specific, customer portal, Method Field Services, Method Manufacturing, ERP" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
</head>
<body>
<p id="demo">Click the button to join two strings into one new string.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction()
{
var tags=$('meta[name=keywords]').attr("content");
var gameurl = "http://xyz/abc/names/";
var jsn = ".json?callback=showGameDetail";
var finalUrl= gameurl.concat(tags).concat(jsn);
document.getElementById("demo").innerHTML=finalUrl;
}
</script>
</body>
</html>
change this
var tags="$('meta[name=keywords]').attr("content");";
to
var tags=$('meta[name=keywords]').attr("content");
also use this code var finalUrl = gameurl + tags + jsn;
What you need is to escape the double quotes inside your tags variable, like so:
var tags="$('meta[name=keywords]').attr(\"content\");";
Cris' solution is also fine, but in some case you will need to have two sets of double quotes inside a string so you will be forced to do escaping correctly.
FYI: Escaping is the process of having special characters getting generated in a string which would otherwise cause issues, for instance in javascript you can't have newlines in a string, like this:
var mystring = 'on
a different line'; // <- this causes a syntax error
So one would do the following:
var mystring = 'on\na different line';
You forgot to include the jquery
<!DOCTYPE html>
<html>
<head>
<meta name="keywords" content="hello"/>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
function myFunction()
{
alert("Hello World!");
var tags=$('meta[name=keywords]').attr("content");
var gameurl = "http://xyz/abc/names/";
var jsn = ".json?callback=showGameDetail";
var finalUrl= gameurl.concat(tags).concat(jsn);
alert(finalUrl);
}
</script>
</head>
<body>
<button onclick="myFunction()">Try it</button>
</body>
</html>
Tough debatable, you can use an array, which can be concatenated by calling join():
var tags = $('meta[name=keywords]').attr("content");
var data = [
"http://xyz/abc/names/",
encodeURIComponent(tags),
".json?callback=showGameDetail"
].join('');
$("#demo").html(data);
Actually the concat method works on strings too (in chrome at least) but the recommended method is using the plus concatenation string operator
You are however missing some stuff
jQuery library - I assume you want that since you have $(...) in the example
encoding of the string from the keywords - I use encodeURIComponent to handle possible newlines and quotes in the keywords
.
<!DOCTYPE html>
<html>
<head>
<title>Create a URL from keywords</title>
<meta name="keywords" content="These are tags" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
function myFunction() {
var tags = $('meta[name=keywords]').attr("content");
var URL ="http://xyz/abc/names/" +
encodeURIComponent(tags) +
".json?callback=showGameDetail";
window.console && console.log(URL);
$("#demo").html(URL);
}
</script>
<body>
<p id="demo">Click the button to join two strings into one new string.</p>
<button onclick="myFunction()">Try it</button>
</body>
</html>

Element within iframe's div not accessible in the current code

I have 2 HTML files namely a.html and b.html, One js file namely do.js.
Here are each the contents of each file:
a.html:
<head>
<script src="do.js" type="text/javascript"></script>
</head>
<body>
<button onClick = "doWork();">click me</button>
<iframe src = "b.html" id = "previewFrame"></iframe>
</body>
b.html (relevant part):
<div id = "container"></div>
do.js:
function doWork(){
var div = $('#previewFrame').contents().find('#container');
div.html("<input type = 'text' id = 'testElem' value = '12'><script>alert(document.getElementById('testElem').value);</script>");
}
When I run the above code, the content of the iframe gets replaced by the text box, however the alert fails.
I get a "type error" stating that document.getElementById... is null.
Can anyone please tell me what am I missing in the above code?
You are calling the Javascript function using document, but this object is from the parent document, not the document of the iframe, try with:
function doWork(){
var a = $('#previewFrame').contents().find('body');
a.html("<input type = 'text' id = 'testElem' value = '12'><sc"+"ript>alert($('#previewFrame').contents()[0].getElementById('testElem').value);</scr"+"ipt>");
}
See demo here.

Can't update iframe content with jquery

iframe is loaded dynamically into container div inside function.
With cc.text(content); I try to update #code content.
I check changed text in runtime, it's updated but on screen value remains the same.
I am not a javascript pro, so any comments are welcome:
function ShowEditor(content) {
var url = "XmlEditor/Editor.htm";
slHost.css('width', '0%');
jobPlanContainer.css('display', 'block');
frame = $('<iframe id="' + jobPlanIFrameID + '" src="' + url + '" class="frame" frameborder="0" />');
frame.appendTo(jobPlanIFrameContainer);
$(frame).load(function () {
var ifr = frame[0];
var doc = ifr.contentDocument || ifr.contentWindow.document;
var jdoc = $(doc);
var cc = jdoc.contents().find("#code");
// var tst = cc.text();
// alert(tst);
cc.text(content);
});
}
I get the text in commented code, but fail to update #code content.
iframe holds the following html where I omit details inside head and script:
<!doctype html>
<html>
<head></head>
<body>
<form>
<textarea id="code" name="code">some texts</textarea>
</form>
</body>
</html>
Your XML editor doesn't read more than once what's in the textarea.
A simple solution would be to generate in javascript the iframe content with the desired textarea content instead of loading it and then try to change the textarea content.
In fact (depending on the capacities of your XML Editor), you probably can do that directly in a generated text area instead of using a whole iframe to do it.

Categories

Resources