JavaScript: инвертировать цвет на всех элементах страницы - PullRequest
43 голосов
/ 22 января 2011

Примечание: я держу в своем вопросе актуальную версию букмарклета, которая хорошо работает и основана на ответе Джейкоба. Если вы ищете букмарклет для использования, используйте его. См. Фантастический ответ leosok, если вы просто хотите что-то удивительное, что работает на Chrome.

Я хочу иметь возможность инвертировать цвет всех элементов на странице с помощью букмарклета JavaScript. Я знаю, что для инвертирования цвета вы вычитаете каждое из шестнадцатеричных значений RGB из 255 (xFF), но кроме этого я не уверен, как поступить.

Как мне это сделать?

Использование jQuery приемлемо, и оно должно работать только в Chrome, хотя, если бы оно работало в Firefox, это было бы плюсом.

Это исключая изображения - цвета фона, текста и ссылок должны быть инвертированы. В основном все, что получает свой цвет от CSS.

UPDATE Вот обновленный букмарклет, который исправляет проблему вложенных элементов и будет работать на многих сайтах (включая этот)

UPDATE2 Добавлена ​​некоторая поддержка прозрачности, обработка элементов, которые имеют цвет фона по умолчанию rgba (0, 0, 0, 0). Больше сайтов теперь должно работать с обновленным.

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

Теперь работает с большинством сайтов, которые я пробовал. Однако фоновые изображения могут создавать проблемы.

Ответы [ 5 ]

71 голосов
/ 22 января 2011

Перво-наперво, возьми классный RGBColor класс здесь .

Вот так:

jsFiddle пример

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

Снимок экрана:

alt text

РЕДАКТИРОВАТЬ : вот букмарклет, который вы теперь можете скопировать и вставить в свой браузер (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();});
36 голосов
/ 26 апреля 2013

Здравствуйте, товарищи инверторы!

мое решение сейчас работает только для Chrome, но оно инвертирует все (включая изображения и фреймы), как показано здесь:

enter image description here

Также он не использует внешние библиотеки и очень прост: добавление -webkit-filter: invert(100%) к 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);
}());

Для меня это работает только в Chrome. Но там это работает как шарм.

Вот скрипка: http://jsfiddle.net/nikita_turing/jVKw6/3/ С букмарклетом в комплекте. Если у кого-то есть идея, как заставить его работать для Firefox (SVG-Filters?), То продолжайте!

Greets leosok

3 голосов
/ 24 сентября 2013

Я убрал комментарии из одного из ответов (от leosok) выше, так что он будет работать как букмарклет в Chrome.Обратите внимание, что это решение более эффективно, чем текущая наивысшая точка, плюс оно работает, даже если html изменяется после запуска сценария.

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

Одна строка для букмарклета.создайте закладку, затем отредактируйте ссылку на это: 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); }());

2 голосов
/ 19 ноября 2015

Принятый ответ является полностью правильным, с одним незначительным недостатком. Каждый раз, когда вы переключаете инвертирование, он добавляет ДРУГОЙ тег стиля к голове. Сделайте это вместо

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

Таким образом, вы просто удаляете тег, если хотите отменить инвертирование. Прекрасно работает!

1 голос
/ 28 августа 2011

Я подумал, что было бы интересно попробовать инвертировать изображения.Не потребовалось много времени, чтобы найти подходящую библиотеку Javascript для редактирования изображений: http://www.pixastic.com/lib/

Вы, вероятно, не сможете загрузить всю эту библиотеку в букмарклет, но если вы разместите ее самостоятельно, вы можете добавить что-то подобное вконец букмарклета (после invertColors):

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

Думаю, стоит отметить, что если ваша цель - взять страницу с белым фоном и сделать ее черным (или наоборот),что-то более простое может быть в порядке.

Я только что попробовал букмарклет от Джейкоба и сравнил его с более наивной версией, которую я нашел на форумах поддержки Google: http://www.google.com/support/forum/p/Chrome/thread?tid=26affebdd0da12d9&hl=en

Инверсия Джейкоба, кажется, работаетреже и занимает немного больше времени на больших страницах.Я думаю, что в конечном итоге я буду чаще использовать наивную версию.

...