JavaScript: инвертировать цвет по всем элементам страницы
Примечание. Я сохраняю обновленную версию букмарклета в моем вопросе, который хорошо работает и основан на ответе Якоба. Если вы ищете букмарклет для использования, используйте его. Посмотрите на отличный leosok ответ, если вы просто хотите что-то потрясающее, которое работает на хроме.
Я хочу иметь возможность инвертировать цвет всех элементов на странице с помощью букмарклета 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);
Теперь работает с большинством сайтов, которые я пробовал. Однако фоновые изображения могут создавать проблемы.
Ответы
Ответ 1
Привет, коллеги-инверторы!
Теперь мое решение работает только для хрома, но оно инвертирует все (включая изображения и фреймы), как показано здесь:
![enter image description here]()
Также он не использует внешние библиотеки и очень прост: добавление -webkit-filter: invert(100%)
в 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);
}());
Для меня это работает только в хроме. Но там это работает как шарм.
Здесь скрипка: http://jsfiddle.net/nikita_turing/jVKw6/3/
С включенным закладкой. Если у кого-то есть идея, как заставить его работать в Firefox (SVG-фильтры?), Продолжайте!
здоровается
leosok
Ответ 2
Прежде всего, возьмите класс RGBColor
здесь.
Здесь:
//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 null, continue
if (!$(this).css(prop)) continue;
//create RGBColor object
color = new RGBColor($(this).css(prop));
if (color.ok) {
//good to go, let 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();});
Ответ 3
Я очистил комментарии от одного из ответов (по leosok) выше, поэтому он будет работать как букмарклет в хроме. Обратите внимание, что это решение более эффективно, чем текущая высшая точка здесь, плюс работает, даже если html изменяется после запуска 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);
}());
Одна строка для букмарклета. создайте закладку, затем отредактируйте URL-адрес:
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); }());
Ответ 4
Принятый ответ абсолютно прав, с одним незначительным недостатком. Каждый раз, когда вы переключаете инверсию, она добавляет к тегу стиль еще один стиль. Сделайте это вместо
// 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);
}
Таким образом вы просто удаляете тег, если хотите отменить инвертирование. Отлично работает!
Ответ 5
Я решил, что было бы интересно попробовать инвертировать изображения. Не потребовалось много времени, чтобы найти подходящую библиотеку 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) {}})})
Я думаю, стоит отметить, что если ваша цель - взять страницу с белым фоном и сделать ее черной (или наоборот), может быть что-то проще.
Я просто попробовал букмарклет от Jacob и сравнил его с более наивной версией, которую я нашел на форумах поддержки Google:
http://www.google.com/support/forum/p/Chrome/thread?tid=26affebdd0da12d9&hl=en
Инверт Jacob работает менее часто и занимает довольно много времени на больших страницах. Я думаю, что я больше использую наивную версию чаще.