Dynamically Add Code to IFrame without Reloading HTML or Javascript - javascript

Weave: http://kodeweave.sourceforge.net/editor/#5dbb5ce4a85bcaf4c5805e337c829e73
I have three textareas:
1 for HTML
1 for CSS
and 1 for JavaScript code
Whenever code is added in these textareas (I'm using keyup for the same of this post) I call a function called runEditor which adds the code into the iframe.
What I'm trying to figure out is how can I call the same function when CSS is added without adding the HTML or the JavaScript again?
var htmlEditor = document.querySelector(".html")
var cssEditor = document.querySelector(".css")
var jsEditor = document.querySelector(".js")
function runEditor() {
var previewFrame = document.querySelector(".preview")
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document
preview.open()
preview.write("<style>"+ cssEditor.value +"</style>" + htmlEditor.value + "<scr"+"ipt>"+ jsEditor.value +"</scr"+"ipt>")
preview.close()
}
runEditor()
htmlEditor.onkeyup = function() {
runEditor()
}
cssEditor.onkeyup = function() {
runEditor()
}
jsEditor.onkeyup = function() {
runEditor()
}
textarea {
width: 30%;
height: 100px;
}
.preview {
width: 100%;
}
<textarea class="html">
<button>
Hello world
</button>
<div class="output"></div>
</textarea>
<textarea class="css">body {
background: #52b165;
}</textarea>
<textarea class="js">
var output = document.querySelector(".output")
var btn = document.querySelector("button")
var counter = 0
function addElm() {
var node = document.createElement("div")
var txt = document.createTextNode("hi " + counter++)
node.appendChild(txt)
output.appendChild(node)
}
btn.addEventListener("click", function() {
addElm()
})
</textarea>
<iframe class="preview" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts"></iframe>

When you set up the iframe, you have access to both window and document objects inside the iframe. You have access to methods like document.getElementById and friends.
To reload the CSS, suggesting you create a <style> element in the iframe. When CSS changes, wipe out the contents of that element and put in the new CSS. HTML can do the same, wiping out the HTML of <body> and replacing it with the new HTML. innerHTML will be your friend. JS will be a bit tricky. You will need to recreate the iframe from the beginning to start fresh.

Related

Change Element href Right Before Drag

I'm creating an extension that allows me to drag photo links in some website that doesn't allow it. The element (photoCell) has a default href of "javascript://" and has a child element (photo) which holds the image.
I want to be able to change the href of the parent element to the src of the child image so when i drag, i drag the URL of the child image. (This works if i do it without a drag listener but then when i click on an element it loads the image and not the expected javascript function). So i need to change the href back to "javascript://" after drag is done.
However, even though the href changes the dragged URL still is "javascript://"
function dragstart() {
this.href = this.children[0].src;
}
function dragend() {
this.href = "javascript://";
}
function doForPicturedesk() {
var gallaryCells = document.getElementsByClassName("gallery-cell");
for (var i = 0; i < gallaryCells.length; i++) {
var gallaryCell = gallaryCells[i];
var photoCell = element.children[0];
photoCell.addEventListener("dragstart", dragstart);
photoCell.addEventListener("dragend",dragend);
}
}
Here's a sample of the HTML
<div class="gallery-cell jg-entry entry-visible" style="width: 534px; height: 345px; top: 10px; left: 10px;">
<a href="javascript://" onclick="openPictureDetail('343563491-516813675371465101')" class="gallery-cell__link gallery-cell__image--hoverable">
<img id="thumb_343563491-516813675371465101" class="gallery-cell__image " src="/bild-disp/diasdb/thumbnailextl.action?ref=343563491-516813675371465101&w=false" onerror="correctMissing(this, '343563491-516813675371465101');" style="width: 534px; height: 356px; margin-left: -267px; margin-top: -178px;">
</a>
</div>
enter code here
I didn't think was possible, but what do I know. All you have to do is use dataTransfer.setData to achieve your goal. Try it below:
let anchor = document.querySelector('a');
anchor.ondragstart = function(event) {
let urlWeWant = 'https://www.example.com';
event.dataTransfer.types.forEach(type => {
//Note that all you HAVE to do for this to work is:
//event.dataTransfer.setData(type, urlWeWant);
//BUT, I think checking the type and replace HTML is better
if (type.includes('html')) {
let clone = event.target.cloneNode(true);
clone.href = urlWeWant;
let dataHTML = clone.outerHTML
event.dataTransfer.setData(type, dataHTML);
} else {
event.dataTransfer.setData(type, urlWeWant);
};
});
};
<a href='javascript:void(0);'>Drag Me Into Another Window :)</a>

