【问题标题】:How to remove :hover css rule from stylesheet如何从样式表中删除 :hover css 规则
【发布时间】:2017-07-23 13:55:11
【问题描述】:

我正在开发一个基于 jQuery 和 javascript 的项目。我正在尝试使用 javascript insert/addRule 属性添加 CSS 规则。我想做的是:

我必须创建悬停效果并使用 javascript css 属性将它们插入到样式表中。为此,我创建了两个类,例如:

.dummy {.... }

.dummy:hover{.....}

我想要如果我改变悬停效果,那么它必须从样式表中删除前一个(或重复的)并将新规则插入到样式表中。

但问题是,如果我尝试使用 deleteRule 或 removeRule 删除或删除 CSS 规则,它只会删除

.dummy{...} 规则但不是 .dummy:hover{...}

这是我的代码,可以帮助你理解我在做什么:

function createNewStyle() {
    var style = document.createElement("style");
    style.setAttribute('id', 'd-set-stylesheet');
    style.appendChild(document.createTextNode(""));
    document.head.appendChild(style);
} // this function might be not required but included here so that you may understand the program flow.

//the main issue is with this function.
function removeIfExists(class_name) {
    var styleTag = document.getElementById("d-set-stylesheet");
    var styleRef = styleTag.sheet ? styleTag.sheet : styleTag.styleSheet;
    if (styleRef.rules) { //all browsers except IE 9-
        console.log(styleRef);
        for (var i in styleRef.cssRules) {
            if (styleRef.cssRules[i].selectorText === "." + class_name+":hover" ||styleRef.cssRules[i].selectorText === "." + class_name )
                styleRef.deleteRule(i);
        }
    } else {
        var i;
        for (i = 0; i < styleRef.rules.length; i++) {
            //if(styleRef.rules[i].selectorText === "."+class_name || styleRef.rules[i].selectorText === "."+class_name+":hover")
            styleRef.removeRule(i);
        }
    }
    return styleRef;
}

 //this function maybe not related with the issue but if it is you can check it.
function setNewClass(element, class_name, classSelector, styleObject) {
    var stylesheet = removeIfExists(class_name);
    if (element.data('hover-class') == null)
        element.data('hover-class', class_name);
    let count = 0;
    var style = [];
    var property = [{
        "append": ":hover"
    }, {
        "append": ""
    }];
    for (j = 0; j < 2; j++) {
        style.push({});
        style[j].sheet = stylesheet;
        style[j].selector = class_name;
        style[j].type = classSelector;
        style[j].property = property[j]["append"];
        style[j].style = "";
    }
    for (i in styleObject) {
        if (styleObject.hasOwnProperty(i))
            if (count % 2 == 0)
                style[0].style += styleObject[i] + ":";
            else
                style[0].style += styleObject[i] + ";";
        count++;
    }
    style[1].style = "transition:" + styleObject.t_property_value;
    addCSSRule(style);
}

function addCSSRule(styleSheet) {
    console.log(styleSheet);
    for (i = 0; i < styleSheet.length; i++)
        if (styleSheet[i].sheet.insertRule)
            styleSheet[i].sheet.insertRule(styleSheet[i].type + styleSheet[i].selector + styleSheet[i].property + "{" + styleSheet[i].style + "}", styleSheet[i].sheet.cssRules.length);
        else
            styleSheet[i].sheet.addRule(styleSheet[i].type + styleSheet[i].selector + styleSheet[i].property, styleSheet[i].sheet.style, -1);
}

这是 console.log 的图片 在第一张图片中,悬停和不悬停类被添加到 CSS 规则中。

在第二张图片中,前一个悬停类没有被删除,而没有悬停类被删除。我想必须删除悬停过渡。在添加新规则以防止类重复之前,应防止在悬停元素时进行多次转换。

谢谢。

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    我今天找到了答案。我将对其进行解释,以便将来帮助其他人了解问题和解决方案。

    通过我的问题,你可以理解这个问题。问题仅在于此功能

    function removeIfExists(class_name) {
     ......
    if (styleRef.rules) { //all browsers except IE 9-
        for (var i in styleRef.cssRules) {
               .....
                styleRef.deleteRule(i); //problem is with this.
               .....
        }
       }
      .......
       return styleRef;
    }
    

    当我根据一些测试检查 deleteRule 时,我发现调用 deleteRule 时会发生以下情况:

    1. 基于索引删除css规则。
    2. (最重要的,因为没有关于此的文档或澄清或解释)内容会随着他们的索引而更新。这样我的函数将不再能够在旧索引的基础上删除正确的规则。

    为了更好的理解,我举个例子:

    假设,我在 css 中添加了两条规则,例如:.dummy:hover{...}.dummy{...}

    现在这些规则的索引如下:

    [0]: .dummy:hover rule
    [1]: .dummy rule
    

    当我调用删除规则时会发生什么:

    // at i =0; 
    deleteRule(0);/* will be called and it will remove [0]: .dummy:hover rule
     and then it will update the rules indexing again, which means
     [1]: .dummy rule => [0]: .dummy rule */
    // now when i = 1;
    deleteRule(1); /* will be called and it will try to remove [1]: .dummy rule which is not here anymore and it will just skip the removal of [1]: .dummy rule.
    

    所以我要删除它是开始从最高索引中删除规则或以相反的顺序删除规则,这意味着 i = 1 规则将首先被删除,然后 i=0;规则,以免产生任何后果。

    函数会变成这样:

    function removeIfExists(class_name)
    {
        ...
        var styleRef = styleTag.sheet ? styleTag.sheet : styleTag.styleSheet;
        var len = styleRef.cssRules ? styleRef.cssRules.length : styleRef.rules.length;
        if(styleRef.rules){ //all browsers except IE 9-
            for(i=len;i>0;i--)
            {
                    if (styleRef.cssRules[i-1].selectorText === "." + class_name+":hover" ||styleRef.cssRules[i-1].selectorText === "." + class_name )
                    styleRef.deleteRule(i-1);
            }
        }
        ......
        .....
        }
        return styleRef;    
    }
    

    注意:对于 IE 将遵循类似的过程,但我没有在此处包含它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      相关资源
      最近更新 更多