Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
26
rated 0 times [  28] [ 2]  / answers: 1 / hits: 57172  / 14 Years ago, sat, january 22, 2011, 12:00:00

Note: I am keeping an up-to-date version of the bookmarklet in my question which works well and is based on Jacob's answer. If you are looking for a bookmarklet to use, use that one. See leosok's fantastic answer if you just want something amazing that works on chrome.



I want to be able to invert the color of all the elements on a page with a JavaScript bookmarklet. I know that to invert a color you subtract each of the RGB hex values from 255(xFF), but beyond that I am unsure of how to proceed.



How can I accomplish this?



Using jQuery is acceptable, and it only needs to work on Chrome, although if it worked in Firefox that'd be a plus.



This is excluding images - background, text and links colors should all be inverted. Basically anything that gets its color from CSS.



UPDATE
Here is an updated bookmarklet that fixes the nested element issue and will work on a lot of different sites (including this one)



UPDATE2
Added some support for transparency, handling elements that have default background-color rgba(0, 0, 0, 0). More sites should be working now with the updated one.



javascript: (function ($) {
function load_script(src, callback) {
var s = document.createElement('script');
s.src = src;
s.onload = callback;
document.getElementsByTagName('head')[0].appendChild(s);
}

function invertElement() {
var colorProperties = ['color', 'background-color'];
var color = null;
for (var prop in colorProperties) {
prop = colorProperties[prop];
if (!$(this).css(prop)) continue;
if ($(this).data(prop) != $(this).css(prop)) continue;

if (($(this).css(prop) === 'rgba(0, 0, 0, 0)') || ($(this).css(prop) === 'transparent')) {
if ($(this).is('body')) {
$(this).css(prop, 'black');
continue;
} else {
continue;
}
}
color = new RGBColor($(this).css(prop));
if (color.ok) {
$(this).css(prop, 'rgb(' + (255 - color.r) + ',' + (255 - color.g) + ',' + (255 - color.b) + ')');
}
color = null;
}
}

function setColorData() {
var colorProperties = ['color', 'background-color'];
for (var prop in colorProperties) {
prop = colorProperties[prop];
$(this).data(prop, $(this).css(prop));
}
}

function invertColors() {
$(document).live('DOMNodeInserted', function(e) {
var $toInvert = $(e.target).find('*').andSelf();
$toInvert.each(setColorData);
$toInvert.each(invertElement);
});
$('*').each(setColorData);
$('*').each(invertElement);
$('iframe').each(function () {
$(this).contents().find('*').each(setColorData);
$(this).contents().find('*').each(invertElement);
});
}
load_script('http://www.phpied.com/files/rgbcolor/rgbcolor.js', function () {
if (!window.jQuery) load_script('https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', invertColors);
else invertColors();
});

})(jQuery);


Now works with most sites I've tried. Background images can pose a problem, however.


More From » jquery

 Answers
17

My solution seems to work only for Chrome right now, but it inverts everything (including images and iframes) as seen here:


enter


Also it does not make use of external libraries and is very simple: adding a -webkit-filter: invert(100%) to the html-selector.


javascript: (
function () {
// the css we are going to inject
var css = 'html {-webkit-filter: invert(100%);' +
'-moz-filter: invert(100%);' +
'-o-filter: invert(100%);' +
'-ms-filter: invert(100%); }',

head = document.getElementsByTagName('head')[0],
style = document.createElement('style');

// a hack, so you can "invert back" clicking the bookmarklet again
if (!window.counter) { window.counter = 1;} else { window.counter ++;
if (window.counter % 2 == 0) { var css ='html {-webkit-filter: invert(0%); -moz-filter: invert(0%); -o-filter: invert(0%); -ms-filter: invert(0%); }'}
};

style.type = 'text/css';
if (style.styleSheet){
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}

//injecting the css to the head
head.appendChild(style);
}());

Here's the fiddle: http://jsfiddle.net/nikita_turing/jVKw6/3/ with the bookmarklet included. If someone has an idea of how to make it work for Firefox (SVG-Filters?), go ahead!


[#94102] Thursday, January 20, 2011, 14 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
katianatasham

Total Points: 293
Total Questions: 110
Total Answers: 103

Location: Saint Helena
Member since Mon, Jun 28, 2021
3 Years ago
;