Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, July 2, 2016

JavaScript: Invert color on all elements of a page

JavaScript: Invert color on all elements of a page


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.

Answer by Jacob Relkin for JavaScript: Invert color on all elements of a page


First things first, grab the awesome RGBColor class here.

Here goes:

jsFiddle example

//set up color properties to iterate through  var colorProperties = ['color', 'background-color'];    //iterate through every element in reverse order...  $("*").get().reverse().each(function() {      var color = null;        for (var prop in colorProperties) {          prop = colorProperties[prop];            //if we can't find this property or it's null, continue          if (!$(this).css(prop)) continue;             //create RGBColor object          color = new RGBColor($(this).css(prop));            if (color.ok) {               //good to go, let's build up this RGB baby!              //subtract each color component from 255              $(this).css(prop, 'rgb(' + (255 - color.r) + ', ' + (255 - color.g) + ', ' + (255 - color.b) + ')');          }          color = null; //some cleanup      }  });  

Screenshot:

alt text

EDIT: Here's a bookmarklet you can now copy-paste into your browser (http://jsfiddle.net/F7HqS/1/)

javascript:function load_script(src,callback){var s=document.createElement('script');s.src=src;s.onload=callback;document.getElementsByTagName('head')[0].appendChild(s);}function invertColors(){var colorProperties=['color','background-color'];$('*').each(function(){var color=null;for(var prop in colorProperties){prop=colorProperties[prop];if(!$(this).css(prop))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;}});}load_script('http://www.phpied.com/files/rgbcolor/rgbcolor.js',function(){if(!window.jQuery)load_script('https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js',invertColors);else invertColors();});  

Answer by i_grok for JavaScript: Invert color on all elements of a page


I figured it would be fun to try inverting images. Didn't take long to find an appropriate Javascript library for image editing: http://www.pixastic.com/lib/

You probably can't load that whole library into a bookmarklet, but if you host it yourself you can add something like this to the end of the bookmarklet (after invertColors):

load_script('http://www.example.com/pixastic.invert.js', function () {$('img').each(function() {try{$(this).pixastic("invert");} catch(e) {}})})  

I think it's worth noting that if your goal is to take a page with a white background and make it black (or vice versa), something simpler might be in order.

I just tried the bookmarklet from Jacob and compared it to a more naive version I found on the Google support forums: http://www.google.com/support/forum/p/Chrome/thread?tid=26affebdd0da12d9&hl=en

Jacob's invert seems to work less frequently and takes quite a bit longer on large pages. I think I'll end up using the naive version more frequently.

Answer by leosok for JavaScript: Invert color on all elements of a page


Hello fellow inverters!

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

enter image description here

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);  }());  

For me, this only works in chrome. But there it works like a charm.

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

Greets leosok

Answer by Zig Mandel for JavaScript: Invert color on all elements of a page


I cleaned up the comments from one of the answers (by leosok) above, so it will work as a bookmarklet in chrome. Note that this solution is more efficient than the current highest-point here, plus it works even if the html changes after you run the script.

javascript:(function () {       var css = 'html {-webkit-filter: invert(100%);' + '-moz-filter: invert(100%);' + '-o-filter: invert(100%);' + '-ms-filter: invert(100%); }';      var head = document.getElementsByTagName('head')[0];      var style = document.createElement('style');      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));      }      head.appendChild(style);  }());  

One line for bookmarklet. create a bookmark, then edit the url to this: javascript:(function () { var css = 'html {-webkit-filter: invert(100%);' + '-moz-filter: invert(100%);' + '-o-filter: invert(100%);' + '-ms-filter: invert(100%); }'; var head = document.getElementsByTagName('head')[0]; var style = document.createElement('style'); 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)); } head.appendChild(style); }());

Answer by astryk for JavaScript: Invert color on all elements of a page


The accepted answer is totally correct, with one minor flaw. Each time you toggle the invert it adds ANOTHER style tag to the head. Do this instead

  // the css we are going to inject    let css = 'html {-webkit-filter: invert(100%);' +      '-moz-filter: invert(100%);' +      '-o-filter: invert(100%);' +      '-ms-filter: invert(100%); }';      let head = $('head')[0];    let invertStyle = $('#invert')[0];      if (invertStyle) {      head.removeChild(invertStyle);    } else {      let style = document.createElement('style');        style.type = 'text/css';      style.id = 'invert';      if (style.styleSheet){        style.styleSheet.cssText = css;      } else {        style.appendChild(document.createTextNode(css));      }        //injecting the css to the head      head.appendChild(style);    }  

That way you simply remove the tag if you want to undo your invert. Works great!


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.