JavaScript:反转页面所有元素的颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4766201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript: Invert color on all elements of a page
提问by Muhd
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.
注意:我在我的问题中保留了书签的最新版本,它运行良好并且基于 Jacob 的回答。如果您正在寻找要使用的书签,请使用该书签。如果您只想要在 chrome 上运行的惊人的东西,请参阅 leosok 的精彩答案。
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.
我希望能够使用 JavaScript 书签反转页面上所有元素的颜色。我知道要反转颜色,您需要从 255(xFF) 中减去每个 RGB 十六进制值,但除此之外我不确定如何进行。
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.
使用jQuery
是可以接受的,它只需要在 Chrome 上工作,但如果它在 Firefox 中工作,那就更好了。
This is excluding images - background, text and links colors should all be inverted. Basically anything that gets its color from CSS.
这不包括图像 - 背景、文本和链接颜色都应该反转。基本上任何从 CSS 获取颜色的东西。
UPDATEHere is an updated bookmarklet that fixes the nested element issue and will work on a lot of different sites (including this one)
更新这是一个更新的书签,它修复了嵌套元素问题,并将在许多不同的站点上工作(包括这个站点)
UPDATE2Added 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.
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);
Now works with most sites I've tried. Background images can pose a problem, however.
现在适用于我尝试过的大多数网站。然而,背景图像可能会造成问题。
采纳答案by leosok
Hello fellow inverters!
各位逆变器,大家好!
my solution seems to work only for chrome right now, but it inverts everything (including images and iframes) as seen here:
我的解决方案现在似乎只适用于 chrome,但它会反转所有内容(包括图像和 iframe),如下所示:
Also it does not make use of external libraries and is very simple: adding a -webkit-filter: invert(100%)
to the html
-selector.
此外,它不使用外部库并且非常简单:将 a 添加-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);
}());
For me, this only works in chrome. But there it works like a charm.
对我来说,这只适用于 chrome。但在那里它就像一个魅力。
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!
这是小提琴:http: //jsfiddle.net/nikita_turing/jVKw6/3/包括书签。如果有人对如何使其适用于 Firefox(SVG 过滤器?)有想法,请继续!
Greets leosok
问候 leosok
回答by Jacob Relkin
First things first, grab the awesome RGBColor
class here.
首先,在这里抓住真棒RGBColor
课程。
jsFiddle example
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
}
});
Screenshot:
截屏:
EDIT: Here's a bookmarklet you can now copy-paste into your browser (http://jsfiddle.net/F7HqS/1/)
编辑:这是一个书签,您现在可以将其复制粘贴到浏览器中(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();});
回答by Zig Mandel
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.
我清除了上面一个答案(由 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);
}());
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); }());
书签的一行。创建一个书签,然后将 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); }());
回答by astryk
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!
这样,如果您想撤消反转,您只需删除标签。效果很好!
回答by i_grok
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/
我认为尝试反转图像会很有趣。没多久就找到了一个合适的 Javascript 库来进行图像编辑: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):
您可能无法将整个库加载到书签中,但是如果您自己托管它,您可以在书签的末尾添加类似的内容(在 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 的书签,并将其与我在 Google 支持论坛上找到的更幼稚的版本进行了比较: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.
Jacob 的反转似乎不太频繁,并且在大页面上需要更长的时间。我想我最终会更频繁地使用天真的版本。