jQuery: сохраняйте адаптивный размер div для контейнера изображений перед исчезновением

У меня есть немного jQuery, который выбирает случайное изображение из папки и затемняет его внутри div при каждой загрузке страницы. Проблема в том, что div меню чуть ниже изображения прыгает в пустое пространство изображения до того, как изображение исчезнет.

Каков наилучший способ сохранить высоту div изображения до того, как изображение исчезнет? CSS для «заполнения» div до того, как изображение исчезнет? Или загрузить пустой .jpg до того, как случайное изображение исчезнет? (Все случайные изображения имеют одинаковый размер: 1000 пикселей в ширину и 250 пикселей в высоту).

Мне нужно сохранить отзывчивость дизайна, поэтому, возможно, лучшим решением будет предварительно загрузить пустой jpg, а затем добавить случайное изображение.

Я не включил массивы изображений и заголовков для простоты, но эта функция выводит изображение с классом .randomheader:

jQuery:

    <script>
    $(document).ready(function(){
     $('.randomheader').randomImage();
    });
    </script>

<script>
(function($){

    $.randomImage = {
        defaults: {

            path: '/fullpathhere/headerimages/',

            myImages: ['image1.jpg' , 'image2.jpg' , 'image3.jpg'],

            myCaptions: ['Caption 1' , 'Caption 2' , 'Caption 3']    
        }           
    }

    $.fn.extend({
        randomImage:function(config) {
            var config = $.extend({}, $.randomImage.defaults, config); 

            return this.each(function() {
                var imageNames = config.myImages;
                var imageCaptions = config.myCaptions;
                var imageNamesSize = imageNames.length;
                var randomNumber = Math.floor(Math.random()*imageNamesSize);
                var displayImage = imageNames[randomNumber];
                var displayCaption = imageCaptions[randomNumber];
                var fullPath = config.path + displayImage;

                // Load the random image
                $(this).attr( { src: fullPath, alt: displayImage }).fadeIn('slow');

                // Load the caption
                $('#caption').html(displayCaption).fadeIn('slow');
            });
        }
    }); 
    </script>

HTML:

    <header id="masthead" class="site-header" role="banner">

    <!-- random image loads in the div below -->
    <img src="" class="randomheader" width="1000" height="250" alt="header image">
    <div id="caption"></div>

   <!-- The nav div below jumps up into the div above -->
   <nav id="site-navigation" class="main-navigation" role="navigation">
       // nav here
   </nav>

CSS:

.randomheader {
    margin-top: 24px;
    margin-top: 1.714285714rem;
}

img.randomheader {
    max-width: 100%;
    height: auto; 
    display: none;
}

person markratledge    schedule 10.04.2013    source источник
comment
Поместите контейнер вокруг изображения с фиксированной высотой. Когда изображение исчезает, изменение его высоты не вызовет проблем с потоком. Фиксированные размеры контейнера должны предотвращать проблемы с потоком.   -  person Lowkase    schedule 10.04.2013
comment
Спасибо, но это нарушает отзывчивость дизайна.   -  person markratledge    schedule 10.04.2013
comment
Что тут отзывчивого? Приведенный выше тег изображения имеет размеры, указанные в неявных единицах пикселей (в HTML). Адаптивные элементы макета обычно указываются в % или em. Каким образом должно измениться изображение при изменении размера браузера?   -  person Matt Coughlin    schedule 15.04.2013
comment
Если проблема вызвана использованием display:none на изображении, как насчет того, чтобы начать изображение с непрозрачностью 0, а не display:none, а затем использовать fadeIn() или animate({opacity:1})?   -  person Matt Coughlin    schedule 15.04.2013
comment
Удалите display:none из img.randomheader в CSS и измените строку jQuery на $(this).attr( { src: fullPath, alt: displayImage }).hide().fadeIn('slow');. Это помогает?   -  person Dom    schedule 16.04.2013
comment
Всегда ли размер случайного изображения одинаков?   -  person PHearst    schedule 20.04.2013
comment
@dom: спасибо, но нет, это не помогает. Похоже, мне нужно предварительно загрузить пустое изображение 1000x250, а затем добавить случайное изображение; должен быть способ сделать это в функции jQuery.   -  person markratledge    schedule 21.04.2013


Ответы (3)


@ apaul34208 apaul34208 в значительной степени попал в самую точку ... Я создал для вас пример, основанный на том же принципе, чтобы вы могли увидеть, как он работает.

HTML:

<header id="masthead" class="site-header" role="banner">
  <div class="randomheader">
    <div class="image"><img src="" /></div>
    <span class="caption"></span>
  </div>

  <nav id="site-navigation" class="main-navigation" role="navigation">
    nav here
  </nav>
</header>

CSS:

.randomheader .image {
  position: relative;
  height: 0;

  /* 
  This percentage needs to be calculated
  using the aspect ratio of your image.
  Type your image width and height in this tool
  to get the aspect ration of your image:
  http://andrew.hedges.name/experiments/aspect_ratio/

  In this example the Google logo was 55:19 and 
  to get the percentage you divide 19 by 55 = 0.3454
  */
  padding-bottom: 34.54%;
}

.randomheader img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%; 
}

.randomheader .caption {
  display: block;
  min-height: 1em;
}

.randomheader img,
.randomheader .caption {
  opacity: 0;
}

jQuery:

(function($) {

  $.fn.extend({

    randomImage: function(config) {
      var defaults = {},
          config = $.extend({}, defaults, config); 

      return this.each(function() {
        var randNum = Math.floor(Math.random()*config.myImages.length),
            image = config.myImages[randNum],
            caption = config.myCaptions[randNum],
            path = config.path + image,
            $container = $(this),
            $image = $container.find('img'),
            $caption = $container.find('.caption');

        // preload image before adding 
        // to DOM and fading it in
        $image.attr({
          src: path,
          alt: image
        }).load(function() {
          $caption.html(caption);
          $image.add($caption).animate({ opacity: 1 }, 'slow');
        });
      });
    }

  });

}(jQuery));

// on DOM ready, 
// start 'er up
jQuery(function($) {
  $('.randomheader').randomImage({
    myImages: ['logo4w.png'],
    myCaptions: ['Google logo'],
    path: 'https://www.google.co.uk/images/srpr/'
  });
});

Демонстрация JSFiddle

person jjenzz    schedule 15.04.2013
comment
Спасибо за работу, но по какой-то причине это все еще ломает мой адаптивный дизайн. Есть ли способ предварительно загрузить пустое изображение размером 1000x250 пикселей в функцию jquery, а затем исчезнуть в случайном изображении? Некрасиво, да, но это один из способов сохранить отзывчивый дизайн. – - person markratledge; 21.04.2013
comment
Разве высота .randomheader img не должна быть «авто»? А @songdogtech зачем предварительно загружать пустое изображение через jquery? Разве вы не можете просто включить его в свой html как style=opacity: 0 и просто заменить изображение, а затем добавить его с анимацией? - person hexalys; 22.04.2013
comment
@songdogtech - Если вы собираетесь использовать пустое изображение, то вышеперечисленное не обязательно, и я бы создал ваше изображение настолько маленьким, насколько это возможно, сохраняя при этом соотношение сторон изображений, которые вы будете загружать (чтобы помочь с представление). Итак, если ваше изображение 958 на 718 пикселей, это соотношение сторон 4: 3, поэтому ваше пустое изображение может быть 4 на 3 пикселя. Затем вы просто устанавливаете его ширину на 100% и высоту на авто в CSS. Надеюсь это поможет. - person jjenzz; 29.04.2013
comment
@Bry - высота не должна быть автоматической. Высота элемента определяется нижним отступом, поэтому его необходимо установить равным 0. - person jjenzz; 29.04.2013
comment
@ Дженна Смит, ты прав, это сработало отлично. Спасибо! Извините за задержку с ответом. - person markratledge; 01.12.2013

Созданный мною jsfiddle показывает, как это можно сделать. Стиль display:none, который вы применяете к изображению, фактически удаляет элемент из DOM, а не просто скрывает его. Таким образом, полоса nav подскакивает вверх, потому что на самом деле там «ничего» нет до вызова fadeIn.

Вы все еще можете скрыть изображение, но вам нужно будет либо заменить его пустым элементом той же высоты, либо поместить его в контейнер, как в jsfiddle.

person DF_    schedule 10.04.2013
comment
Спасибо, это работает, но нарушает отзывчивость дизайна. Мне нужна высота: авто в контейнере, чтобы контейнер реагировал при изменении размера окна браузера. Или мне нужно заменить пустой jpg размером 250pxx1000px. - person markratledge; 10.04.2013
comment
Не могли бы вы дать более подробную информацию о том, что именно отвечает? Изображение меняет размер или что-то в этом роде? Я не понимаю, что ты пытаешься сделать. - person DF_; 15.04.2013
comment
Да, изображение меняет размер в зависимости от размера браузера при использовании max-width: 100%; высота: авто; Итак, я думаю, что пустой.jpg 1000x250, предварительно загруженный до того, как случайное изображение исчезнет, ​​сохранит высоту и ширину div, и он не рухнет до того, как случайное изображение исчезнет. Я не знаю, может ли отзывчивость быть эмулируется в jsfiddle, но это нарушает отзывчивость моего живого сайта. - person markratledge; 15.04.2013
comment
Я добавил некоторые детали в вопрос. - person markratledge; 15.04.2013
comment
Минимальная высота: 250 пикселей убивает отзывчивость; это удерживает div на высоте 250 пикселей, даже когда ширина изображения уменьшается, и это оставляет пространство под контейнером изображения. - person markratledge; 21.04.2013

У меня была аналогичная проблема с моим контентом, прыгающим вниз при загрузке моего слайд-шоу.

Вот что я нашел: jsFiddle

HTML

<div id="Container">
<div id="box"></div>
<div id="element"> <!-- add content here --> </div>
</div>

css

#Container {
display: inline-block;
position: relative;
width: 100%;
}

#box {
padding-top: 25%;
/* adjust % for height */
}

#element {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background:red; /* added for visibility */
}

Это делает большой жидкий держатель места. Просто поиграйте с процентами, чтобы получить желаемый размер.

Я впервые увидел этот метод где-то на SO, но думаю, что это была адаптация этого- http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio

person apaul    schedule 15.04.2013
comment
Спасибо за работу, но по какой-то причине это все еще ломает мой адаптивный дизайн. Есть ли способ предварительно загрузить пустое изображение размером 1000x250 пикселей в функцию jquery, а затем исчезнуть в случайном изображении? Некрасиво, да, но это один из способов сохранить отзывчивый дизайн. - person markratledge; 21.04.2013
comment
@songdogtech Можете ли вы дать ссылку на пример? Не уверен, как это нарушает адаптивный дизайн. - person apaul; 21.04.2013