我正在开发一个基于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规则中。
在第二张图像中,不删除上一个悬停类,而不删除悬停类。我想要悬停转换必须删除。在添加新规则以防止重复类之前,应该防止在悬停元素时进行多个转换。
谢谢。
答案 0 :(得分:0)
我今天找到了答案。我将解释它,以便将来可以帮助其他人理解问题和解决方案。
通过我的问题,你可以理解这个问题。问题出在这个函数上只有
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时会发生以下事情:
为了更好地理解它,我会给你一个例子:
假设我在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会遵循类似的程序,但我没有在此处包含它。