使用jQuery UI“大小”效果时防止重排

时间:2009-11-04 04:09:30

标签: jquery jquery-ui css avatar

我有一个像这样的图像列表:

<ul class='blah'>
  <li><img src='...' /></li>
  <li><img src='...' /></li>
  <li><img src='...' /></li>
  <li><img src='...' /></li>
</ul>

我将它设计为显示为没有项目符号的水平列表。有点像你在GitHub上看到的关注者(见http://github.com/chrislloyd)。当用户将鼠标悬停在它上面时,我正在使用jQuery和jQuery UI来使这些图像更大。这是我到目前为止的代码:

$(".blah img").hover(
  function() {
    $(this).effect("size",
      { to: { width: 64, height: 64 },
        origin: ['top','center'], scale: 'content' });
  },
  function() {
    $(this).effect("size",
      { to: { width: 32, height: 32 }, scale: 'content' });
  });

这在动画制作时效果很好,但是一旦图像达到最大尺寸,其他图像就会重新流动(移开)。任何想法如何做到这一点,而不回复任何东西?

我在图像和容器(<ul>)上尝试了'position:absolute;','position:relative'等变体,但它并没有什么区别。

6 个答案:

答案 0 :(得分:3)

您可以尝试以下方式:

var pos = $(this).position();
$(this).css({ position: "absolute",
              top: pos.top, left: pos.left, zindex:10 }); 

这将使图像不会推动其他图像,但它有一个相反的问题,即“吮吸”其他图像,因为它被放置在一边。


使用jQuery可以很好地example here来实现类似的效果。

此示例使用列表项来排序保留图像的空间。我们将列表项向左浮动,并通过将它们定位为“相对”并为它们提供明确的大小来将它们分开。然后图像在列表项中定位为“绝对”。现在,当我们使用jQuery重新调整图像大小时,其他图像不会重新流动,因为列表项充当占位符。

该示例还使用animate而不是effect.size来获得更清晰的效果。

希望这会有所帮助。祝你好运。

答案 1 :(得分:2)

这是我的尝试。我将列表项设置为相对于保持绝对定位的图像。这似乎与您指定的一样有效。唯一的问题是,当你快速滑过所有这些时,它们都会生成动画。我会假设你想在那里添加一些内容,以便一次只调整一个。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title></title>
    <style type="text/css">
        li { position:relative; height:40px; width:40px; float:left; list-style:none; }
        li img { position:absolute; top:0; left:0; height:32px; width:32px; border:1px solid #666; background:#eee; }
    </style>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            $(".blah img").hover(
              function() {
                $(this).css("z-index", "2");
                $(this).animate({
                  "height": "65px", "width": "65px", "top": "-16px", "left":"-16px"
                }, "slow");
              },
              function() {
                 var that = this;
                $(this).animate({
                  "height": "32px", "width": "32px", "top": "0", "left":"0"
                }, "slow", "swing", function() { $(that).css("z-index", "1"); });

              });
        });
    </script>
</head>

<body>
    <ul class='blah'>
      <li><img src='http://www.gravatar.com/avatar/116ed602629e00b79eae9af774398bb0?s=24&d=http%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-24.png' /></li>
      <li><img src='http://www.gravatar.com/avatar/116ed602629e00b79eae9af774398bb0?s=24&d=http%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-24.png' /></li>
      <li><img src='http://www.gravatar.com/avatar/116ed602629e00b79eae9af774398bb0?s=24&d=http%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-24.png' /></li>
      <li><img src='http://www.gravatar.com/avatar/116ed602629e00b79eae9af774398bb0?s=24&d=http%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-24.png' /></li>
    </ul>

</body>
</html>

答案 2 :(得分:1)

如果你使用jquery中的'animate'函数而不是“effect”,它的效果很好(它不会重排)。我在Firefox 3,Chrome和IE 8中尝试了以下代码,并且在所有情况下都没有回流。这是功能:

    $(".blah img").hover(
      function() {
        $(this).animate( {'width': 64, 'height': 64 });
      },
      function() {
        $(this).animate( {'width': 32, 'height': 32 });
      });

