inject CSS link into head prior to existing CSS link - javascript

I would like to inject some CSS into the head using link tags. I can get this to work pretty easily using
var linkNode = document.createElement('link');
linkNode.href = '"+ jqueryTablesorterCSS_URL +"';
linkNode.type = 'text/css';
linkNode.rel = 'stylesheet';
documentHead.appendChild(linkNode);
However I would like to have another already existing link tag be the last item in the head as it needs to take precedence. I do not have control over this other link tag and it already exists on the page.
Moving the other element by finding it like this does not seem to work.
var documentHead = document.head;
var customCSSNode = documentHead.querySelector("link[href$='custom.css']");
documentHead.appendChild(customCSSNode);

I feel kind of gross for suggesting this as it seems "wrong", though also seems to work when I tested it. I think if you wait for the load event on the new css you can reload the existing by adding it back to the the "head" with appendChild
Note in this sandbox "head" is actually "body".
You can manually play with the ordering of the two css files, but I believe the effect you want is correctly applied when this result shows a split background with a rose in the center/right.
If the rose is on the left or if the background is not a rose then I have failed.
You may need to open the demo in full screen. Sorry these were two easily grabbed CSS files to try to replicate what you are after.
var documentHead = document.body;
var existingNode = document.getElementById("existing");
var linkNode = document.createElement('link');
linkNode.type = "text/css";
linkNode.rel = "stylesheet";
linkNode.onload = function(){ documentHead.appendChild(existingNode); }
linkNode.href = "http://www.csszengarden.com/220/220.css";
documentHead.appendChild(linkNode);
<link id="existing" rel="stylesheet" type="text/css" href="http://www.csszengarden.com/120/120.css" />
<div>Success if background pink rose in center</div>
<div>Fail if background pink rose on left</div>
<div>fail if kind of blue hand print</div>

Related

how to add css styling inside javascript?

Actually i am using iframe element in html page but it is inside tag which means javascript. so I want to add css to that iframe element, how can I do that? Can someone help please
Styles from the parent will not be applied to the document within the iframe. The best solution is to add the stylesheet to the document in the iframe. Either via javascript or creating a template page to load in via src.
Something like:
var head = doc.head
var link = doc.createElement('link')
link.type = 'text/css'
link.rel = 'stylesheet'
link.href = ...src...
head.appendChild(link)
This is an example: link
yourElement.style.attribute = value
for example
var button = document.getElementById("btn")
button.style.color = "red"
button.style.marginTop = 0;
when writing css in javascript you must use camel case css for example type marginTop not type the margin-top

Place HTML and CSS in my iframe using javascript

I'm building an html preview tool inside a small project and I'm trying to find the best way to place html and the css that will style that html inside an iframe.
I'm able to create the iframe and place the html contents of my div inside. So far that seems to be working correctly in this fiddle
$(function() {
var $html = $("#html").html();
var $frame = $('<iframe>');
$('body').html( $frame );
var doc = $frame[0].contentWindow.document;
var $framehtml = $('html',doc);
$framehtml.html($html);
});
But how do I add css to the head of that iframe? For example, adding the class .mobile you see in the fiddle to the head of the iframe so the image is hidden when the iframe reaches a width of 500px?
EDIT: I don't want to inject a css style sheet. I'd rather create a tag in the head and place the css you see in the fiddle.
#FRAN and #APAD1 were right, this is a duplicate. I was able to use those answers to create my own with this updated fiddle
var $head = $("#myframe").contents().find("head");
$head.append($("<style/>",
{type: "text/css" }));
var $style = $("#myframe").contents().find("style");
$style.append($css);

The margins in div of new tab not at all taking effect