Javascript, I can't with the sun to reach the above items to a iframe

I have to create the effect of a popup using a DIV with DOM, I used an iframe, inside the frame is a form, I can not get rid of the div with Javascript in the submit button because the DOM sees only after the iframe his creation and not the div that contains it ... how should I do?
<html>
<body >
<h1>Title</h1>
</body>
</html>
//Global variable which contain reference to divPopup's element
var divPopup;
function hideDiv() {
window.alert("Content of DIV POPUP " + divPopup );
divPopup.className = "overlayHidden";
}
function load_page() {
var nodoDiv = document.createElement("DIV");
divPopup = nodoDiv;
nodoDiv.className = "overlay";
nodoDiv.setAttribute("id", "popup1");
//nodoDiv.addEventListener("click", function () { hideDiv(); }, false);
document.body.appendChild( nodoDiv );
var nodoDivPopup = document.createElement("DIV");
nodoDivPopup.setAttribute("id", "popup2");
nodoDivPopup.className = "popup";
var elem = document.getElementById("popup1");
divPopup = elem;
elem.appendChild( nodoDivPopup );
var nodoDivEsami= document.createElement("DIV");
nodoDivEsami.setAttribute("id", "contenitoreEsami");
nodoDivEsami.className = "content";
var elem = document.getElementById("popup2");
elem.appendChild( nodoDivEsami );
var nodoIFrame = document.createElement("IFRAME");
nodoIFrame.className = "content";
nodoIFrame.setAttribute("src", "esami_da_importare_TEST.html");
var nodoDivEsami = document.getElementById("contenitoreEsami");
nodoDivEsami.appendChild( nodoIFrame );
//window.alert( document.body.innerHTML );
}
_______file css
.overlayHidden{
visibility:hidden;
opacity:0;
}
the function hideDiv() is in the form, activated onClick on submit button.
the window.alert( ) in function hideDiv return "undefined"...
I think you're trying too hard, as iFrames are notoriously problematic. You don't need to use an iFrame, and you can predefine your DIVs in the HTML (unless you really need to create the DIV dynamically). For example:
<div id="popup1" class="overlayHidden">
<div id="contenitoreEsami" class-"content">
...
</div>
</div>
No code is needed for page load. When you want to display the pop-up, change its class to something that isn't hidden.

CKEditor: is it possible to make img inline editable with contenteditable="true"

I'm trying to get CKEditor up and running with Inline Editing, and I want to allow users to only edit single dom elements like h1, h2, p, ect. and it's working fine - but I can't get it to work for html img element:
<img src="img/myimage.jpg" contenteditable="true" />
Images are working fine if I allow CKEditor to insert images into eg. a div element, but is there a way to only allow the content editor to update the src for img tag?
UPDATE
I have solved this with simple jQuery:
$(document).ready(function () {
$('img[contenteditable]').click(function (event) {
var view = $(event.target);
var uniqueIdforCurrentElement = randomString(32).trim();
if (view.attr('id') === undefined || view.attr('id') === '') {
view.attr('id', uniqueIdforCurrentElement);
} else {
uniqueIdforCurrentElement = view.attr('id');
}
window.open('mySelectImageUrl' +
'?mode=jquery" +
'&CKEditorFuncNum=' + uniqueIdforCurrentElement,
'imageWindow',
'width=800, height=600');
});
});
and in imageWindow:
var element = window.opener.document.getElementById('<%:Model.Callback%>');
element.src = fileUrl;

