How do you make a bookmarklet change page icon? - javascript

Before I begin, this is NOT a duplicate. To explain my goal, I want a bookmark that, when clicked, changes the page icon WITHOUT loading a new tab. Other similar questions gave your bookmarklet an icon, but nothing accomplished what I wanted.
Here is the code I have right now:
data:text/html; charset=utf-8, <html><link rel="shortcut icon" href="http://link-to-my-icon.info/favicon.ico"></html>
It works, but it changes my tab. I want to keep the tab open, but edit the HTML to change the page icon. I've tried using
javascript: document.write(<link rel="shortcut icon" href="http://transparent-favicon.info/favicon.ico">);
as well, but it does absolutely nothing, while my first attempt at least changes the icon.
Any help would be greatly appreciated, thanks.

Checkout this gist and the demo.
//source: https://gist.github.com/mathiasbynens/428626
document.head || (document.head = document.getElementsByTagName('head')[0]);
function changeFavicon(src) {
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = src;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}

Related

How do I retain toggle state across website?

So, I have a button that toggles between dark and light mode (my site is dark by default) and it works but now I need it to stay on whatever toggle state is selected across multiple pages. I suspect it has something to do with sessionstorage. Not using jQuery and don't want to. What can I just add to my code to make that happen?
I have five pages all linked to styles.css with an id of "dark" and then in the JS I'm referencing a second style sheet, light.css or 'light' in the JS, so I'm toggling the style sheets. All five pages have the button in the footer each with the same function written in one JS file.
HTML
<head>
<link rel="stylesheet" href="styles.css" id="dark">
</head>
<body>
<button onclick="toggle();" id="light-mode"><i class="fas fa-adjust"></i></button>
</body>
JavaScript
function toggle() {
var a = document.getElementById("dark");
a.x = 'light' == a.x ? 'styles' : 'light';
a.href = a.x + '.css';
}
This works perfectly, just not sure how to integrate sessionstorage or localstorage to save the toggle state across the site. What is the best method proceeding from this point if possible or should I do a complete overhaul?
UPDATE
So, tried #Reality's answer and not working but I think I might just be integrating it wrong. Very new to JS.
localStorage.setItem('toggled','true');
function toggle() {
var a = document.getElementById("dark");
a.x = 'light' == a.x ? 'styles' : 'light';
a.href = a.x + '.css';
if (localStorage.getItem('toggled') === 'false') {
localStorage.setItem('toggled','true');
} else {
localStorage.setItem('toggled','false');
}
}
SOLVED
Ok, anyone wanting to know how to toggle a theme perfectly where it works across your website, just follow this: https://dev.to/albertomontalesi/add-dark-mode-to-your-website-with-just-a-few-lines-of-code-5baf
When you follow that, you should do an additional thing to have your theme load better when toggled to. Just link to your second style sheet in the head of every page and add disabled="disabled" If you don't add this to the above approach, I found that when toggling to whatever theme and then navigating around the site, you basically have to load a new style sheet and you get a flicker and can even see the bare HTML version of the site momentarily, so this addition fixes that because by putting it in the head it is already loaded from the beginning.
FINAL
Here's what ended up working:
<head>
<link rel="stylesheet" href="dark-theme.css" type="text/css" id="theme">
<link rel="stylesheet" href="light-theme.css" type="text/css" disabled="disabled">
<script>
document.addEventListener('DOMContentLoaded', () => {
const themeStylesheet = document.getElementById('theme');
const storedTheme = localStorage.getItem('theme');
if (storedTheme) {
themeStylesheet.href = storedTheme;
}
const themeToggle = document.getElementById('theme-toggle');
themeToggle.addEventListener('click', () => {
if (themeStylesheet.href.includes('dark')) {
themeStylesheet.href = 'light-theme.css';
} else {
themeStylesheet.href = 'dark-theme.css';
}
localStorage.setItem('theme', themeStylesheet.href);
});
});
</script>
</head>
Per #Reality's suggestion, placing the JS in the head improved performance better than what the SOLVED edit suggested doing, however, the code in the link provided (https://dev.to/albertomontalesi/add-dark-mode-to-your-website-with-just-a-few-lines-of-code-5baf) is what is used in the above example. Still needed the disabled="disabled" in the light-theme.css link or else it would override the dark-theme.css and the toggle wouldn't occur all together. This was true of all the code examples seen in this thread that were tried.
You can set it using localStorage.setItem(); and localStorage.getItem().
localStorage.setItem('toggled','true');
//or
localStorage.setItem('toggled','false');
inside your toggle function:
//get the style by it's id
let a = document.getElementById("dark");
if(localStorage.getItem('toggled') === 'false'){
//set toggled to true, because the user clicked it when dark theme is on
localStorage.setItem('toggled','true');
//toggled is now on, in this case, light theme is switched on
//do something here
a.href = "light.css";
}
else{
//set toggled to false, because the user clicked it when light theme is on
localStorage.setItem('toggled','false');
//if toggled is off, in this case, dark theme is switched on
a.href = "styles.css";
}
It seems confusing at first, but just pay attention to the logic. It'll start to unfold in your mind as you read and reread it :)
If you want to switch to session storage (for that tab instance. Once you close the tab, session storage for that tab is deleted), then just replace the "localStorage" with "sessionStorage". Please keep in mind that localStorage and sessionStorage stringify values (convert them into a string) before storing them.