Hi I am creating dynamic form in new tab using JavaScript. Margin effects on div are not taking effect. I am neither able to set the margins using class and id in css nor using div.setAttribute. Below is the code.
`
var openWindow = window.open('dynForm.html','_blank','');
var windoc=openWindow.document;
windoc.write("This is dynamic form ");
var div=document.createElement("div");
div.setAttribute("style","border:solid");
div.setAttribute("style","margin-left:1cm");
div.setAttribute("style","margin-right:1cm");
div.setAttribute("style","margin-bottom:1cm");
div.setAttribute("style","margin-top:1cm");
div.setAttribute("style","background-color:lightblue");
`Only background color is taking effect on the new tab. The below screen shot shows how the screen looks irrespective of the values of margin.
Quesstion 2: No class or id attribute in my css is being applied to div.
#myDIV2{
background-color:lightblue;
}
I tried div.id="myDIV2";
I also tried div.setAttribute("id","myDIV2");` I applied the same using class also, but still couldn't find any difference. I do not know why its not working and what went wrong here. Please help
You're overriding the styles every time you call setAttribute, try combining the styles and then set the style attribute only once:
var openWindow = window.open('dynForm.html','_blank','');
var styles= [
"border:solid;",
"margin: 1cm;",
"background-color:lightblue;"
];
var windoc=openWindow.document;
windoc.write("This is dynamic form ");
var end_styles = "";
for (var i=0; i<styles.length;i++) {
end_styles += styles[i];
}
var div=document.createElement("div");
div.setAttribute("style", end_styles);
Note: the fiddle won't work on stackoverflow, I used it because it's easier to format code
This is happening because your all style attribute are getting overridden by previous div.setAttribute and your last attribute div.setAttribute("style","background-color:lightblue"); getting applied. Try to put all styles in one go. div.setAttribute("style","style1:value1;style2:value2;style3:value3;");

Live editor that allows for editing of an iframe's HTML and CSS within a textarea (or similar.)

Okay, to preface, I am not an overly experience programmer. My area is predominantly in HTML and CSS, so I'm a little stuck here, and I've searched high and low online and can't find what I need; whether that's bad phrasing on my part or lack of information, I'm not sure, haha.
THE LIVE VERSION
HTML
<select ONCHANGE="document.getElementById('display-inner').src = this.options[this.selectedIndex].value">
<option value="http://tessisamess.com/freeedit.html">Free Edit</option>
<option value="http://tessisamess.com/completestyle.html">Complete Style</option>
<option value="http://tessisamess.com/generator.html">Generator</option>
JQUERY
$(function() {
function change() {
var iFrame = document.getElementById('display-inner');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
iFrameBody.innerHTML = document.getElementById('input-inner').value;
}
});
What I'm trying to accomplish:
I'm creating a live editor for the users that I generally create layouts for, and I've got Free Edit mode and the Save function all in working order. I've also got my two base layouts that are often restyled uploaded and displayed in iframes, and you can call either layout or Free Edit from a dropdown to display on the right, next to the editor.
The goal here is for you to be able to click any of the three modes, and then code on the left and see your updates effect what's already in the iframe to the right rather than clearing it and replacing it with your textarea content (which is what it currently does.)
What needs to function, and doesn't:
When you click Complete Style or Generator, the textarea (left) needs to display the base code that people use to style each layout. When you start editing that side, either by using the code generated for you, or replacing it with a premade layout edit, the changes effect the iframe it's connected to on the right. (example: Adding a background image to body will change the page background in the iframe, and so on.)
The purpose:
I'm using this as a tool to give the users who frequently use my free layouts on the site, who have trouble editing them using the site's very out of date resources. I'd like them to be able to throw in my custom CSS and edit it as they please so they can take it back to the site and implement it on their actual journals.
Note that I AM okay with having to change how this already functions if need be. I'd rather it work correctly than stick within what I already have. I'm not really looking to upload TinyMCE, but if options are slim then hey. Nothing for it, right?
$(function() {
function change() {
var iFrame = document.getElementById('display-inner');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
iFrameBody.innerHTML = document.getElementById('input-inner').value;
}
});
$(function() {
function saveTextAsFile()
{
var textToWrite = document.getElementById('input-inner').value;
var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
var fileNameToSaveAs = "mycode_tessisamess.txt";
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null)
{
// Chrome allows the link to be clicked
// without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
}
else
{
// Firefox requires the link to be added to the DOM
// before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
var button = document.getElementById('save');
button.addEventListener('click', saveTextAsFile);
});
#import url(https://fonts.googleapis.com/css?family=Open+Sans);
::selection{background:#EAA2B9;}
::-moz-selection{background:#EAA2B9;}
body,html{height:100%;}
body{margin:0;}
#input, #display{display:inline-block;height:100%;vertical-align:top;overflow:hidden;}
#input{position:relative;background:#ddd url(http://i.imgur.com/wBSwx5F.jpg)center no-repeat fixed;width:35%;-webkit-box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);}
#controls{font-family:Open Sans,Helvetica,arial,sans-serif;font-size:13px;text-align:right;height:24px;background:#fff;padding:7px;border-bottom:1px solid #ccc;-webkit-box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);}
.c-button, select, option{background:#fff;cursor:pointer;border:1px solid rgba(0,0,0,0.3);border-radius:4px;padding:2px 10px;margin:0 2px;font-family:Open Sans,Helvetica,arial,sans-serif;}
#input-inner{position:absolute;bottom:4px;top:38px;width:97%;margin:0;background:transparent;border:none;padding:10px;color:#000;overflow:auto;}
input:focus, textarea:focus, select:focus, option:focus{outline:none;}
#display{width:65%;}
#display-inner{height:100%;overflow:auto;border:none;width:100%;}
#display-inner p{max-width:600px;display:block;margin:0 auto;padding:100px;text-align:justify;font-family:Open Sans,Helvetica,arial,sans-serif;line-height:150%;font-size:115%;color:#444;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<form id="input">
<div id="controls">Options:
<select ONCHANGE="document.getElementById('display-inner').src = this.options[this.selectedIndex].value">
<option value="http://tessisamess.com/freeedit.html">Free Edit</option>
<option value="http://tessisamess.com/completestyle.html">Complete Style</option>
<option value="http://tessisamess.com/generator.html">Generator</option>
</select>
<button type="button" value="save" id="save" class="c-button">save</button>
<input type="reset" class="c-button" value="clear">
</div>
<textarea id="input-inner" onkeyup="change();" placeholder="You are in Free Edit mode! You can paste your code here, or start coding from scratch.
To style a layout instead, select your base from the dropdown above, and start with the base CSS given to create a new layout, or replace it with the free layout coding you wish to edit.
All changes will appear on the righthand side as you make them."></textarea>
</form><!---
---><div id="display">
<iframe id="display-inner" src="http://tessisamess.com/freeedit.html">
</iframe>
</div>
</body>
This would be a very long answer if I were to cover all the aspects of what needs to happen for you to get it working the way you need it, so instead I'll give you some helpful hints.
You can get to the document of the iFrame from your main page with: document.getElementById('MY_IFRAME_ID').contentWindow.document
The Element.outerHTML and Element.innerHTML properties will be your best friend in retrieving and updating page code.
To display HTML, you can do: iframeDocument.getElementsByTagName('html')[0].outerHTML and that will contain the HTML for the entire page, including all the inline css/js. If you need the doctype also, read this. Insert all that into textarea.
To make updates you can grab the html from your textarea and insert it back with Element.innerHTML like so: iframeDocument.getElementsByTagName('html')[0].innerHTML = htmlFromTextarea
For the external css/js, you'll need a proper way to display the code, but I'll leave it to you to figure out the details of that.
To get the external css you just have to iterate over iframeDocument.styleSheets, and use a similar strategy as the one mentioned above, although there are some cross browser considerations you might want to keep in mind.
For external js, you can find them in a similar fashion. Iterate over iframeDocument.getElementsByTagName('script') and get their content with Element.innerHTML
You could implement strategies for updating just sections instead of the entire document each time, but that's a bit more involved. I recommend taking the "update entire document" route until you have a better understanding of the moving parts.
Syntax highlighting would be immensely helpful, so consider putting your code inside a code editor like "Ace".
I hope this helps and good luck! Please don't forget to check this answer as correct if you felt that it addresses your question.

How to conditionally apply different backgrounds to a canvas

The code shown here may be useful to others: It shows the solution I came up with to a requirement I had to, conditionally, apply different background images to a canvas. Questions on how to achieve this or variations of this have been asked here before.
(Sorry for my botched editing. I had originally posted this as a question, then, while reading my posted code, the answer dawned on me, so I removed that part of the post. I didn't realise at the time that there were already two answers, which would make no sense to anyone who didn't see the original question. So, to summarize it: I couldn't work out why functions I had added to someone else's published code that I was adapting couldn't be accessed by my function calls. I didn't realise that the code I was inserting them into was "wrapped" inside an anonymous IFFE function. When I moved them below the end of the "wrapper", I was able to call them from outside the IFFE.)
Thanks javinor, for the link to that very informative article explaining the IFFE function.
As for the method shown below, I have since found a better way to do it. I learned that div elements do not really belong in the HTML head section, so this is a better way:
var lnk;
lnk = document.createElement('LINK');
lnk.rel = 'stylesheet';
lnk.type = 'text/css';
lnk.href = 'CanvasStylesA.css';
document.getElementsByTagName('head')[0].appendChild(lnk);
You can wrap a condition around the href line that decides which file to use.
HTML
<head>
<div id="conditionalCSSincludes">
<!--
The javascript below will insert an inner div section here called "CanvasStyles", which
will, conditionally, contain one of the following two lines. That line will link to one of
two external style sheets containing the canvas style for the canvas displayed by this page.
<link rel="stylesheet" type="text/css" href="CanvasStylesA.css">
<link rel="stylesheet" type="text/css" href="CanvasStylesB.css">
The two style sheets differ with respect to the background image set for Canvas1.
A sets it to A.jpg, B sets it to B.jpg.
-->
</div>
<script src="code.js" type="text/javascript"></script>
<!-- the javascript below goes here -->
</head>
<body>
<canvas width="530" height="530" id="Canvas1">
<p>This page will not display correctly because your browser does not support the canvas element. Sorry.</p>
</canvas>
</body>
Javascript
<script type="text/javascript">
var includesDiv1, includesDiv2, includesDiv3, dt, hour, Bgnd;
// Conditional code that, depending on page load time, chooses
// whether to display the night-time or daytime background
dt = new Date();
hour = dt.getHours();
// for testing, enable the line below and set the hour manually ...
// hour = 6;
if (hour < 6 || hour >= 18){Bgnd = 1;} else{Bgnd = 2;}
// These are the two versions of the include link to the external style sheets:
includesDiv1 = '<div id="CanvasStyles"> <link rel="stylesheet" type="text/css" href="CanvasStylesA.css"> </div>';
includesDiv2 = '<div id="CanvasStyles"> <link rel="stylesheet" type="text/css" href="CanvasStylesB.css"> </div>';
if (Bgnd==1){
includesDiv3 = includesDiv1; // use the night-time background image
}
else{
includesDiv3 = includesDiv2; // use the daytime background image
}
// Insert into the conditionalCSSincludes div above an inner div called "canvasStyles".
// It contains an html include link to an external css file containg canvas styles.
cssIncludesDiv = document.getElementById("conditionalCSSincludes");
cssIncludesDiv.innerHTML = includesDiv3;
just below
window.startClock = startClock;
window.stopClock = stopClock;
add
window.yourFunctionName = yourFunctionName
do that for your three functions, so they will be available in the global (window) scope
#pawel hit the button, everything defined within the IIFE (function () {}()) cannot be accessed outside of the IIFE scope.
Take a look at this very enlightening explanation about modules and namespaces.

Categories

Resources