【问题标题】:Problems with jQuery animate and z-index/Relative PositioningjQuery 动画和 z-index/相对定位的问题
【发布时间】:2014-03-14 23:52:09
【问题描述】:

我正在尝试使用 position: relative 让一个 div 包含鼠标悬停时的其他 div。不幸的是,它只适用于最后一个 div。如果您将鼠标悬停在其他 div 上,它们只会覆盖在它们之前声明的 div。

代码在这里:http://jsfiddle.net/YuKaR/3/

绝对定位可以正常工作,但不幸的是我不能为这个特定的应用程序使用绝对定位。

有人知道我做错了什么吗?感谢您的宝贵时间。

【问题讨论】:

  • 我强烈建议您在小提琴上使用样式表。内联阅读几乎是不可能的。
  • 抱歉,不知道我是怎么错过的。谢谢。

标签: jquery jquery-animate z-index css-position


【解决方案1】:

相对定位的问题在于位置是相对于它们的正常位置的,这意味着如果你在中间调整一个元素的大小,浏览器将移动并重新排列它之后的所有内容。

需要进行一些更改才能使其正常工作。如果要使用相对定位,则必须将调整大小的 div 包装在固定大小的容器中,这样在调整大小时不会破坏元素流。你的 div 有 150px 的宽度和高度,固定大小的容器必须足够大来容纳它,假设默认的盒子模型是 150px + 10px*2 padding + 1px*2border = 172px。由于元素流由容器控制,因此我将边距移动到 css 中的容器。

通过将它们包装在一个额外的固定大小的 div 中,元素流将永远不会改变,您调整大小的 div 只会流过容器的边缘,与其他容器重叠(溢出:可见)。

我还更改了您的 z-index 逻辑,因为您现在需要为容器设置 z-index(这将适用于所有子元素)。默认情况下,所有内容的 z-index 为 2。当 div 被调整回其原始状态时,我在动画结束后使用 .animate() 上的回调函数将其容器的 z-index 设置回 2。调整大小开始时,所有容器都重置为 z-index 2,以防仍有一个动画恢复到其原始状态,当前调整大小的 div 的容器设置为 z-index 3 以使其显示在所有其他容器之上。

http://jsfiddle.net/x34d3/

HTML 标记:

 <div id="main" style="position:relative;z-index:1;">

     <div class="container"><div id="lefttop" class="resizer">left top</div></div>
     <div class="container"><div id="righttop" class="resizer">right top</div></div>
     <p style="clear:both;"></p>
     <div class="container"><div id="leftbottom" class="resizer">left bottom</div></div>
     <div class="container"><div id="rightbottom" class="resizer">right bottom</div></div>

 </div>

CSS:

.resizer { position:relative; border: 1px solid #000000; padding:10px; margin:0px; width:150px; height:150px; }

.container { position:relative; padding:0px; margin:8px; float:left; z-index: 2; width:172px; height:172px; }

javascript:

$(function(){
     $(".resizer").mouseover(function() {
         $(".container").css('z-index' , '2');
         $(this).parent().css('z-index' , '3');
         if(this.id == "lefttop"){
             aoptions = {width: "340px", height: "340px", backgroundColor: "#CCCCCC", left: '0', top: '0'}
         }else if(this.id == "righttop"){
             aoptions = {width: "340px", height: "340px", backgroundColor: "#CCCCCC", left: '-=190', top: '0'}
         }else if(this.id == "leftbottom"){
             aoptions = {width: "340px", height: "340px", backgroundColor: "#CCCCCC", left: '0', top: '-=190'}
         }else if(this.id == "rightbottom"){
             aoptions = {width: "340px", height: "340px", backgroundColor: "#CCCCCC", left: '-=190', top: '-=190'}
         }
         $(this).css('z-index' , '99').animate(aoptions, 800);
     }).mouseout(function(){
         if(this.id == "lefttop"){
             aoptions = {width: "150px",    height: "150px", backgroundColor: "#FFFFFF", left: '0', top: '0'}
         }else if(this.id == "righttop"){
             aoptions = {width: "150px",    height: "150px", backgroundColor: "#FFFFFF", left: '+=190'}
         }else if(this.id == "leftbottom"){
             aoptions = {width: "150px",    height: "150px", backgroundColor: "#FFFFFF", left: '0', top: '+=190'}
         }else if(this.id == "rightbottom"){
             aoptions = {width: "150px",    height: "150px", backgroundColor: "#FFFFFF", left: '+=190', top: '+=190'}
         }
         $(this).animate(aoptions, 800, function(){
             $(this).parent().css('z-index' , '2');
         });
     });
 });

【讨论】:

  • 看起来很像我最先发布的解决方案,只是没有那么好=D
  • @DarthJDG - 我的强迫症不会让我忽略可以优化代码或使其看起来更有条理的地方。这就是我偏离的原因。
  • @DarthJDG - 我想说清楚,我并不想变得粗鲁。再读一遍,好像是这样的。我的意思是在格式/组织方面很好,我知道你只是让原件工作并保持一切不变。没有难过的感觉!
  • @Scott:不用担心,我没有看错,我的帖子中也有一些双关语。以任何方式冒犯我都需要更多。 :) 当你弹出你的帖子时,我只是在输入我的帖子的结尾,我只是输入了太多没有发布它。您的解决方案看起来和工作得更好。
