JavaScript transition with the display property?

前端 未结 3 1190
粉色の甜心
粉色の甜心 2021-01-28 01:54

Can I make a certain element fade in when I hover over another one, and make it fade out when my mouse isn\'t on the element anymore?

I tried adding a transition

相关标签:
3条回答
  • 2021-01-28 02:35

    Here is a mostly css answer: http://jsfiddle.net/Z7GuR/4/

    Instead of using display since that has only two modes (in this case: none and block) you should use opacity. That will give you a smooth transition.

    Css:

    #menu {
        background-color: rgb(0,100,0);
        width: 200px;
        height: 100px;
        margin-left: 50px;
        // Notice
        opacity: 0;
        transition: opacity 1s;
        -webkit-transition: opacity 1s;
        -moz-transition: opacity 1s;
        -o-transition: opacity 1s;
    }
    

    Javascript:

    function showMenu() {
        document.getElementById("menu").style.opacity = 1;
    }
    
    function hideMenu() {
        document.getElementById("menu").style.opacity = 0;
        // If you want, you can bind an "end" event to css transition and
        // set "display" to none when that happens
    }
    

    As some have pointed out, the element will still take up space even after its opacity is set to 0. To prevent this, you can set display to none after the animation has ended, as I said in the example (sorry if this wasn't clear). This is much better than changing the margin, which is a "hacky" solution.

    Edit: Okay, the display: none, works, but for some reason, with display: block, the animation is choppy when you fade back in, if it's completely faded out previously (in chrome, at least). So, instead of display: none, I used a combination of position: absolute, and visibility: hidden, to hide the element:

    http://jsfiddle.net/Z7GuR/4/

    var menu = document.getElementById("menu"), button = document.getElementById("button");
    
    function showMenu() {
        menu.style.opacity = 1;
        // Reset visibility and position
        menu.style.visibility = "visible";
        menu.style.position = "static";
        menu.removeEventListener("transitionend", setDisplayNone, false);
    }
    
    function hideMenu() {
        menu.style.opacity = 0;
        // I prefer using transitionend to setTimeout
        // transitionend is more extendable, and it makes more sense to me
        menu.addEventListener("transitionend", setDisplayNone, false);
    }
    
    function setDisplayNone() {
        menu.style.visibility = "hidden";
        menu.style.position = "absolute";
    }
    
    button.addEventListener("mouseover", showMenu);
    button.addEventListener("mouseout", hideMenu);
    

    The only major difference between my answer and the accepted answer is that the text will always be visible (the fading element won't cover it).

    0 讨论(0)
  • 2021-01-28 02:48

    At first, I thought about soktinpk's solution. Opacity can be animated with css so it's the best bet.

    However, it takes up the space even when it is not shown. To prevent that, you could make it position:absolute. But even then, elements behind it will not be clickable.

    Here is a more robust solution with a combination of @soktinpk's ideas

    To prevent that, hide it with display:none when it is not visible.

    Edit

    Actually, visibility:hidden seems to work better when fading back in.

    HTML

    <div id="button" onmouseover="showMenu()" onmouseout="hideMenu()">
        <!-- placing it inside will allow it to be positioned as wanted -->
        <div id="menu"></div>
    </div>
    

    CSS

    #button {
        background-color: rgb(0,0,100);
        width: 100px;
        height: 50px;
        margin-top: 50px;
        margin-left: 50px;
        position:relative; // All absolutely positioned elements inside are relative to this element
    }
    
    #menu {
        background-color: rgb(0,100,0);
        width: 200px;
        height: 100px;
        opacity:0;
        visibility:hidden;
        transition: opacity 1s;
        -webkit-transition: opacity 1s;
        -moz-transition: opacity 1s;
        -o-transition: opacity 1s;
        position:absolute; // So that it displays at the right position
        top:100%;
        left:0;
    }
    

    JS

    var time_out;
    var menu = document.getElementById("menu");
    
    function showMenu() {
        clearTimeout(time_out);
        menu.style.visibility = "visible";
        menu.style.opacity = 1;
    }
    
    function hideMenu() {
        clearTimeout(time_out);
        menu.style.opacity = 0;
        // This will hide it when the animation is over
        time_out = setTimeout(function(){menu.style.visibility = "hidden";},1000);
    }
    

    JS Fiddle Demo

    0 讨论(0)
  • 2021-01-28 02:49

    Here's a pure css solution for your specific html:

    fiddle

    html

    <div id="button" onmouseover="showMenu()" onmouseout="hideMenu()"></div>
    <div id="menu"></div>
    

    for the css I used opacity instead of display and added the following:

    css

    #button:hover ~ #menu,
    #menu:hover {
        opacity:1;
        height:100px;
    }
    
    0 讨论(0)
提交回复
热议问题