web-dev-qa-db-fra.com

JavaScript: Inverser la couleur sur tous les éléments d'une page

Note: Je garde une version à jour du bookmarklet dans ma question qui fonctionne bien et est basée sur la réponse de Jacob. Si vous recherchez un bookmarklet à utiliser, utilisez-le. Voir la réponse fantastique de leosok si vous voulez juste quelque chose d’extraordinaire qui fonctionne avec le chrome.

Je veux pouvoir inverser la couleur de tous les éléments d'une page avec un bookmarklet JavaScript. Je sais que pour inverser une couleur, vous soustrayez chacune des valeurs hexadécimales RVB de 255 (xFF), mais au-delà de cela, je ne sais pas comment procéder.

Comment puis-je accomplir cela?

Utiliser jQuery est acceptable et cela ne doit fonctionner que sur Chrome, bien que si cela fonctionnait dans Firefox, ce serait un plus.

Ceci exclut les images - les couleurs de l’arrière-plan, du texte et des liens doivent toutes être inversées. Fondamentalement, tout ce qui tire sa couleur de CSS.

UPDATE Voici un bookmarklet mis à jour qui résout le problème des éléments imbriqués et fonctionnera sur de nombreux sites différents (y compris celui-ci).

UPDATE2 Ajout de la prise en charge de la transparence, du traitement des éléments dont la couleur d'arrière-plan est par défaut rgba (0, 0, 0, 0). Plus de sites devraient travailler maintenant avec le mis à jour.

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

Fonctionne maintenant avec la plupart des sites que j'ai essayés. Les images d'arrière-plan peuvent toutefois poser problème.

43
Muhd

Bonjour chers inverseurs!

ma solution ne semble fonctionner que pour chrome pour le moment, mais elle inverse tout (y compris les images et les iframes), comme indiqué ici:

enter image description here

De plus, il n’utilise pas de bibliothèques externes et est très simple: ajouter une -webkit-filter: invert(100%) au sélecteur html-.

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

Pour moi, cela ne fonctionne qu'en chrome. Mais là ça fonctionne comme un charme.

Voici le violon: http://jsfiddle.net/nikita_turing/jVKw6/3/ Avec le Bookmarklet inclus. Si quelqu'un a une idée, comment le faire fonctionner pour Firefox (filtres SVG?), Allez-y!

Greets Leosok

35
leosok

Tout d’abord, prenez l’impressionnant RGBColor classe ici .

Voici: 

jsFiddle exemple

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

Capture d'écran: 

alt text

EDIT: Voici un bookmarklet que vous pouvez maintenant copier/coller dans votre navigateur ( 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();});
71
Jacob Relkin

J'ai nettoyé les commentaires de l'une des réponses (par leosok) ci-dessus, de sorte que cela fonctionnera comme un bookmarklet en chrome. Notez que cette solution est plus efficace que le point culminant actuel ici, et qu’elle fonctionne même si le code HTML change après l’exécution du 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);
}());

Une ligne pour bookmarklet. créez un signet, puis modifiez l'URL en ceci: 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); }());

3
Zig Mandel

La réponse acceptée est tout à fait correcte, avec un défaut mineur. Chaque fois que vous basculez l'inversion, elle ajoute une autre balise de style à la tête. Faites ceci à la place 

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

De cette façon, vous supprimez simplement la balise si vous souhaitez annuler votre inversion. Fonctionne très bien!

2
astryk

Je pensais que ce serait amusant d'essayer d'inverser des images. Nous n’avons pas tardé à trouver une bibliothèque Javascript appropriée pour l’édition d’images: http://www.pixastic.com/lib/

Vous ne pouvez probablement pas charger toute la bibliothèque dans un bookmarklet, mais si vous l'hébergez vous-même, vous pouvez ajouter quelque chose comme ceci à la fin du bookmarklet (après invertColors):

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

Je pense que cela vaut la peine de noter que si votre objectif est de prendre une page avec un fond blanc et de la noircir (ou vice-versa), il est peut-être préférable de choisir quelque chose de plus simple.

Je viens d'essayer le bookmarklet de Jacob et de le comparer à une version plus naïve que j'ai trouvée sur les forums d'assistance de Google: http://www.google.com/support/forum/p/Chrome/thread?tid= 26affebdd0da12d9 & hl = fr

L'inverseur de Jacob semble fonctionner moins souvent et prend un peu plus de temps sur les grandes pages. Je pense que je vais finir par utiliser la version naïve plus fréquemment.

1
i_grok