Display java script preload banner before html document loaded - Pure Javascript

I need to be able to show an advertisement banner using JavaScript while the page is loading (before other HTML elements are loaded). I've tried the following, but it only loads a few seconds after the rest of the body content has loaded:
document.onreadystatechange = function () {
if (document.readyState != 'uninitialized') checkCookie();
}
How should I go about making the ad load before the other HTML elements? Thank you!
first you can set
body { display: none; }
and then call the preload function to load all the required images. like this
preload('image1.jpg,image2.jpg,image3.jpg');
and at the end of function you can change style of body tag to make it visible again.
.visible { display: block; }
function preload(images) {
if (document.images) {
var i = 0;
var imageArray = new Array();
imageArray = images.split(',');
var imageObj = new Image();
for(i=0; i<=imageArray.length-1; i++) {
//document.write('<img src="' + imageArray[i] + '" />');// Write to page (uncomment to check images)
imageObj.src=imageArray[i];
}
// ------ add class to body tag to make it visible again
var d = document.getElementsByTagName("body")[0];
d.className = d.className + " visible";
}
}
You can execute JavaScript is in a script tag before the document is parsed:
<head>
<script>
// your script here
alert(); //for example
</script>
</head>

How to print only a selected HTML element?

I am trying to implement a print feature in HTML. I know I can print the whole page with window.print(), but how do I print only a specific page element? For example a particular <DIV>Some text to print</DIV>.
You could use a print specific CSS stylesheet and hide everything but what you want printed.
<div class="no-print">I won't print</div><div class="something-else">I will!</div>
Just the no-print class will be hidden, but anything with a print class will show.
<style type="text/css" media="print">
.no-print { display: none; }
</style>
If you are familiar to jQuery, you can use jQuery Print Element plugin like this:
$('SelectorToPrint').printElement();
Created something generic to use on any HTML element
HTMLElement.prototype.printMe = printMe;
function printMe(query){
var myframe = document.createElement('IFRAME');
myframe.domain = document.domain;
myframe.style.position = "absolute";
myframe.style.top = "-10000px";
document.body.appendChild(myframe);
myframe.contentDocument.write(this.innerHTML) ;
setTimeout(function(){
myframe.focus();
myframe.contentWindow.print();
myframe.parentNode.removeChild(myframe) ;// remove frame
},3000); // wait for images to load inside iframe
window.focus();
}
Usage:
document.getElementById('xyz').printMe();
document.getElementsByClassName('xyz')[0].printMe();
Hope this help
Regards
Gaurav Khurana
Simple html and pure javascript works best. Parameter "this" refers to current id, so that function is universal for all ids. By using "ref.textContent" instead of "ref.innerHTML" you can extract only textual content for printing.
html body:
<div id="monitor" onclick="idElementPrint(this)">element to print
<img src="example.jpg" width="200">
</div>
pure javascript:
/*or:
monitor.textContent = "click me to print content";
const imga = new Image(200); //width
imga.src = "./example.jpg";
monitor.appendChild(imga);
*/
const idElementPrint = ref => {
const iframe = document.createElement("iframe");
iframe.style.display = "none";
document.body.appendChild(iframe);
const pri = iframe.contentWindow;
pri.document.open();
pri.document.write(ref.innerHTML);
pri.document.close();
pri.focus();
pri.print();
pri.onafterprint = () => { document.body.removeChild(iframe); }
}
If you are using JQuery, you can use clone to do the following:
function printElement(e) {
var ifr = document.createElement('iframe');
ifr.style='height: 0px; width: 0px; position: absolute'
document.body.appendChild(ifr);
$(e).clone().appendTo(ifr.contentDocument.body);
ifr.contentWindow.print();
ifr.parentElement.removeChild(ifr);
}
and use like so:
printElement(document.getElementById('myElementToPrint'))
If I understood you well you can use CSS3 to print your selected HTML element.
#media print {
body.print-element *:not(.print) {
display: none;
}
}
Notice, that you just need a selector. This allows you to easily print an element or the entire page using CSS classes.
Here you can check a working example: https://jsfiddle.net/gengns/d50m8ztu/
If you're using bootstrap, just add classname d-print-none to the elements you don't want to display in print
I found a solution that doesn't have the problems other solutions have. It copies the printed element to the body, and is fairly elegant and general:
CSS:
#media print {
body *:not(.printable, .printable *) {
// hide everything but printable elements and their children
display: none;
}
}
JS:
function printElement(e) {
let cloned = e.cloneNode(true);
document.body.appendChild(cloned);
cloned.classList.add("printable");
window.print();
document.body.removeChild(cloned);
}
The only limitation is that the element loses styles it inherited from its previous parents. But it works on arbitrary elements in the document structure
If you need to print the HTML element with pure JS, you can open a window that contains only the element you want to print (without any HTML-markup).
For instance, you can print the image itself without wrapping it in any HTML by opening this image in a new window as a file.
Note: 'visible=none' doesn't actually make the window invisible, but it allows to open it as a separate window (not a tab).
afterprint event allows us to close the window when the printing dialog is closed. event.target points to the opened window instance.
Note: afterprint MUST be assigned before calling .print(), otherwise it would not be called.
let win = window.open('/absolute/image/path.jpg', '__blank', 'visible=none');
win.addEventListener('afterprint', event => event.target.close() );
win.print();
Printing an Html or a Selected Html is easy using Print.Js
Add Print.Js Library
http://printjs.crabbly.com/
<form method="post" action="#" id="printJS-form">
...
</form>
<button type="button" onclick="printJS('printJS-form', 'html')">
Print Form
</button>
Add this method
function printDiv(divName) {
let specific_element = document.getElementById(divName).innerHTML;
let original_elements = document.body.innerHTML;
document.body.innerHTML = specific_element;
window.print();
document.body.innerHTML = original_elements;
}
This implementation will create and apply an ad-hoc temporary style that hides all the elements on print media except the one that we want to print. After the printing the temporary style is removed, so your document will get back to its initial state.
Feel free to adjust the ad-hoc style (like papar size, margins, etc) to fit your needs.
/**
* #description Print the given element using browser built-in function
* #param {HTMLElement} element
*/
function printElement(element) {
if (!element) {
throw new Error(`Invalid print target element`);
}
const printWrapper = "print-wrapper";
const printElement = "print-element";
const css = `
body.${printWrapper} *:not(.${printElement}) {
visibility:hidden;
}
body.${printWrapper} .${printElement} {
width: 210mm;
height: 297mm;
left:0;
top:0;
position:fixed;
}
body.${printWrapper} .${printElement} * {
visibility:initial;
margin: 0;
}
`;
const head = document.getElementsByTagName("head")[0];
const style = document.createElement("style");
style.setAttribute("type", "text/css");
style.setAttribute("media", "print");
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
document.body.classList.add(printWrapper);
element.classList.add(printElement);
window.print();
document.body.classList.remove(printWrapper);
element.classList.remove(printElement);
head.removeChild(style);
}
The simplest way to do it is:
elem = document.getElementById('elem').outerHTML
orig = document.documentElement.outerHTML
document.documentElement.outerHTML=elem
print()
document.documentElement.outerHTML = orig
function printDomElement(element) {
element.classList.add("printCss");
let printId = "printSvgId";
let name = ".printCss";
let rules = "-webkit-print-color-adjust:exact;height:100%;width:100%;position:fixed;top:0;left:0;margin:0;";
var style = document.createElement('style');
style.id = printId;
style.media = "print";
document.getElementsByTagName('head')[0].appendChild(style);
if (!(style.sheet || {}).insertRule)(style.styleSheet || style.sheet).addRule(name, rules);
else style.sheet.insertRule(name + "{" + rules + "}", 0);
window.print();
setTimeout(() => {
element.classList.remove("printCss");
let elem = document.getElementById(printId);
if (elem) elem.remove();
}, 500);
}
Set the style of the element you want to print to position:fixed,then make it cover the whole page.
Here is another (perhaps a more modern?) solution:
<link rel="stylesheet" media="print" href="print.css">

Categories

Resources