سؤال

I want to invert and re-invert background image of the page (div) with a click on specific element. Now I have the script:

$(function(){
$(".invert").click(function(){
    $(".pattern").css({
    "-webkit-filter": "invert(100%)",
    "-moz-filter": "invert(100%)",
    "-o-filter": "invert(100%)",
    "-ms-filter": "invert(100%)"

    });
    $(".invert").addClass("reinvert");
    $(".invert").removeClass("invert");

});

$(".reinvert").click(function(){
    $(".pattern").css({
    "-webkit-filter": "invert(0%)",
    "-moz-filter": "invert(0%)",
    "-o-filter": "invert(0%)",
    "-ms-filter": "invert(0%)"

    });
    $(".reinvert").addClass("invert");
    $(".reinvert").removeClass("reinvert");
});
});

The invert function works fine, but it doesn't re-invert the element back.

I'd also like to make it work at least in Firefox and in other browsers if possible.

Update: Changed code to:

$(function(){
$(".invert").click(function(){
    $(".pattern").toggleClass("inverted");
    $(".invert").css("display", "none");
    $(".re-invert").css("display", "inline");
});
$(".re-invert").click(function(){
    $(".pattern").toggleClass("inverted");
    $(".re-invert").css("display", "none");
    $(".invert").css("display", "inline");
});
});

With CSS:

.inverted {
filter: invert(100%);
-webkit-filter: invert(100%);
-moz-filter: invert(100%);
-o-filter: invert(100%);
-ms-filter: invert(100%);
}

Which works fine (at least the way I wanted) in Chrome, but still looking for any way to make it work the same in Firefox. Thank you guys for help, sorry I don't have enough reputation to rate answers.

Here's the working code: http://jsfiddle.net/5AdxC/1/

Update 2: It seems like I found a way to make it work in Chrome and Firfox, but didn't test it with Opera or IE. http://jsfiddle.net/5AdxC/2/

CSS option for Firefox:

filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'invert\'><feColorMatrix in='SourceGraphic' type='matrix' values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0'/></filter></svg>#invert");
هل كانت مفيدة؟

المحلول

Your code as-is is working just fine!

See this fiddle with your code: http://jsfiddle.net/K5NJy/1/

Perhaps, the problem lies where you are swapping classes on the .invert and .reinvert element(s):

$(".invert").addClass("reinvert"); // perhaps this is causing unwanted behavior
$(".invert").removeClass("invert"); // perhaps this is causing unwanted behavior

And as @Shivan said, this will work only on webkit based browsers. Others do not support filter in this form.

Edit: (after your requisites of Firefox or Opera)

See this updated fiddle: http://jsfiddle.net/K5NJy/5/

This updated fiddle will work in Chrome, IE9 and Firefox. (I don't have Chrome installed so can't check, but webkit based browsers should anyway support it).

As mentioned above (and also by @Shivan), Firefox (Gecko) supports only the url() way of filters. So you need an SVG/XML map for that to work.

I lifted Firefox bit of code from here: https://stackoverflow.com/a/19691142/1355315

Also, note that the order of the application of css in your code will affect IE9 and Firefox. Whichever way of filter is applied last will hold. So, if url() one is applied last, it will work in Firefox but not in IE. So, you will have change that in fiddle to check.

Moreover, for older IE (<9) you will need to use DXImageTransform.Microsoft.Invert, which is deprecated in IE9 and above.

Hope that helps.

نصائح أخرى

For Firefox, Gecko currently only implements the url() form of the filter property; . IE 4-9 has another syntax of filter.

No such thing called -moz-filter, -ms-filter and -o-filter according to specification.

Reference: filter at MDN

Why have a '.invert' AND '.reinvert' when you can just toggle()?

Makes your code super easy, anyways here is my version of inverting only the bg and keeping everything else static within.

Also, instead of doing inline css, why not create classes in your stylesheet for the inverted, so the 'reverted' just does not use that class with the toggle effect? Makes the code more professional :-)

$(".reinvert").click(function(){
    $(".pattern").css({
    "-webkit-filter": "invert(100%)",
    "-moz-filter": "invert(100%)",
    "-o-filter": "invert(100%)",
    "-ms-filter": "invert(100%)"

    });
    $(".reinvert").addClass("invert");
    $(".reinvert").removeClass("reinvert");
});

With this , you'll be applying the filter to 100% again , there by going back to the original.

You can achieve this by clearing the filter:

$(".reinvert").click(function(){
    $(".pattern").css({
        "-webkit-filter": "",
        "-moz-filter": "",
        "-o-filter": "",
        "-ms-filter": ""
    });

    $(".reinvert").addClass("invert");
    $(".reinvert").removeClass("reinvert");
});

Working fiddle: http://jsfiddle.net/Ad4mD/.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top