Предотвращение перепрошивки при использовании эффекта “размера” пользовательского интерфейса jQuery

StackOverflow https://stackoverflow.com/questions/1671633

  •  13-09-2019
  •  | 
  •  

Вопрос

У меня есть список таких изображений, как это:

<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' });
  });

Это хорошо работает во время анимации, но как только изображение достигает своего максимального размера, другие изображения перерисовываются (сдвигаются в сторону).Есть идеи, как это сделать, ничего не переплавляя?

Я пробовал вариации "положения:абсолютное;', 'положение:родственник" и т.д.на изображениях и контейнере (the <ul>) но на самом деле это не имело никакого значения.

Это было полезно?

Решение

Вы могли бы попробовать что-то вроде:

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

Это не позволит изображению оттеснить другие, но у него есть своего рода противоположная проблема "всасывания" других, поскольку оно расположено в стороне.


Есть довольно хороший пример здесь об использовании jQuery для достижения аналогичного эффекта.

В этом примере элементы списка используются для того, чтобы как бы зарезервировать место для изображений.Мы перемещаем элементы списка влево и распределяем их по пространству, располагая их "относительно" и присваивая им явный размер.Затем изображения позиционируются как "абсолютные" внутри элемента списка.Теперь, когда мы используем jQuery для изменения размера наших изображений, другие изображения не перемещаются повторно, поскольку элемент списка действует как заполнитель.

В примере также используется animate, а не effect.size для немного более чистого эффекта.

Надеюсь, это поможет.Удачи.

Другие советы

Вот моя попытка.Я установил расположение элементов списка относительно друг друга, чтобы удерживать абсолютно позиционированные изображения.Кажется, это работает так, как вы указали.Единственная проблема заключается в том, что когда вы быстро просматриваете их все, все они оживают.Я бы предположил, что вы хотели бы добавить туда что-то, чтобы сделать так, чтобы одновременно изменялся только один размер.

<!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>

Если вы используете функцию 'animate' из jquery вместо "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>

Простой ответ обычно заключается в том, чтобы найти существующий плагин 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
});  // $(

Когда мышь наводится на изображение меньшего размера, создается изображение большего размера при наведении на него курсора и сразу же расширяется на месте.Когда мышь покидает увеличенное изображение, оно уменьшается, а затем исчезает.

Вам нужна функция, которая выполняет следующее:

  1. Пользователь наводит курсор мыши на изображение
  2. Функция вызывает CLONE ($(this).clone()...) изображение и абсолютно позиционирует его в том же месте, что и базовое изображение, но на один слой сверху (визуализирует клонированный элемент где-нибудь позже в DOM)
  3. Сделайте свою анимацию на клонированном изображении
  4. При выключенном наведении мыши измените анимацию в обратном направлении, затем полностью удалите клонированный элемент.(.удалить())

Довольно просто.Остальные элементы останутся нетронутыми и не будут двигаться.

Я получил немного лучший результат, установив начало координат в верхнем левом углу вместо верхнего центрального.

Но в остальном это примерно то же самое.Вот кое-что, над чем другим стоит поработать:

<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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top