The plan:
I have an iframe, called frame.html. If the frame.html is shown alone (not inside a page) it should load the no_frame.css.
If the frame.html is shown as an iframe inside a page it should load the frame.css.
The CSS should change divs inside the frame.html, so its important that the script check out if the page stays alone or inside an iframe. And I want to use this script in general for iframes, not only for the iframe.html.
Is there a better way to achieve this?
UPDATE:
#Alex K. - like this??:
<script type="text/javascript">
jQuery(document).ready(function($){
if (window!=window.top) { framed=true }
var cssId = 'myCss'; // you could encode the css path itself to generate id..
if (!document.getElementById(cssId))
{
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.id = cssId;
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'http://website.com/css/frame.css';
link.media = 'all';
head.appendChild(link);
}
});
Related
I want to know how can I load a css on a website before it loads.
I have tried the code below in main.js
win.webContents.on('did-start-loading', function () {
fs.readFile(__dirname + '/home.css', "utf-8", function (error, data) {
if (!error) {
var formatedData = data.replace(/\s{2,10}/g, ' ').trim()
win.webContents.insertCSS(formatedData)
}
})
})
It did work but the original style of the website popped up for few seconds and then it loaded my style, which makes zero sense if the original CSS and mine got whole different style.
I also tried loading the CSS below in preload.js
window.addEventListener("DOMContentLoaded", injecting)
function injecting() {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'https://example.com/hello.css';
document.documentElement.appendChild(link);
}
It also did not work. It keeps showing the original style and then loads my css after a second.
You cannot control the speed of the CSS download, but you can achieve a similar behavior. You could have body as:
<body class="invisible">
<!-- Some HTML here -->
</body>
and some helpful CSS
.invisible {
display: none;
}
Now, you could do
document.body.className = ""; once the CSS is loaded as:
window.addEventListener("DOMContentLoaded", injecting)
function injecting() {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'https://example.com/hello.css';
link.onload = (() => {document.body.className = "";});
document.documentElement.appendChild(link);
}
I'm trying to understand, why HTML5 Import doesn't work with dynamically created link element.
First example. It's work fine.
main_page.html:
<head>
<link rel="import" href="import.html">
</head>
<body>
<script>
var imported = document.querySelector('link[rel="import"]').import;
var el = imported.querySelector('#foo');
document.body.appendChild(el);
</script>
</body>
import.html:
<div id="foo">foo</div>
Second example. For some reason, it doesn't work.
main_page.html:
<body>
<script>
var link = document.createElement('link');
link.rel = 'import';
link.href = 'import.html';
document.head.appendChild(link);
var imported = document.querySelector('link[rel="import"]').import;
var el = imported.querySelector('#foo');
document.body.appendChild(el);
</script>
</body>
import.html:
<div id="foo">foo</div>
Why it occurs and how it may be fixed?
That would happen because the link is not yet loaded when you are calling querySelector('link[rel="import"]').
One way to fix it would be to run the subsequent code when the link is loaded using link.onload. You can even save that querySelector call, which should make it a bit faster:
var loadFoo = function(event) {
var imported = event.target.import;
var el = imported.querySelector('#foo');
document.body.appendChild(el);
}
var link = document.createElement('link');
link.rel = 'import';
link.href = 'import.html';
link.onload = loadFoo;
document.head.appendChild(link);
You could (and probably should) add an onerror handler to run when things go wrong.
I'm working with a CMS that prevents us from editing the head section. I need to add css stylesheet to the site, right after the tag. Is there a way to do this with JS, where I can add a script to the bottom of the page (I have access to add script right before the tag) that would then inject the stylesheet into the head section?
Update: According to specs, the link element is not allowed in the body. However, most browsers will still render it just fine. So, to answer the questions in the comments - one really has to add link to the head of the page and not the body.
function addCss(fileName) {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = fileName;
head.appendChild(link);
}
addCss('{my-url}');
Or a little bit easier with jquery
function addCss(fileName) {
var link = $("<link />",{
rel: "stylesheet",
type: "text/css",
href: fileName
})
$('head').append(link);
}
addCss("{my-url}");
Original answer:
You don't need necessarily add it to the head, just add it to the end of body tag.
$('body').append('<link rel="stylesheet" type="text/css" href="{url}">')
as Juan Mendes mentioned, you can insert stylesheet to the head instead
$('head').append('<link rel="stylesheet" type="text/css" href="{url}">')
And the same without jQuery (see code above)
This will do what you want in an intelligent way. Also using pure JS.
function loadStyle(href, callback){
// avoid duplicates
for(var i = 0; i < document.styleSheets.length; i++){
if(document.styleSheets[i].href == href){
return;
}
}
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
if (callback) { link.onload = function() { callback() } }
head.appendChild(link);
}
I've modified Eddie's function to remove or toggle the stylesheet on or off. It will also return the current state of the stylesheet. This is useful for example, if you want to have a toggle button on your website for vision-impaired users and need to save their preference in a cookie.
function toggleStylesheet( href, onoff ){
var existingNode=0 //get existing stylesheet node if it already exists:
for(var i = 0; i < document.styleSheets.length; i++){
if( document.styleSheets[i].href && document.styleSheets[i].href.indexOf(href)>-1 ) existingNode = document.styleSheets[i].ownerNode
}
if(onoff == undefined) onoff = !existingNode //toggle on or off if undefined
if(onoff){ //TURN ON:
if(existingNode) return onoff //already exists so cancel now
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
document.getElementsByTagName('head')[0].appendChild(link);
}else{ //TURN OFF:
if(existingNode) existingNode.parentNode.removeChild(existingNode)
}
return onoff
}
Sample usage:
toggleStylesheet('myStyle.css') //toggle myStyle.css on or off
toggleStylesheet('myStyle.css',1) //add myStyle.css
toggleStylesheet('myStyle.css',0) //remove myStyle.css
You can use pure javascript and still elegance in the modern browser.
const range = document.createRange()
const frag = range.createContextualFragment(`THE CONTENT IS THE SAME AS THE HTML.`)
document.querySelector("YOUR-NODE").append(frag)
It's very easy to add any HTML code.
Document
createRange
createContextualFragment
Example 1
Add the style on the head by javascript.
<head></head><body><button class="hover-danger">Hello World</button></body>
<script>
const range = document.createRange()
const frag = range.createContextualFragment(`
<style>
.hover-danger:hover{
background-color: red;
font-weight: 900
}
</style>
`
)
document.querySelector("head").append(frag)
</script>
Example 2
Import CSS, JS, and modify the existing stylesheet.
<head></head>
<body><button class="btn btn-primary hover-danger">Hello world</button></body>
<script>
const range = document.createRange()
const frag = range.createContextualFragment(`
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"/>
`)
document.querySelector("head").append(frag)
window.onload = () => {
// 👇 If you don't want to import the new source, you can consider adding the data to exists source.
const nodeLink = document.querySelector(`link[href^="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"]`) // ^: match begin with my input
if (nodeLink) { // !== null
const stylesheet = nodeLink.sheet
const myCSS = `
background-color:red;
font-weight: 900;
`
stylesheet.insertRule(`.hover-danger:hover{ ${myCSS} }`, stylesheet.cssRules.length)
}
}
</script>
📙 You must have permission to modify the CSS directly
If you get the error:
Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules,
then you can reference: https://stackoverflow.com/a/49994161/9935654
Here is a simple one-liner to add a stylesheet:
document.head.insertAdjacentHTML('beforeend', `<link typs="text/css" rel="stylesheet" href="<Source URL>">`);
When running in a web browser, I can do this to dynamically inject a stylesheet:
var link = document.createElement('link'),
head = document.getElementsByTagName('HEAD')[0];
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = '/path/to/stylesheet.css';
head.appendChild(link);
Is there a way to do the same in XULRunner? I've seen you can use something called Components.interfaces.mozIJSSubScriptLoader to load JavaScript, but does the same capability exist for CSS?
You can try using the style sheet service. Something like:
var sss = Cc["#mozilla.org/content/style-sheet-service;1"]
.getService(Ci.nsIStyleSheetService);
var ios = Cc["#mozilla.org/network/io-service;1"] .getService(Ci.nsIIOService);
var uri = ios.newURI("chrome://pluginname/skin/notes.css", null, null);
if(!sss.sheetRegistered(uri, sss.USER_SHEET)) {
sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
}
More examples.
I am building a javascript widget and i need to add my widget css and js files dynamicly to the client page.
I am doing this for now:
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute('href', 'css path');
document.getElementById('test').appendChild(css);
alert(document.getElementById('test').innerHTML);
But it does not add the element to the dom.
The alert shows correctly.
What i am missing?
EDIT1:
Here is the updated code: (note that this is only a test page).
<html>
<head>
</head>
<body>
<div id="test">
test
</div>
<script type="text/javascript">
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute("type", "text/css");
css.setAttribute('href', 'path');
var header = document.getElementsByTagName("head")[0];
header.appendChild(css);
alert(header.innerHTML);
</script>
</body>
</html>
header.InnerHtml appears correct but nothing is added to the page.
have you tried to append the css into the <head> section ?
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute('href', 'css path');
document.getElementsByTagName('head')[0].appendChild(css);
I think you need to attach it to the of your html, not simply the document:
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute("type", "text/css");
css.setAttribute('href', 'css path');
var header = document.getElementsByTagName("head")[0];
header.appendChild(css);
Hope this helps :)