window.getComputedStyle not working for shorthand

2020-02-11 04:05发布

问题:

window.getComputedStyle give the style's value in Chrome, but in firefox and Microsoft Edge it gives an empty string and in Internet Explorer, it say that it doesn't support that method. Here is my code.

Whenever the Upvote image is clicked it fires the upDownVote() function, passing two arguments. This is the HTML.

 <div id="upvote" title="Click to UpVote" onClick="upDownVote('increment',<?php echo $id; ?>);"></div>
 <div id="downvote" title="Click to DownVote" onClick="upDownVote('decrement',<?php echo $id; ?>);"></div>

I passed three variables to my php script through ajax; Id, type, applicable. Type can store one value, either increment or decrement.

I wanted, even upvote button is clicked. Vote value is increase by 1 and background of button is changed. Same for the button downvote, but here is decrease in vote value. I handle this with type variable.

When upvote is clicked again (or double clicked by the user), then there must be decrement in vote value not increment. I handled this with a nested if condition inside the if condition (when type is increment). In that condition I checked if applicable is greater than one. If it is, I changed the type to decrement and applicable to 0, also the background to its original image.

But what if when user clicked the upvote button after the clicking the downvote button. In that condition applicable value is more than 1. And then must change the type to decrement. That should not happen. for this In my that nested if condition I add check the background of downvote button also. It must be the same as before when the page load.

when applicable value is more than 1 (when user clicked upvote before clicking the downvote). In my php script I increase the vote value by two.

Same logic for the downvote button.

and here is the JavaScript.

var applicable = 0; // determine applicable to vote or not.
var upvote = document.getElementById("upvote"); 
var downvote = document.getElementById("downvote");

var upvoteBlack = window.getComputedStyle(upvote).getPropertyValue("background");
var downvoteBlack = window.getComputedStyle(downvote).getPropertyValue("background");

function upDownVote(x, id) {
    debugger;
    var type = x; // determine the type(increment or decrement).
    if (type === "increment") { 
        upvote.style.background = "url(img/image-sprite-1.jpg) 0px -40px";

        applicable++; // increment in the applicable.
        if (applicable > 1 && window.getComputedStyle(downvote).getPropertyValue("background") === downvoteBlack) { 
            type = "decrement"; 
            applicable = 0;
            upvote.style.background = "url(img/image-sprite-1.jpg) 0px 0px";
        }
        downvote.style.background = "url(img/image-sprite-1.jpg) -40px 0px";
    } else {
        downvote.style.background = "url(img/image-sprite-1.jpg) -40px -40px";
        applicable++;
        if(applicable > 1 && window.getComputedStyle(upvote).getPropertyValue("background") === upvoteBlack) {
            type = "increment";
            applicable = 0;
            downvote.style.background = "url(img/image-sprite-1.jpg) -40px 0px";
        }
        upvote.style.background = "url(img/image-sprite-1.jpg) 0px 0px";
    }

    // Ajax started here.
}

CSS of upvote and downvote.

div#upvote {
    width: 40px;
    height: 40px;
    background: url(../img/image-sprite-1.jpg);
    background-position: 0px 0px;
    margin: 0px auto;
    margin-top: 10px;
    cursor: pointer;
}
div#downvote {
    width: 40px;
    height: 40px;
    background: url(../img/image-sprite-1.jpg) -40px 0px;
    background-position: -40px 0px;
    margin: 0px auto;
    cursor: pointer;
}

Everything works fine but now I'm stuck. How to get the background value of buttons as window.getComputedStyle not working fine all the browsers. I want to know is there any other property by which I can have the background property.

Also, I want to know how can I do the same thing with different logic. If I can't have the solution for window.getComputedStyle.

回答1:

The shorthand property problem

background is a shorthand property, a combination of background related properties. When you set a background of pink, it is actually setting a number of background properties, just one of which is backgroundColor. For instance, it is probably actually doing the equivalent of rgb(255, 165, 0) none repeat scroll 0% 0% / auto padding-box border-box.

getComputedStyle will not return the value of shorthand properties, except in Chrome as you've discovered.

To get the computed style, look for the value of primitive properties such as backgroundColor, not that of shorthand properties such as background.

A different approach?

However, this is not really how you want to be doing things. Instead of setting styles on your elements directly, you're going to find your code to be much cleaner if you add and remove classes from your elements, and then define the rules for the classes. As you've found, setting styles directly on elements may require you to then go back and query the style, whereas with classes, you can easily query the existing class with elt.classList.has(), or toggle with .toggle(), or add, or remove.

More on getComputedStyle

getComputedStyle is a rather specialized API that should only be necessary in special situations.

For more on the issue of getComputedStyle and shorthand properties, see this question. A bug was reported against FF and you can find it here.

See this MDN page. It says that CSSStyleDeclaration (which is what is returned by getComputedStyle) has a getPropertyCSSValue method which

returns ... null for Shorthand properties.