如何防止div:通过javascript div样式属性更改禁用悬停转换

时间:2015-06-11 19:04:53

标签: javascript html css css-transitions

这是我尝试调试的jsfiddle:

http://jsfiddle.net/Neoheurist/x57fkzng/

HTML

<div id="birthday">Surprise Party</div>
<p></p>
<button onclick="blue()">Blue</button>
<button onclick="red()">Red</button>

<script>
function blue()
{
    element=document.getElementById("birthday");

    element.innerHTML="Happy";

    element.style.background="blue";
    element.style.width="150px";
    element.style.opacity="1.0";
    element.style.transition="width 2s,background 15s,opacity 2s";
}

function red()
{
    element=document.getElementById("birthday");

    element.innerHTML="Birthday";

    element.style.background="red";
    element.style.width="300px";
    element.style.opacity="0.0";
    element.style.transition="width 2s,background 4s,opacity 6s";
}
</script>

CSS

div
{
    width:100px;
    height:50px;
    background:blue;
    transition:width 2s,opacity 2s,background 15s;
}

div:hover
{
    width:200px;
    background:green;
    opacity:0.25;
    transition-timing-function:linear;
    transition:width 2s,background 4s,opacity 6s;
}

问题:

为什么单击按钮会禁用div:hover?

如何防止这种情况发生?

3 个答案:

答案 0 :(得分:3)

这是因为HTML样式属性会覆盖css文件中的元素选择器。直接在HTML样式属性中设置的任何属性将自动用于任何css选择器声明中的任何属性集。

样式属性比标签选择器更具体(这就是为什么不推荐它们实际使用的原因)。

根据webkit中的检查员,这还包括:悬停状态,因此任何内联样式都将阻止悬停状态的工作。

可以使用重要的,诱人的,但那是不是一个好主意,因为它会带来你当前的特殊问题并放大它甚至更进一步,导致specificity nightmare。覆盖!important的唯一方法是使用更多!important,在文档的下方,或使用更具体的选择器(如ID)或更长的选择器链和!important等等,你可以看到这可能是多么可怕的维护。此外,任何直接为HTML添加样式的js都不起作用。

最佳解决方案是使用 javascript添加和删除css类以触发更改。这将解决您的问题,因为您的所有课程都具有可管理的特异性。

#birthday.blue {
    background: blue;
    width: 150px;
    opacity: 1.0;
    transition: width 2s,background 15s,opacity 2s;
}

#birthday.red {    
    background: red;
    width: 300px;
    opacity: 0.0;
    transition: width 2s,background 4s,opacity 6s;
}

然后确保为所有组合定义了悬停状态,因此任何类都将:hover。内联样式无法实现这一点。

#birthday:hover,
#birthday.blue:hover,
#birthday.red:hover
{
    width: 200px;
    background: green;
    opacity: 0.2;
    transition-timing-function: linear;
    transition: width 2s,background 4s,opacity 6s;
}

我整理了一个jsfiddle that demos this。我已经使用了JQuery,为了快速获得一个演示,他们的addClass()方法很棒。努力使用纯粹的js,这是一个很好的习惯;这个问题将详细阐述如何add and remove classes in javascript

加; 作为额外奖励,您还可以在自己的样式文件中拥有所有风格,并在javascript中拥有所有功能,这样做会更好separation of concerns并使网站样式DRYer并且更容易在项目的其他地方重复使用(你没有样式卡住你不能轻易添加到其他地方的js,而是你复制,然后尝试在一个地方而不是另一个地方改变...我们都做,或我们的同事做!)。

[看到我提出了特殊性问题,你可能也有兴趣知道ID也是pretty bad for that and unnecessary in style files]

答案 1 :(得分:2)

你可以制作div:hover属性all!important如下:

NSMenuItem

但是我听说你想要避免!如果可能的话,这很重要,但这可以做你想要的......

答案 2 :(得分:0)

您也可以使用

document.addEventListener('DOMContentLoaded', function () {
    var storedStyles;
    var elem = document.getElementById("birthday");
    elem.addEventListener('mouseenter', function () {
        if (elem.hasAttribute('style')) {
            storedStyles = elem.attributes.style.value;
            elem.removeAttribute('style');
        }
    });

    elem.addEventListener('mouseleave', function () {
        if (storedStyles) {
            elem.setAttribute('style', storedStyles);
        } else {
            storedStyles = null;
        }
    });
 });

并清除鼠标上的所有样式进入恢复悬停样式优先级并在鼠标离开时设置内联样式