Adding CSS to new document created by Javascript

I'm trying to create a blank document with Javascript, and then import the CSS file I already have with it.
Here is my code:
function printData() {
let ptimetable = document.getElementById("timetable");
let printWin = window.open("");
printWin.document.write(ptimetable.outerHTML);
let hd = printWin.document.getElementByTagName("head")[0];
let link = printWin.document.createElement("link")
link.rel = "stylesheet";
link.type = "text/css";
link.href = "../css/main.css";
hd.appendChild(link);
//printWin.print();
//printWin.close();
}
I can't figure out what I'm doing wrong - the document is created, but the CSS from my file doesn't apply to the table.
Any help would be much appreciated!
Thanks!
R
After the comments I've seen, the problem resides in the incorrect CSS link. There's also an issue with one of the functions that I have seemingly just made up in my head. Thanks everyone

How to refresh the page on document.write

I am using document.write in a function to give different CSS to user's based on their choosing.
function blue() {
document.write('<link rel="stylesheet" type="text/css" href="http://ilam.irib.ir/documents/697970/237563314/blue.css" />');
}
I am calling the function from an anchor tag.
function color2(){
document.getElementById("navigation").innerHTML +='<a class="myButton" onclick="blue()" background-color:"#05c8f2";></a>';
}
As you can guess, when the link is clicked, the page clears out and I get a blank page.
Is there any way to fix this problem? I don't want to stop page refreshing, I'm just trying to fix the problem in any way possible!
Note: don't ask why I'm adding code using JavaScript, and not directly into HTML code. This site is a large scale system and we just have access to JavaScript and CSS. So this is all we can do to edit our pages.
document.write rewrites the body , as a result the only thing in your document remains is the css file you added and hence it is blank.
View this
Code from above link :-
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/stylesheet.css';
link.media = 'all';
head.appendChild(link);
}
Instead of rewriting while dom , we append the link element inside head tag

Can I display favicon from inside an iframe?

I have another site running inside a webpage as an iframe. However it's not displaying the favicon. I think it's not possible but just wanted to double confirm if someone knows of a way.
May be something like this in your child page i.e. page inside iFrame :
(function() {
var link = parent.document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = 'http://www.stackoverflow.com/favicon.ico';
parent.document.getElementsByTagName('head')[0].appendChild(link);
}());
You can set a favicon by modifying the HTML, i.e. by adding:
<link rel="shortcut icon" type="image/png" href="/favicon.png"/>
to the <head> (or changing the existent link).
You can also access DOM of the top document if both the top document and the iframe are on the same domain.
Example:
master = window.parent.document;
head = master.getElementsByTagName("head")[0];
favicon = master.createElement("link");
favicon.rel = "shortcut icon";
favicon.type = "image/png";
favicon.href = "//cdn.sstatic.net/stackoverflow/img/favicon.ico?v=038622610830";
head.appendChild(favicon);
sets the icon of the page to Stack Overflow favicon.

FireFox 3.6 - 9 drops favicon when changing window.location

Problem exists only on FireFox (from 3.6 up to current 9), other browsers are fine. My code looks like this:
jQuery.extend({
AnchorFromUrl : function(url) {
var anchor = url.substr(1).replace('.html','');
$.fizzer_anchor = anchor;
window.location.hash = anchor;
return anchor;
}
});
The most weird thing is that if I place an alert before the window.location.hash = anchor; line, after clicking Ok favicon doesn't disappear, remove that alert() and you get your favicon disappearing.
Note: it also drops the favicon if you just do window.location = something.
I had the same problem, but found this interesting post and it worked for me, its just adding 2 lines of javascript.
The problem occure when the hash element changes, so, we need to re-stablish it via javascript
http://kilianvalkhof.com/2010/javascript/the-case-of-the-disappearing-favicon/
this is the code
function setFavicon() {
var link = $('link[type="image/x-icon"]').remove().attr("href");
$('<link href="'+ link +'" rel="shortcut icon" type="image/x-icon" />').appendTo('head');
}
Or (thanks to Mottie) using jQuery detach
$('link[type*=icon]').detach().appendTo('head');
It worked for me :
var link = document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = 'FAV_ICON_URL';
document.getElementsByTagName('head')[0].appendChild(link);
Refer : Changing Website Icon Dynamically
I noticed this behaviour, too. Every now and then Firefox drops a favicon or it refuses to put the favicon alongside my bookmark. I think this is a Firefox bug.
To workaround this (and for other functionality), I installed the Favicon Picker add-on. Of course, this doesn't solve your problem on other computers, like clients and the like.

Categories