这是我用来测试功能的完整页面:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    <script src="../jquery.js" type="text/javascript"></script>
    <script type="text/javascript" >
            $(document).ready( function() {
            $(".blah img").hover(
              function() {
                $(this).animate( {'width': 64, 'height': 64 });
              },
              function() {
                $(this).animate( {'width': 32, 'height': 32 });
              });
            });
    </script>
    <style type="text/css" rel="stylesheet">
      ul li { 
        float: right;
        list-style: none;
      }
    </style>
    </head>
    <body>
    <ul class='blah'>
      <li><img src='../i32.jpg' /></li>
      <li><img src='../i32.jpg' /></li>
      <li><img src='../i32.jpg' /></li>
      <li><img src='../i32.jpg' /></li>
    </ul>
    </body>
    </html>

答案 3 :(得分:1)

简单的答案通常是找到一个已经完成你想要的现有jQuery插件。那里有很多,即使一个不完美,你也可以适应或学习它以获得理想的结果。

为了自己动手,我建议使用两个图像副本:一个与列表内联,另一个在顶部放大。这样,列表的布局根本不依赖于缩放图像

未经测试的代码,只是想:

//  on page load, process selected images
$(function () {
  $('img.hoverme').each(function () {
    var img = $(this);
    var alt = $("<img src='" + img.attr('src') + "'/>");
    img.after(alt);
    alt.hide();

    img.hover(function () {
      var position = img.position();
      alt.css({ 
        position: "absolute",
        top: position.top,
        left: position.left,
        width: 32,
        height: 32
      }).animate({
        top: position.top - 16,
        left: postion.left - 16,
        width: 64,
        height: 64
      });
    }, function () { });

    alt.hover(function () { }, function () {
      var position = img.position();
      alt.animate({
        top: position.top,
        left: position.left,
        width: 32,
        height: 32
      }, function () {
        alt.hide();
      });  // alt.animate
    });  //  alt.hover

  });  //  each
});  // $(

当鼠标移过较小的图像时,会在其上方创建较大的图像,并立即展开。当鼠标离开较大的图像时,它会收缩然后消失。

答案 4 :(得分:1)

您需要一个执行以下操作的功能:

  1. 用户将鼠标悬停在图片上
  2. 函数调用CLONE($(this).clone()...)图像并绝对位于与基本图像完全相同的位置,但顶层有一层(稍后在DOM中的某处将克隆元素渲染)
  3. 在克隆的图片上制作动画
  4. 在悬停时,反转动画,然后完全删除克隆的元素。 (卸下摆臂())
  5. 非常简单。其他元素将保持不变,不会移动。

答案 5 :(得分:0)

通过将原点设置为左上角而不是顶部中心,我得到了稍好的结果。

但是否则它大致相同。以下是其他人可以使用的内容:

<html><head><title>HELL NO WE WON'T REFLOW</title>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'></script>
<script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js'></script>
<script>
jQuery(function($) {
  $('.blah img').each(function(){
    var p = $(this).position();
    $(this).css({top:p.top,left:p.left});
  });
  $('.blah img').each(function(){
    //$(this).css({position:'absolute'});
  });
  $(".blah img").hover(
  function() {
    $(this).effect("size",
      { to: { width: 375, height: 91 },
        origin: ['top','left'], scale: 'content' });
  },
  function() {
    $(this).effect("size",
      { to: { width: 250, height: 61 }, scale: 'content' });
  });
});
</script>
</head>
<body>
<ul class="blah">
<li><img src='http://sstatic.net/so/img/logo.png'/></li>
<li><img src='http://sstatic.net/so/img/logo.png'/></li>
<li><img src='http://sstatic.net/so/img/logo.png'/></li>
<li><img src='http://sstatic.net/so/img/logo.png'/></li>
</ul>
</body>
</html>