【解决方案2】:

花了我一段时间,但我终于弄明白了。看看这个working jsFiddle demo

HTML:

 <div id="main">

     <div class="overlay"><div id="lefttop">left top</div></div>
     <div class="overlay"><div id="righttop">right top</div></div>
     <p></p>
     <div class="overlay"><div id="leftbottom">left bottom</div></div>
     <div class="overlay"><div id="rightbottom">right bottom</div></div>

 </div>

CSS:

* {

    margin: 0px;
    padding: 0px;
    border: none;
    z-index: -1;
}

p { clear: both; }

#main {

    float: left;
    margin: 50px;
    background: black;

}

#main div {

    position: relative;
    float: left;

    height: 150px;
    width: 150px;

}

.overlay {

    height: 0;
    overflow: visible;
    position: relative;
    z-index: 99;

}

#lefttop { background: yellow; }
#righttop { background: green; }
#leftbottom { background: red; }
#rightbottom { background: blue; }

jQuery:

var $divs = $("div", ".overlay"),
    optionsOver = {

         width: "300px",
         height: "300px"

    },
    optionsOut = {

         width: "150px",
         height: "150px"

    };

$divs.hover(function() {

    $divs
        .stop(true,true)
        .parent()
        .css({"z-index" : "1"});

    if (this.id == "lefttop") {

        optionsOver.left = "0px";
        optionsOver.top = "0px";

    } else if (this.id == "righttop") {

        optionsOver.left = "-=150px";
        optionsOver.top = "0px";

    } else if (this.id == "leftbottom") {

        optionsOver.left = "0px";
        optionsOver.top= "-=150px";

    } else if (this.id == "rightbottom") {

        optionsOver.left = "-=150px";
        optionsOver.top= "-=150px";

    }

    var $this = $(this);
    $this.stop(true,true);
    $this.parent().css({"z-index" : "99"});
    $this.animate(optionsOver, 400);

 }, function() {

    if (this.id == "lefttop") {

        optionsOut.left = "0px";
        optionsOut.top = "0px";

    } else if (this.id == "righttop") {

        optionsOut.left = "+=150px";
        optionsOut.top = "0px";

    } else if (this.id == "leftbottom") {

        optionsOut.left = "0px";
        optionsOut.top= "+=150px";

    } else if (this.id == "rightbottom") {

        optionsOut.left= "+=150px";
        optionsOut.top = "+=150px";

    }

    $(this)
        .stop(true,true)
        .animate(optionsOut, 400, function() {
            $divs.parent().css({"z-index" : "1"});
        });

 });

【讨论】:

  • 主要技巧是将每个 div 包装在另一个具有 .overlay 类的 div 中。该类设置为height: 0overflow: visible。然后,当鼠标悬停在 div 上时,我们将所有 .overlay div 设置为 z-index: 1,同时将鼠标悬停的 .overlay div 设置为 z-index: 99.overlay css 和鼠标悬停动作的组合告诉浏览器不要推动其他 HTML 元素。
  • 我还将对象文字向上移动,这样我们就不必重新键入一堆相同的属性,以及添加.stop(true,true) 以消除动画排队。
  • 太好了,谢谢!我会立即采用这些优化。
  • 别忘了,对所有对你有帮助的答案都点赞 (+1) 总是很好的 =D
  • 它说我没有足够高的声誉,但我会尽快。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 2015-10-31
  • 2014-11-23
  • 1970-01-01
相关资源
最近更新 更多