VovkDesign

Блог Александры и Владимира Вовк

RSS лента
wp-puzzle

Как зафиксировать блок в боковой колонке с помощью JavaScript

Часто появляется необходимость зафиксировать определенный блок на сайте так, чтобы он был виден даже при прокрутке страницы. Это может быть любая навигация и меню, корзина в интернет-магазине, кнопки наверх или оформить заказ, рубрикатор и даже… реклама. При правильном подходе фиксированный блок поможет увеличить показатели сайта — юзабилити, глубину просмотра, конверсию, рекламный доход — все зависит от целей. В одной из статей Владимир Вовк поделился реальными цифрами из практики, когда зафиксированный рекламный блок в боковой колонке увеличил доход с контекстной рекламы в 4 раза. А я сегодня покажу как же с помощью небольшого скрипта на чистом JavaScript сделать такой блок у себя на сайте.

пример зафиксированного блока

Шаг 1. Код блока, который нужно зафиксировать

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

Код рекламы обычно вставляется в стандартный текстовый виджет (в консоли WordPress меню Внешний Вид → Виджеты). Находим свой виджет с рекламой (или добавляем новый, если нужно) и вокруг кода рекламы добавляем тег div вот так:

<div id="fixblock">
<!-- тут должен быть ваш код рекламы -->
</div>

А вот так это выглядит у меня с рекламный блоком AdSense:

рекламный блок в виджете

Чтобы дальше в скрипте идентифицировать блок, мы установили ему атрибут id со значением fixblock.

Будьте внимательны!
Значение атрибута id будет использоваться в скрипте. Если вы сменили значение на свое, исправьте его и в скрипте.

Шаг 2. Добавляем скрипт

Теперь нужно добавить код скрипта, который будет фиксировать блок на странице при прокрутке. Для этого копируем код ниже (помним про значение id) и добавляем его перед закрывающим тегом </body> в файл footer.php через меню Внешний вид → Редактировать. Функционал написан на чистом JavaScript, поэтому подключение фреймворка jQuery не требуется.

<script type="text/javascript">
function getTopOffset(e) { 
	var y = 0;
	do { y += e.offsetTop; } while (e = e.offsetParent);
	return y;
}
var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
if ( null != block ) {
	var topPos = getTopOffset( block );
	window.onscroll = function() {
		var newcss = (topPos < window.pageYOffset) ? 
			'top:20px; position: fixed;' : 'position:static;';
		block.setAttribute( 'style', newcss );
	}
}
</script>

Сохраняем и проверяем как все работает.

Тонкости

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

<script type="text/javascript">
jQuery(document).ready(function($) {

а последнюю на вот это:

});
</script>

На этом у меня все. Если возникнут вопросы — пишите в комментариях, вместе разберемся с любой проблемой. И не забывайте подписываться на обновления блога 🙂

 

Добавлено 04.11.2014:

В процессе обсуждения в комментариях, появился доработанный вариант скрипта. С ним зафиксированный блок будет пропадать в самом низу страницы, чтобы не перекрывать подвал. Высота блока и подвала вычисляются в скрипте. Если блок пропадает раньше или позже, чем нужно, то можно указать высоту подвала вручную.
Код работает и для сайтов с динамической загрузкой содержимого (например, комментарии вроде Disqus или Cackle).

Вариант с автоматическим определением вычислением высоты зафиксированного блока и подвала (замените id подвала на свой):

<script type="text/javascript">
function getTopOffset(e) { 
	var y = 0;
	do { y += e.offsetTop; } while (e = e.offsetParent);
	return y;
}
var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
if ( null != block ) {
	var topPos = getTopOffset( block );

	window.onscroll = function() {
		var scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),

		    // определяем высоту рекламного блока
		    blockHeight = block.offsetHeight,

		    // вычисляем высоту подвала, footer заменить на значение атрибута id подвала
		    footerHeight = document.getElementById('footer').offsetHeight, 	    

		    // считаем позицию, до которой блок будет зафиксирован 
		    stopPos = scrollHeight - blockHeight - footerHeight; 

		var newcss = (topPos < window.pageYOffset) ? 
			'top:20px; position: fixed;' : 'position:static;';

		if ( window.pageYOffset > stopPos ) 
			newcss = 'position:static;';

		block.setAttribute( 'style', newcss );
	}
}
</script>

Или с точно указанной высотой (подставьте свои значения в пикселах):

<script type="text/javascript">
function getTopOffset(e) { 
	var y = 0;
	do { y += e.offsetTop; } while (e = e.offsetParent);
	return y;
}
var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
if ( null != block ) {
	var topPos = getTopOffset( block );

	window.onscroll = function() {
		var scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),

		    // высота рекламного блока
		    blockHeight = 400, 

		    // высота подвала
		    footerHeight =  500, 

		    // считаем позицию, до которой блок будет зафиксирован 
		    stopPos = scrollHeight - blockHeight - footerHeight; 

		var newcss = (topPos < window.pageYOffset) ? 
			'top:20px; position: fixed;' : 'position:static;';

		if ( window.pageYOffset > stopPos ) 
			newcss = 'position:static;';

		block.setAttribute( 'style', newcss );
	}
}
</script>

 

Добавлено 04.01.2016:

Для тех, кто использует WordPress и не хочет возиться с установкой кода, теперь доступен наш плагин Fixed Widget. В опциях есть возможность тонкой настройки фиксации блока, его положения и анимации.

Комментарии всего: 203

  • Добрый день!
    Подскажите пожалуйста, как реализовать код в дочерней теме?

    • Добрый день, Михаил! В дочерней теме нужно добавить в файл function.php (если его нету, то создайте) фильтр для функции wp_footer().
      Вот этот код вставьте в function.php:

      function add_fixblock_script(){
          echo <<<EOT
      <script type='text/javascript'>
      function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
      }
      var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
      if ( null != block ) {
      	var topPos = getTopOffset( block );
      	window.onscroll = function() {
      		var newcss = (topPos < window.pageYOffset) ? 
      			'top:20px; position: fixed;' : 'position:static;';
      		block.setAttribute( 'style', newcss );
      	}
      }
      </script>
      EOT;
      }
      add_action( 'wp_footer', 'add_fixblock_script' );
  • Спасибо за информацию, попробую как-нибудь заморочиться =)

  • Добрый день!
    Столкнулся с ситуацией по пункту «Тонкости» и что-то у меня не получается.
    Блок на джейквери сверху ломает рекламный нижний блок и вообще корежет сайдбар весь.
    В чем может быть причина?
    Какая библиотека джейквери должны быть подключена?

    • Добрый день, Михаил! Не совсем поняла суть проблемы — вы используете одновременно два рекламных блока и оба хотите зафиксировать? Версия JQuery не играет никакой роли в любом случае.

  • вот что я прописал, согласно вашим инструкциям:

    function add_fixblock_script(){
        echo "
    jQuery(document).ready(function($) { 
    	var y = 0;
    	do { y += e.offsetTop; } while (e = e.offsetParent);
    	return y;
    }
    var block = document.getElementById('fixblock'), /* fixblock - значение атрибута id блока */
        topPos = getTopOffset( block );
    window.onscroll = function() {
    	var newcss = (topPos < window.pageYOffset) ? 'top:20px; position: fixed;' : 'position:static;';
    	block.setAttribute( 'style', newcss );
    }
    \n";
    }
    add_action( 'wp_footer', 'add_fixblock_script' );
    • Вы упустили строку с открывающим и закрывающим тегом <script> и еще пару-тройку строк. Вот так будет верно:

      function add_fixblock_script(){
          echo "<script type='text/javascript'>
      jQuery(document).ready(function($) { 
      function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
      }
      var block = document.getElementById('fixblock'), /* fixblock - значение атрибута id блока */
          topPos = getTopOffset( block );
          window.onscroll = function() {
      	var newcss = (topPos < window.pageYOffset) ? 'top:20px; position: fixed;' : 'position:static;';
      	block.setAttribute( 'style', newcss );
          }
      });
      </script>";
      }
      add_action( 'wp_footer', 'add_fixblock_script' );
      • Все так же, ломает шаблон:(

        • Михаил, к сожалению, лишь по фразе «ломает шаблон» я не смогу помочь вам определить причины. Опишите подробнее что именно происходит — виджет с <div id="fixblock"> у вас есть? Один или несколько? После вставки последнего кода выдается какая-либо ошибка или проблема исключительно в том, что некорректно отображается оформление блоков в боковой колонке?

          • Александра, спасибо за статью. Проблема заключается в том, что перед фикс. блоком есть еще виджеты. Так вот, фикс. блок раньше времени появляется, перекрывая блоки до него.
            Пробовал с подключением jQuery(document).ready(function($) {, не помогло.
            Может jQuery у меня вообще не подключено. в header.php прописал .
            Заранее спасибо.

          • Алексей, проблема возникает скорее всего из-за того, что есть виджеты с динамичеки загружаемым контентом.
            Можно попробовать подкорректировать значение в строке с объявлением topPos:

            var topPos = getTopOffset( block ) + 500;

            Вместо 500 подберите свое значение и реклама будет фиксироваться немного позже

  • На самом деле достаточно нестабильное решение… имхо. Тут не получится простого решения, т.к. нужно учесть массу нюансов… лично я решил от такого отказаться в пользу статики.

    • Константин, считаю это решение вполне стабильным, но при определенных условиях 🙂 О простом решении речи не идет, а вот о каких нюансах речь я бы с удовольствием узнала. Поделитесь?

      • ну, все нюансы имхо заключаются в позиционировании блока в общем и в ограничении области, в рамках которой будет двигаться блок. Первая же проблема это когда блок вылезает за приделы подвала, как на вашем кулинарном сайте: https://lh5.googleusercontent.com/-QRAgQIwwAvg/VBqNrzP71KI/AAAAAAAAnTg/5odwX9jJ8MM/w834-h572-no/18-09-2014%2B11-44-48.jpg — остальное думайте сами 🙂

        • C позиционированием проблем не вижу. А приведенная в пример проблема решается правильным выбором высоты блока.
          Спасибо за отзыв

          P.S. Кулинарный сайт не наш, а клиента.

  • Все работает отлично, но есть нюанс, код работает только с одной стороной, у меня например только слева, а вот когда добавляешь код в правую сторону то не хочет. Если можно помогите реализовать работу на 2-х сторонах. Спасибо

    • Александр, чтобы работал второй блок, нужно в коде (и нового блока и скрипта) сменить id.
      Если в примере указан id с названием fixblock, то для второго блока просто замените это название, например, на fixblock2. А скрипт модифицируйте как в этом примере.

      • Сделал как написано, но фиксируется только 1 блок . При чем, когда добавляю второй блок перестает фиксироваться первый и фиксируется второй. Когда удаляю второй блок первый опять фиксируется.
        Проверял все идентично вашему коду..

        • Дмитрий, а код для самих блоков одинаковый прописали или с разным значением id? Нужно для каждого блока свой id:

          <div id="fixblock">
          <!-- первый блок -->
          </div>

          а второй:

          <div id="fixblock2">
          <!-- второй блок -->
          </div>

          и скрипт с комментария выше

          • ID я прописан разный.
            Сейчас попробовал добавить еще 3-й блок, перестал работать второй, работает только третий.
            В общем работает только один блок указанный последним. Я сделал все как написано.

          • Дмитрий, попробуйте еще этот вариант. Он точно работает:

            <script type="text/javascript">
            function getTopOffset(e) { 
            	var y = 0;
            	do { y += e.offsetTop; } while (e = e.offsetParent);
            	return y;
            }
            var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
            var block2 = document.getElementById('fixblock2'); /* fixblock2 - значение атрибута id блока */
            if ( null != block || null != block2 ) {
            	var topPos = getTopOffset( block );
            	var topPos2 = getTopOffset( block2 );
            	window.onscroll = function() {
            	    var newcss = (topPos < window.pageYOffset) ? 
            		'top:20px; position: fixed;' : 'position:static;';
            	    var newcss2 = (topPos2 < window.pageYOffset) ? 
            		'top:60px; position: fixed;' : 'position:static;';
            	    block.setAttribute( 'style', newcss );
            	    block2.setAttribute( 'style', newcss2 );
            	}
            }
            </script>

            Единственное, стоит учесть, что если оба блока находятся в одной боковой колонке, то могут перекрывать друг друга при одинаковом значении top в css стилях. Поэтому в примере для второго блока я указала 60px. Если блоки в разных колонках, то замените на 20px

          • У меня таблица, в первой колонке находится баннер который я зафиксировал, в правой колонке статья с текстом. И при первом запуске сайта при скролинге вниз первая колонка исчезает и 2-я колонка с текстом прижимается к левому краю, а сам баннер поверх текста. При прокрутке наверх и новой прокрутке вниз проблема исчезает. Но при обновлении сайта снова возникает.

          • Дмитрий, для первой колонки попробуйте задать фиксированную ширину в стилях и добавить пустой блок до/после фиксированного блока.
            Ну а в идеальном случае — пользуйтесь блочной версткой… 🙂

  • Сайт просто кладезь 🙂 Спасибо огромное — искал буквально на днях эту информацию — не нашел, забил. Точнее нашел, но ничего не работало. Здесь же все работает, однако, как уже писалось в комментариях, блок заезжает под футер, уменьшить по высоте блок не представляется возможным, так как это рекламный баннер 240*400. Скажите, пожалуйста, есть ли возможность сделать так, чтобы блок останавливался за определенное кол-во пикселей до низа страницы (подберу вручную), то бишь чтобы он не прокручивался прямо до самого упора, а за пикселей 500 от низа останавливался. Пробовал марджином, но не помогло. Заранее спасибо за ответ и за прекрасную, полезную статью!

    • Максим, спасибо на добром слове 🙂 Будем рады видеть в числе постоянных читателей.
      Касательно Вашего вопроса. Учитывая, что этот блок фиксируется на определенной позиции относительно окна браузера, то остановить его не получится, т.к. прокручивается страница, а не сам блок.
      Как вариант решения проблемы с перекрытием подвала — скрывать блок, когда прокрутка уже в самом низу. Более-менее гибкое решение будет с вот таким кодом:

      <script type="text/javascript">
      function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
      }
      var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
      if ( null != block ) {
      	var topPos = getTopOffset( block ),
      	scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
      	blockHeight = block.offsetHeight, /* высота рекламного блока */
      	footerHeight = document.getElementById('footer').offsetHeight, /* footer - id блока футера */
      	/* считаем позицию, до которой блок будет зафиксирован */
      	stopPos = scrollHeight - blockHeight - footerHeight; 
      
      	window.onscroll = function() {
      		var newcss = (topPos < window.pageYOffset) ? 
      			'top:20px; position: fixed;' : 'position:static;';
      		if ( window.pageYOffset > stopPos ) 
      			newcss = 'position:static;';
      		block.setAttribute( 'style', newcss );
      	}
      }
      </script>

      Можно настроить блок «под себя», точно указав размер рекламного блока и/или футера (в пикселах) в строках 11 и 12. Например, вот так:

      
      	blockHeight = 400,  /* высота рекламного блока */
      	footerHeight = 500, /* высота футера */
      
  • Спасибо огромное за доработку! Высоту футера и самого блока не указывал (оставил, как в скрипте) — кстати, если не сложно, напишите, пожалуйста, как должны выглядеть строки после указания собственной высоты, а то в строке футера же указан еще id, не понял, как вставить высоту (мне просто для информации).

    У меня блок прокручивается до самого начала комментариев, а после пропадает — то бишь до футера не доезжает. Думаю, что это из-за того, что комменты подгружаются уже после полной загрузки и растягивают страницу (на аджаксе, походу), а скрипт успевает рассчитывать еще до появления комментов и потому так происходит. На самом деле это тоже неплохо, так как в комментах (до и после) еще два блока 468*60 и дабы привлечь к ним внимание, пусть пропадает плавающий блок в сайдбаре. Не знаю есть ли решение в такой ситуации (возможно, отложенная загрузка скрипта до того, как загрузятся комменты и скролл примет окончательную высоту или что-то вроде того) . Но по сути и так шикарно 🙂 Еще раз спасибо — у вас полезный ресурс!

    • Максим, строки с указанием высоты блоков (рекламного и подвала) я привела отдельно в комментарии выше. Вот так будет выглядеть код с точно заданной высотой:

      <script type="text/javascript">
      function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
      }
      var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
      if ( null != block ) {
      	var topPos = getTopOffset( block ),
      	scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
      	blockHeight = 400,  /* высота рекламного блока */
      	footerHeight = 500, /* высота футера */
      	/* считаем позицию, до которой блок будет зафиксирован */
      	stopPos = scrollHeight - blockHeight - footerHeight; 
      
      	window.onscroll = function() {
      		var newcss = (topPos < window.pageYOffset) ? 
      			'top:20px; position: fixed;' : 'position:static;';
      		if ( window.pageYOffset > stopPos ) 
      			newcss = 'position:static;';
      		block.setAttribute( 'style', newcss );
      	}
      }
      </script>

      По комментариям — да, скорее всего проблема именно в динамической загрузке. Можно попробовать вариант запуска скрипта, после полной загрузки документа:

      <script type="text/javascript">
      window.onload = function() {
          function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
          }
          var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
          if ( null != block ) {
      	var topPos = getTopOffset( block ),
      	scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
      	blockHeight = 400,  /* высота рекламного блока */
      	footerHeight = 500, /* высота футера */
      	/* считаем позицию, до которой блок будет зафиксирован */
      	stopPos = scrollHeight - blockHeight - footerHeight; 
      
      	window.onscroll = function() {
      		var newcss = (topPos < window.pageYOffset) ? 
      			'top:20px; position: fixed;' : 'position:static;';
      		if ( window.pageYOffset > stopPos ) 
      			newcss = 'position:static;';
      		block.setAttribute( 'style', newcss );
      	}
          }
      }
      </script>

      Но если загрузка комментариев выполняется в момент, когда до них доходит прокрутка — то этот вариант также вряд ли поможет.

  • Про строки я понял, я подумал, что нужно как-то их уместить так, чтобы и id футера остался.

    Добавил window.onload = function(), как вы и написали, но теперь блок пропадает примерно после 3-4 комментов. Ладно, это не так страшно, наоборот лучше, когда прямо перед комментами пропадает, так что оставлю, как было. Еще раз благодарю за помощь!

    • Максим, интересный случай. Учитывая, что на многих блогах стоят системы комментирования Disqus и Cackle, решение для сайта с асинхронной загрузкой информации лишним не будет.
      Давайте попробуем еще один вариант. Будем при каждой прокрутке получать общую высоту страницы. Теоретически, должно сработать даже без windown.onload :

      <script type="text/javascript">
      function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
      }
      var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
      if ( null != block ) {
      	var topPos = getTopOffset( block );
      
      	window.onscroll = function() {
      		var scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
      		    blockHeight = block.offsetHeight, /* высота рекламного блока */
      		    footerHeight = document.getElementById('footer').offsetHeight, /* footer - id блока футера */
      		    /* считаем позицию, до которой блок будет зафиксирован */
      		    stopPos = scrollHeight - blockHeight - footerHeight; 
      
      		var newcss = (topPos < window.pageYOffset) ? 
      			'top:20px; position: fixed;' : 'position:static;';
      
      		if ( window.pageYOffset > stopPos ) 
      			newcss = 'position:static;';
      
      		block.setAttribute( 'style', newcss );
      	}
      }
      </script>
  • Во, вот этот вариант просто великолепен! Правда, пришлось все же указать вручную высоту футера, как вы и говорили выше, а не через id, но теперь все круто! Спасибо! Да и информация другим пригодится.

    • Максим, отлично! Добавим этот вариант в статью, кому-нибудь точно пригодится

      • Не знаете еще, почему валидатор ругается?) Цитирую:

        Line 4006, Column 24: character «<" is the first character of a delimiter but occurred as data
        var newcss = (topPos < window.pageYOffset) ?
        This message may appear in several cases:
        You tried to include the "<" character in your page: you should escape it as "<"
        You used an unescaped ampersand "&": this may be valid in some contexts, but it is recommended to use "&", which is always safe.
        Another possibility is that you forgot to close quotes in a previous tag.

        • Максим, нужно скрипт закрыть html-комментарием. Вот так:

          <script type="text/javascript">
          <!--
               // код скрипта
          -->
          </script>
  • Так у меня ваш плавающий блок вроде и так закрыт с помощью данных html-комментариев 🙂

    var newcss = (topPos < window.pageYOffset) ?
    Это как раз строчка из него. Это не особо важно, просто интересно.

    • Максим, у Вас есть комментарий до скрипта и после. А нужно поставить открывающий тег комментария после <script> и закрывающий тег комментария до </script>. Вот наглядно с Вашим кодом скриншот.
      А ругается валидатор, потому что после левой треугольной скобки ожидает увидеть html-тег, а его нету. Поэтому, скрипты, размещенные в html-документе лучше закрывать как комментарий.

  • Ничего себе 🙂 Буду знать, спасибо большое! А если подгружать файлом .js, то такие комментарии не требуются верно? 🙂

  • не работает как надо, фиксируется, но прыгает вправо пикселей на 100..и верстка в блоке рушится…шире становится раза в два блок. Пробовал все варианты в том числе с jquery

    • У меня все работает, блок немного сдвигался влево, когда прилипал, но я это исправил марджином (подобрал до пикселя), вставляется в эту строчку: ‘top:20px; position: fixed;’ Например:
      ‘top:20px; margin-left:50px;position: fixed;’

    • Serg, если становится шире, то нужно точно указывать ширину блока. Или в стилях (если WordPress — файл style.css Вашей темы) или в скрипте, как порекомендовал Максим Измайлов. Только в Вашем случае нужно указать значение width:

      'top:20px; position: fixed; width: 240px;' : 'position:static;';
  • ага, спасибо..так работает..есть небольшой скачок в строну, надо наверное небольшое смещение прописать как выше обозначил Максим Измайлов

    Но вот еще вопрос..в данном случае блок начинает фиксироваться когда при прокрутке достигается его верхняя граница…
    В этом есть один существенный недостаток. Ведь если баннер по длине больше чем высота экрана, то он намертво фиксируется и вида лишь его часть (у меня например 9 тизеров, при фиксации видны только три..остальные 6 не увидеть никак)). Тоже самое происходит с мелкими баннерами при маленьких разрешениях…А возможно ли сделать так, что бы баннер прокручивался по длине, но фиксировался при достижении соответсвенно верхней или нижней границы? Или импосибл?

    • Serg, если есть скачок, попробуйте добавить margin-left, подобрав нужное значение в пикселях.
      Относительно прокрутки внутри блока — такой вариант можно реализовать с использованием CSS свойства overflow. Решение нужно «подкручивать» под высоту конкретного рекламного блока.

      В скрипте замените эти строки:

      var newcss = (topPos < window.pageYOffset) ? 
          'top:20px; position: fixed;' : 'position:static;';
      

      На вот это:

      var scrollcss = '', maxh = document.body.clientHeight;
      if ( maxh < 600 )  // где 600 - это высота рекламного блока в px
      	    scrollcss = 'max-height:' + maxh + ';overflow: scroll;';
      			
      var newcss = (topPos < window.pageYOffset) 
          ? 'top:20px; position: fixed; ' + scrollcss
          : 'position:static; overflow: visible; max-height: none;';
      

      Переменная maxH - это текущая высота окна браузера. В следующей строке место 600, поставьте реальную высоту рекламного блока, когда он не прокручивается.

      • не дало никакого эффекта(( менял maxh и так и эдак, никакой разницы… блок также намертво фиксируется в тот момент когда его верхняя граница достигает верхней границы окна…далее не крутится

        • Без наглядности трудно сказать в чем проблема.
          Вот рабочий пример на моем втором блоге — если сделать окно браузера по высоте меньше 600 пикселей (т.е. меньше чем зафиксированный рекламный блок в сайдбаре), то можно наблюдать появление прокрутки внутри блока. О такой реализации шла речь?
          В этом варианте прокручиваться информация внутри блока будет только если подвести курсор на блок и прокрутить скролл. Чтобы текст внутри прокручивался автоматически — нужно подключать слайдер или ротатор на JavaScript или jQuery.

  • похоже, не совсем,впрочем прокрутки даже такой нет. Я имел ввиду, что при прокрутке страницы блок прокручивается до своей нижней границы (вровень с нижней границей окна) и только потом фиксируется, если же начать крутить вверх скроллинг, то блок со страницей прокручивается до своей верхней границы и опять фиксируется, таким образом большой блок при скроллинге плавает от своей нижней границы до верхней . Но как я понял такое так просто не сделаешь…а от «ручной» прокрутки имхо толку немного, врядли кто будет руками крутить тизеры))
    А вообще вот Прокрутка не появилась…

    • Serg, тогда подключайте скрипт автоматической прокрутки отдельно к этому блоку. И будет он и фиксироваться и автоматически прокручиваться. А с высотой рекламного блока в 2600 пикселей даже проверку не нужно делать 😉

      Вот эти строки

      var newcss = (topPos < window.pageYOffset) ? 
          'top:20px; position: fixed;' : 'position:static;';
      

      Переписываете на if, в котором активируете плагин прокрутки:

      var newcss = '';
      if (topPos < window.pageYOffset) {
          newcss = 'top:20px; position: fixed; '; 
          // подключить скрипт автопрокрутки к блоку fixed
      } else {
          newcss = 'position:static; overflow: visible; max-height: none;';
          // отключить скрипт прокрутки
      }
      

      Для автопрокрутки присмотритесь к скриптам вроде jQuery Scrollbox: демо (пример под номером 3 - как раз ваш случай), официальная страница с инструкциями (на англ.) и инфа на русском.

  • Спасибо! Попробую применить этот код. Раньше пользовался подобным, но сейчас почему-то на новом шаблоне (а может из-за новой версии WP) не работает. Использую пока плагин Q2W3 Fixed Widget.

  • а в чем может быть проблема если виджет слишком рано фиксируется? когда остатся при прокрутке от верхней границы окна до него гдето 100 пикселей, он прыгает на верх..тоесть на свое место, где он зафиксирован, тем самым перекрыая предыдущий виджет..пробовал jquery подключать и заменять первую-последнюю строку скрипта..без толку, все равно есть скачок.
    И кажется при каждом обновлении страницы это расстояние разное
    Есть пара виджетов аля «популярные статьи»..это в прицие динамика, но они не меняются по высоте..Да и вообще все виджеты в вордпрессе динамические по идее..метки, последние статьи…

    • Serg, речь шла не о динамических виджетах, а о динамически подгружаемом контенте. Т.е., во время или после загрузки страницы какой-либо скрипт подгружает данные.
      У Вас проблема может быть в том, что информация в самом рекламном блоке подгружается динамически с сайта рекламодателя. Или — в разметке, она не совсем корректная в сайдбаре. Можно попробовать в style.css найти вот этот код (строка 197):

      #sidebar ul li.widget {
      float: left;
      width: 280px;
      padding: 10px 10px 30px 10px;
      -moz-border-radius-bottomleft: 5px;
      -moz-border-radius-bottomright: 5px;
      -moz-border-radius-topleft: 5px;
      -moz-border-radius-topright: 5px;
      margin-bottom: 15px;
      background: url('images/wg-bottom.gif') repeat-x bottom;
      }

      И закоментировать строку с float: left:

      #sidebar ul li.widget {
      /* float: left; */
      width: 280px;
      padding: 10px 10px 30px 10px;
      -moz-border-radius-bottomleft: 5px;
      -moz-border-radius-bottomright: 5px;
      -moz-border-radius-topleft: 5px;
      -moz-border-radius-topright: 5px;
      margin-bottom: 15px;
      background: url('images/wg-bottom.gif') repeat-x bottom;
      }

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

      var topPos = getTopOffset( block );

      укажите свое значение:

      var topPos = 1850;

      Оно будет примерно 1850 пикс, меняйте на больше/меньше по ситуации.

  • прошу прощения)) речь о другом сайте..на том я снял фикс, там он не катит в своем обычном виде..а как сделать с прокруткой в пределах блока я не знаю. Речь о другом сайте, но выяснилось что все скрипты, а не только ваш, так себя ведут (прыжок вверх на 100-300 пикселей). Ну да ладно…фиг с ним, что и где глючит слишком накладно выяснять, проще вернуться к статике

  • Здравствуйте опять)) Подскажите если несложно, блок после фиксации влияет на бекграунд на область под ним (бэкграунд сайдбара исчезает).. Как сделать так чтоб блок он не влиял на фон? background:none; для #fixblock ничего не решает..просто убирается фон сайдбара

    • Serg, если фон установлен отдельно для каждого блока виджета (чаще всего это тег li с классом widget), то после фиксации бэкграуд пропадет. Не будет пропадать только если установлен сплошной фон для всей боковой колонки.
      Можно найти в стилях какой фон прописан для блока с виджетом и такой-же фон установить для блока #fixed прямо в style.css.

  • Здравствуйте! Подскажите как решить проблему с адаптивным дизайном. То есть, если зайти с мобильного на сайт, то блок прыгает и закрывает половину контента. Может как нибудь стилями его запретить? например если разрешение меньше 1024 то он допустим не действует!

    • Лёшкин, достаточно добавить условие с проверкой ширины экрана. Вот пример доработанного кода скрипта, где фиксация блока будет срабатывать только при ширине экрана от 1024 пикселей:

      <script type="text/javascript">
      function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
      }
      var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
      if ( null != block ) {
      	var topPos = getTopOffset( block );
      	window.onscroll = function() {
                      if ( $(window).width() >= 1024 ) {  // проверка ширины экрана
      			var newcss = (topPos < window.pageYOffset) ? 
      				'top:20px; position: fixed;' : 'position:static;';
      			block.setAttribute( 'style', newcss );
      		}
      	}
      }
      </script>
      • Спасибо! То, что нужно!

      • Не работает фича с определением разрешения. Как не пытался, но на планшетах из-за fixed возникают проблемы, при зуме.

        • При фиксации блока ему задается фиксированный размер и положение, поэтому при зуме будет нестандартное поведение у любого блока с аналогичными параметрами. И проблема не в коде фиксации, а в особенности самой фиксации и стилях блока.
          Попробуйте использовать более подходящее решение с показом рекламы для мобильных устройств, стразу фиксируя строчку в низу окна (как это обычно делается в приложениях).

  • Спасибо. Давно искал. У вас именно то что мне нужно было. Еще классно что очень просто написано. Все понял, сделал за 5 мин.

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

    Скрипт:

    function getTopOffset(e) { 
    	var y = 0;
    	do { y += e.offsetTop; } while (e = e.offsetParent);
    	return y;
    }
    var block = document.getElementById('block -a'); /* fixblock - значение атрибута id блока */
    if ( null != block ) {
    	var topPos = getTopOffset( block );
    	window.onscroll = function() {
    		var newcss = (topPos < window.pageYOffset) ? 
    			'top:20px; position: fixed;' : 'position:static;';
    		block.setAttribute( 'style', newcss );
    	}
    }
    var block2 = document.getElementById('block-b'); /* fixblock2 - значение атрибута id блока */
    if ( null != block2 ) {
    	var topPos2 = getTopOffset( block2 );
    	window.onscroll = function() {
    		var newcss2 = (topPos2 < window.pageYOffset) ? 
    			'top:0px; position: fixed;' : 'position:static;';
    		block2.setAttribute( 'style', newcss2 );
    		}
    }
  • Добрый день.
    До сегодня было все хорошо. А сегодня такая проблема: в хроме и яндексбраузере блок не скрывается, а заезжает на футер (если не заходить в админку). Однако если зайти в админку, то все работает отлично.
    Скажите в чем может быть проблема?
    Сам код (скрипт) — не менял.

    • Добрый день, Юрий. Проблема в высоте страницы и блока. Возможно, Вам помогут один из двух последних кодов в статье — там как раз учитывается подвал (вычисляется его высота или можно задать числовое значение), чтобы фиксированный блок не перекрывался с ним.

  • Спасибо, Александра и Владимир! Сделал у себя на сайте. Шаблон респонсивный, радует то, что виджет с рекламой на мобилках просто смещается вниз и ничего не перекрывает но да, проверять надо.

    Скажите, а почему сейчас на сайте http://blondnotes.ru/ реклама в сайдбаре статичная? Почему решили отказаться от плавающего блока?

    • Это временная неисправность. Сайт используется часто для наших экспериментов, по этому ничего удивительного.

      • Решил еще раз проштудировать рекомендации Гугла по поводу объявлений: в плавающий блок их вешать нельзя, могут забанить аккаунт (в сети нашлась переписка с поддержкой AdSense по поводу такого блока). https://support.google.com/adsense/answer/1354736?hl=ru — вот тут указано, что следует избегать такого приема как «размещение объявлений в плавающих окнах и перемещающихся рекламных блоках с целью привлечения внимания». Однако, это не касается контекстной рекламы Яндекса.

        • Это действительно так. Вопрос обсуждался в соседнем топике — читать
          Даже есть уже случай с практики. Подобный блок с adsence был установлен на дружественном сайте и простоял там около полугода. Заработок владельцев вырос не реально и всё было хорошо. Но потом из-за резкого повышения трафика (выскочили сезонные запросы), резко выросла и выручка с рекламы, перевалив за 500 евро с одного блока. Буквально через неделю пришло письмо от adsence, в котором говорилось, что реклама размещена неправильно и привлекает на себя излишнее внимание, у вас есть 3 дня на исправление или будет бан. Хозяева просто убрали фиксацию и реклама показывается дальше. Правда о заработке теперь с блока лучше не спрашивать 🙁
          Случаев нарушений правил размещения блока от других рекламных сетей пока не поступало. Судя по всему, данный метод не нравиться только Google.

          • Спасибо, Владимир. Тоже наткнулся на историю про 500 евро с блока на одном из блогов, рискну предположить, что речь про один и тот же блог. У меня такой блок также показал заработок больше, чем 2 других вместе взятые( Размещал 300×600 в сайдбаре.
            Что ж, фиксацию лучше потестировать тогда и применять, например, для блока подписки (с него и начну тест) либо для лока с партнерскими ссылками или собственным баннером.
            Спасибо за ответ, классный блог сейчас стал, подписался.

          • Очень интересная тема. Тоже подумывал о размещении adsense в зафиксированном блоке.
            Прочитав ваши комментарии, хочу прояснить кое-какие моменты:
            1. Как я понял, до сезонных запросов-повышения трафика владелец того сайта (не знаю, о каком сайте идет речь) регулярно получал гугловский чек и обналичивал деньги? Или нет?
            2. После 500+ евро Гугл не банил сразу сайт, а вежливо предупредил?

          • Всё правильно. Я так подозреваю, что в Google обратили внимание на сайт, когда тот превысил определённый заработок. Либо же резкий скачок посещалки, а с ним и дохода, заставил присмотреться к ресурсу. Ведь до этого реклама стояла себе спокойно с полгода.
            После предупреждения сняли фиксацию и AdSence работает до сих пор без проблем.

          • Спасибо. Значит, можно поэкспериментировать))) хотя бы попробовать.

  • Добрый день! Попробовал зафиксировать виджет указанным кодом, но выявилась одна проблема — если мы пытаемся масштабировать окно на планшете, либо другом устройстве с сенсорным экраном фиксированный виджет «выезжает» из сайдбара. можно ли как-то устранить этот эффект?

    • Евгений, данный код не рассчитан на работу с тач-устройствами и наличие проблем зависит от случая и конкретной верстки сайта. Поэтому и говорить о решении не могу.

      • Понятно — подобная проблема возникает и при использовании других плагинов WordPress, в том числе и на других сайтах проверял… Жаль. Если вдруг кто-то найдет решение проблемы — буду очень признателен.

  • Александра, вот прям ОГРОМНОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО за скрипт! Сегодня перерыл Интернет вверх дном в поисках подходящего для адаптивного дизайна скрипта, уже отчаялся, оффнулся. Потом решил последний раз попытать счастья, опять полез в Гугл и … ба-бац, сразу на Ваш пост наткнулся.
    Немного «ТОНКОСТЬ» подпорчивает впечатление, но это только на мобильных устройствах и уже в самом конце страницы. А в остальном все супер, спасибо!

  • здравствуйте, попробовал больше чем на дюжине сайтов, гдето работает, гдето работает «наполовину» (есть определенніе нюансі),а гдето вообще не работает никак . Подскажите, от чего работспособность в основном зависит, другие скрипты мешают? Понятно, что каждый случай индивидуален..но все же наверное есть какието основные причины..

    • Сергей, конфликт с другими скриптами возможен, но чаще всего проблемы возникают из-за особенной верстки или некорректной установки.

  • Благодарю за действительно работающий скрипт! Все получилось с первого раза!
    Единственное, что при прокрутке до начала действия скрипта блок немного смещается, будто бы прописанные стили как для сайдбара перестают работать. Можно ли к плавающиму блоку закрепить такие же стили как в сайдбаре?

    • Максим, у Вас в верстке ширина для блоков четко не прописана, поэтому и «скачет». Добавьте в скрипт установку фиксированной ширины и все будет на месте. Там, где прописан код стилей:

      top:20px; position: fixed;

      допишите установку ширины:

      top:20px; width:280px; position: fixed;
  • Александра, благодарю за отзывчивость и за скорый ответ! Сегодня вечером попробую подправить 🙂

  • Александра, Вы волшебница!)) Все стало на свои места как нужно 🙂 Благодарю за помощь! Оставлю Ваш сайт в закладках, может еще что интересного найду для своего блога. Успехов в работе!))

  • Александра. Подскажите а как сделать такой же блок как у вас в внизу страницы (там где написано «Понравилась статья?» и стоят кнопки соц сетей. Вот этот блок мне очень понравился.)

    • Роман, блок особо по принципу работы не отличается. Разница в стилях оформления, благодаря чему блок фиксируется не сверху (как блок в сайдбаре), а внизу и растягивается на всю ширину страницы.
      С примером кода парой слов не обойтись, лучше опубликую небольшой урок в ближайшие дни по настройке такого блока.

  • Здравствуйте. Спасибо за статью.
    Сделал фиксированный блок с рекламой в левом сайдбаре по первому варианту в статье. Работает почти так, как нужно. Проблема появляется, если появляется горизонтальная прокрутка. При горизонтальной прокрутке блок начинает наезжать на все остальное содержимое. Подскажите, пожалуйста, как можно модифицировать первый скрипт, чтоб блок становился статичным, если производится горизонтальная прокрутка?

    • http://avovkdesign.com/kak-zafiksirovat-blok-v-bokovoj-kolonke-s-pomoshhyu-javascript.html#comment-784
      Сори за невнимательность. Вот то, что должно подойти. Щас буду пробовать

      • Изыскания показали, что при том условии проверки должен быть подключен jquery — без него не работало.
        Нашел версию для проверки на javascript

        document.documentElement.offsetWidth>= document.documentElement.scrollWidth

        работает также, как и ваш пример.
        В принципе, в мобильных браузерах теперь у меня плавающий блок с таким условием статичный (что устраивает). При загрузке сайта в маленьком окне браузера тоже статичный. А вот если загрузить в полноэкранном режиме, а потом уменьшить окно, то также наезжает на контент, да потом еще и на меню, под которым расположен плавающий блок, при прокрутке вверх страницы. Разворачиваем на весь экран — не наезжает на меню.
        Пойдет и так, думаю, что только я так извращаюсь с просмотром своего сайта.
        Но если есть решение, подскажите, пожалуйста.

        • Петр, в примере на автомате использовала проверку ширины с JQuery. Вместо $(window).width() в JavaScript нужно использовать один из следующих вариантов:

          document.body.clientWidth   /* ширина тега <body> */
          document.documentElement.clientWidth   /* ширина тега <html> */
          window.innerWidth    /* ширина окна */

          Или применить кроссбраузерное решение для определения ширины:

          var window_width = window.innerWidth 
                      || document.documentElement.clientWidth 
                      || document.body.clientWidth;

          Чтобы управлять блоком в процессе изменения ширины окна, нужно добавить функцию для события onresize:

          window.addEventListener("resize", myFunction);
          function myFunction(){
          
                var window_width = window.innerWidth 
                      || document.documentElement.clientWidth  
                      || document.body.clientWidth;
          
                //  проверяем ширину экрана и добавляем нужный свойства, например:
                if ( window_width >= 1024 )
                      document.getElementById('fixblock').setAttribute( 
                            'style', 
                            'position:static;' 
                      );
                }
          };

          Последней сниппет кода доработайте под свои условия, выставив нужные стили под определенную ширину экрана.

  • В IE 8 увы не работает. Не подскажите, как сделать универсальный вариант?

  • Здравствуйте. Что-то у меня не получается реализовать фиксацию блока над футером, он уходит выше.

    function getTopOffset(e) { 
    	var y = 0;
    	do { y += e.offsetTop; } while (e = e.offsetParent);
    	return y;
    }
    var block = document.getElementById('fixblock');
    if ( null != block ) {
    	var topPos = getTopOffset( block );
        window.onscroll = function() {
            var scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
            blockHeight = block.offsetHeight,
            footerHeight = document.getElementById('footer').offsetHeight, 	    
            stopPos = scrollHeight - blockHeight - footerHeight;
            var newcss = (topPos < window.pageYOffset) ? 'top:10px; position: fixed;' : 'position:relative;';
            if ( window.pageYOffset > stopPos) 
            newcss = 'top:'+stopPos+'px;';
            block.setAttribute( 'style', newcss );
    	}
    }
    • Артем, убедитесь, что в разметке Вашего сайта блок футера действительно имеет идентификатор id="footer". Если другой, то замените id на свой в этой строке:

      footerHeight = document.getElementById('footer').offsetHeight,
  • Пересмотрел кучу сайтов, только ваш вариант мне удалось установить себе на сайт, спасибо большое!

  • Заметил один неприятный эффект: если высота рекламного блока, превышает высоту контекста, то при скроллинге вниз происходит скачек. Проверял в последних версиях Mozilla, Chrome, IE.

    Вот пример:

    <div id=info style="right: 100; top:0px; position: fixed;">-</div>
    
    <table border="1">
    <tr valign="top">
    <td width="30%">
    sidebar
    <br><br><br><br><br><br>
    <div id="fixblock">
    adver1<br><br><br><br><br><br><br><br><br><br><br>
    adver2<br><br><br><br><br><br><br><br><br><br><br>
    adver3<br><br><br><br><br><br><br><br><br><br><br>
    adver4<br><br><br><br><br><br><br><br><br><br><br>
    adver5<br><br><br><br><br><br><br><br><br><br><br>
    adver6
    </div>
    </td>
    <td width="30%">text text text text text text text text text</td></tr>
    <tr><td id=footer height="50" colspan=2>footer</td></tr>
    </table>
    
    <script type="text/javascript">
    function getTopOffset(e)
    {
    	var y = 0;
    	do { y += e.offsetTop; } while (e = e.offsetParent);
    	return y;
    }
    
    var block = document.getElementById('fixblock');
    if (null!=block)
    {
    	var topPos = getTopOffset(block);
    
    	window.onscroll = function() {
    
    			var scrollHeight = Math.max(document.body.clientHeight, document.documentElement.scrollHeight, document.documentElement.clientHeight);
    			var blockHeight = block.offsetHeight;
    			var footerHeight = 50;
    			var stopPos = scrollHeight - blockHeight - footerHeight;
    
    document.getElementById('info').innerHTML='document.body.clientHeight: '+document.body.clientHeight+'<br>document.documentElement.scrollHeight: '+document.documentElement.scrollHeight+'<br>document.documentElement.clientHeight: '+document.documentElement.clientHeight+'<br>max height: '+scrollHeight;
    
    			var newcss = (topPos < window.pageYOffset) ? 'top:0px; position: fixed;' : 'position:static;';
    			if (window.pageYOffset>stopPos) newcss = 'position:static;';
    			block.setAttribute('style', newcss);
    	}
    }
    </script>

    Подскажите, как исправить?

    • Скачок происходит в момент, когда блок достигает подвала и фиксация снимается. А видно этот скачек в примере из-за того, что изначально в блоке установлена фиксированная позиция. Если убрать вот эти строки, то скачок пропадет:

      if (window.pageYOffset>stopPos) newcss = 'position:static;';
      			block.setAttribute('style', newcss);

      Не понятно только одно — если блок постоянно зафиксирован относительно окна браузера, то в каких целях используется скрипт?

      • Скачок происходит в момент, когда блок достигает подвала и фиксация снимается.

        Это не так. Скачек виден в самом начале скроллинга, когда до подвала еще очень и очень далеко.

        Не понятно только одно — если блок постоянно зафиксирован относительно окна браузера, то в каких целях используется скрипт?

        На разных страницах сайта — разный объем данных. И узнать заранее где нужно фиксировать блок при прокрутке, а где нет — нельзя. Поэтому скрипт присутствует на всех страницах где есть рекламный блок.

        • Grey, без сайта трудно что-то сказать. В приведенном примере у меня нету скачка в начале прокрутки. Возможно, позиция фиксации не точно рассчитывается и стоит попробовать подобрать значение вручную

  • Чтобы увидеть «эффект», медленно потяните полоску скролла вниз и в какой-то момент, положение страницы перескочит снова в самый верх.

  • Спасибо за вариант. Но у него, как почти у всех, что есть в сети, есть одна проблема. На планшетах, к примеру, если увеличить шрифт, то реклама наезжает на контент. Можно ли решить эту проблему?

    • Владимир, это решение не учитывает адаптивность. Подозревая, что увеличение шрифта скорее всего делается масштабированием? В этом случае очень тяжело управлять поведением блоков.
      Лучшее решение — на мобильных и планшетах показывать рекламу фиксируя ее в низу экрана.

  • Здравствуйте, код работает, пользуюсь давно. Но сейчас возник конфликт в другим скриптом (геотаргетинга), от чего тот не хочет работать вместе с вашим плавающим блоком.

    <script src="http://yastatic.net/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript">
      window.onload = function () {
          jQuery("#user-city").text(ymaps.geolocation.city);
      }
    </script>
    <script src="http://api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU" type="text/javascript"></script>

    Как решить проблему?

    • Артём, у Вас в коде ошибка — дважды указывается открывающий тег <script> и закрывающий &lgt;/script>. И строчка с jQuery там также не нужна, код фиксации работает на чистом JavaScript.

      скриншот ошибки в коде

      • Спасибо. В этом скрипте не ошибка, я просто обернул его в «noConflict», но дело было не в этом, и даже не в вашес скрипте. Проблема была в javascript коде самого баннера, а не плавающего блока. Заменил код баннера на обычный и всё заработало. Однако ваш плавающий блок всё же заменил на плагин Q2W3 Fixed Widget, он позволяет фиксировать блок перед футером, а ваш код убирал блок на исходную позицию, когда он доставал футер.

  • Спасибо, отличный скрипт!
    Хочу добавить, что у меня плавающий header, поэтому сайдбар был перекрыт.
    Поэтому увеличил отступ от верха.
    var newcss = (topPos < window.pageYOffset) ?
    'top:20px; position: fixed;’ : ‘position:static;’;

    Можно добавить тоже в статью и закомментировать:)

  • ГЕНИЙ!!!!!!
    Успехов, Вам и спасибо большое!

  • Добрый день, такой вопрос, сайт на вордпрессе в боковой колонке реклама адсенс , как сделать ее плавающей, т.е. в какие файлы добавлять код?

  • Добрый вечер! Спасибо большое, всё работает, воспользовался первым кодом, чуток находит на подвал, но меня волнует, что полностью сбивается внешний вид, то есть надо или стили как-то прописать к этому блоку отдельно или что? Не подскажите? Ещё раз спасибо.

    • Odessit, да — если в стилях не прописана фиксированная ширина блока, то он может менять внешний вид при фиксации. Ранее обсуждали этот момент — Вы можете просто точно указывать ширину блока при фиксации, как в этом примере.

      • Ссылка битая. Если вариант из комментариев выше, то не работает, уже пробовал. Пробовал методом тыка в style.css прописывать стили как к sidebar, что-то оно там начало обрамляться, но все равно ломается. Сейчас пришлось ваш скрипт снять, так как нагрузка на хостинг выросла в 2 раза за последние 3 дня, как раз как его установил. Посмотрю результат, если не он, то придётся вас дальше мучать)))

        • Odessit, фиксация блока через JavaScript абсолютно не может повлиять на увеличение нагрузки на хостинг. JavaScript выполняется браузером, а не сервером, — соответственно это нагрузка на компьютер посетителя.
          Ищите другие причины — может обновлялись, или атака на xmlrpc.php была (по логам сервера легко отследить по количеству обращений к этому файлу).

          Что же касается зафиксированного блока — как поставите снова код и выставите фиксированную ширину — дайте знать, я загляну и исправим проблему.

  • Да, порылся в логах, вижу что wp-cron.php запросы увеличились в разы, теперь думаю что с этим делать…Написал хостеру, но что-то рвения решить вопрос, от них особо не вижу…

    • Odessit, проверяйте плагины — возможно, какие-то антивирусы или защитники активно работают, может еще быть регулярная проверка на битые ссылки.

  • Добрый день! Вернул скрипт, выставляю ширину сайдбара 270, текст растягивается на ширину 270, выставляю на 249, которые есть в стилях, все равно ломается и вот как будто на чуточку съезжает вправо, ставил и 248 и 250…
    Попробую вставить стили к сайдбару, может вы глянете и увидите что не так((( Заранее спасибо.

    /*боковая колонка*/
    #sidebar{width:270px;margin:25px 0 0 0;padding:5px 0 0 0px;float:left;text-shadow:1px 1px 1px #FFFFFF}
    
    /*заголовки блоков в сайдбаре*/
    .title{background:url(images/title.png) no-repeat;width:271px;height:56px;position:absolute;top:0;left:0}
    .title h4,.title2 h4{color:#cccccc;text-shadow:1px 1px 1px #000000;padding:8px 0 5px 20px;font-size:16px}
    
    
    /*блоки сайдбара*/
    .widget{padding:60px 10px 20px 20px;margin-bottom:40px;font-size:17px;background:#eaeaea;position:relative}
    .widget ul{list-style-type:none;margin:0px 0px 15px 0px;padding:0}
    .widget ul li{list-style-type:none;margin:0px 0px 5px 0px;padding:0 0 0 25px;background:url(images/li.gif) 0px 8px no-repeat}
    .widget li ul{list-style:none;display:block;padding:10px 0px 0px 0px}
    .widget ul li ul li{list-style:none;display:block;padding:0px 0px 0px 25px;background:url(images/li.gif) 0px 8px no-repeat}
    .widget a{text-decoration:none;color:#333}
    .widget a:hover{text-decoration:underline;color:#d42455}
    .wid-shadow{background:url(images/shadow2.png) no-repeat;width:249px;height:11px;position:absolute;bottom:-11px;left:10px;}
    • Odessit, в самом скрипте идеально прописать ширину блока при фиксации в 240px — тогда ширина идеально сохранится. Но из-за того, что реклама у Вас в виджете с серым фоном, который после фиксации пропадает, кажется что есть скачок.

      • Это не реклама с серым фоном, он везде серый. Когда я выводил блок через плагин, то стили не ломались, виджет плыл весь обрамлённый серым и сверху была эта чёрная шапка с надписью — реклама.
        Сейчас вот прописал вот так, как для всех виджетов, оно не ломается, но отскакивает чуть вправо и пропадает вот эта чёрная шапка с надписью — реклама. Как то это можно поправить?

        #fixblock{padding:60px 10px 20px 20px;margin-bottom:40px;font-size:17px;background:#eaeaea;position:relative}

  • спасибо вам большое, у меня стоит тема thesis 2 и думала ничего не получится, но все получилось с 1 раза.

  • Здравствуйте, Александра! Больше вам спасибо за этот скрипт.

    Подскажите, как сделать так чтобы блок не исчезал над футером, а останавливался?

  • Добрый день! Подскажите пожалуйста. Если вы посмотрите на страницу которую я указал, то вы увидите что текст заканчивается до того как блок начинает плавать, так вот, при попытке прокрутки вниз, он как проскакивает опять на нало и так по кругу, ну вы сами можете посмотреть. Что с этим делать? На длинных страницах где он плывёт раньше чем заканчивается текст, всё хорошо, он знает где останавливаться.

    • Odessit, так и не увидела описанного Вами эффекта. Возможно, нужно немного откорректировать позицию, с которой начинает плавать блок, попробуйте добавить/отнять 10-20 пикселей.

      • Вы имеете в виду top:20px? поигрался, ничего. В каком браузере у вас всё хорошо? У меня хром, опера, мозилла едет(((

        • Odessit, в скрпте вычисляется topPos — позиция, с которой блок фиксируется. Попробуйте просто добавить или отнять несколько пикселей от этого значения. Вместо строчки:

          var topPos = getTopOffset( block );

          написшите:

          var topPos = getTopOffset( block ) + 10;
  • Здравствуйте! Скажите пожалуйста, можно ли сделать так, чтобы фиксированный блок при достижении footerHeight не исчезал резко, а как бы упирался в него и дальше уже прокручивался вместе со страницей. Надеюсь вы меня поняли. Заранее спасибо. Жду ответа.

    • Фаина, думаю можно. При достижении блока прописать position:absolute и значение top, равное текущей позиции блока. Например, в коде с учетом высоты футера, попробуйте заменить:

      if ( window.pageYOffset > stopPos ) 
      			newcss = 'position:static;';

      на вот это:

      if ( window.pageYOffset > stopPos ) 
      			newcss = 'position:absolute;top:' + getTopOffset( block );

      Работоспособность не гарантирую, но это вариант от которого можно оттолкнуться в нужном направлении.

  • Александра, можно ли зафиксировать сайдбар этим кодом? Вернее его нижнюю часть, чтобы при прокрутке статьи он не уезжал вверх. А то смотрится как-то не очень, когда остается только средний блок, а сайдбар уползает.

  • Александра, добрый день!
    А не подскажете как закрепить сторонний баннер. К примеру Баннер Adsense гугл без манипуляций в кодах сайта.
    Я как то сделал такой баннер через скорее всего position:fixed но теперь не помню где вставлял и что(?

    • Василий, можно в CSS прописать для нужного блока (по его классу или id) position:fixed, но он зафиксируется сразу же в том месте, какое укажете.
      Например, чтобы зафиксировать снизу справа блок, в html которого прописано class='ad_245', нужно в style.css написать небольшой код:

      .ad_245 {
         position: fixed;
         bottom: 10px;
         right: 10px;
      }
  • Здравствуйте. Подскажите, пожалуйста, можно ли как-то сделать так, чтобы фиксированный блок исчезал, доходя до определенного элемента в контентной части?

    • Павел, для этого нужно взять какой-то блок за ориентир (или фиксированное значение высоты).
      Например, если нужно, чтобы блок исчезал при достижении прокрутки блока с id="stop-position", то можно воспользоваться следующим кодом:

      <script type="text/javascript">
      function getTopOffset(e) { 
      	var y = 0;
      	do { y += e.offsetTop; } while (e = e.offsetParent);
      	return y;
      }
      var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
      if ( null != block ) {
      	var topPos = getTopOffset( block );
      
      	window.onscroll = function() {
      		var scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
      
      		    // определяем высоту рекламного блока
      		    blockHeight = block.offsetHeight,
      
      		    // определяем позицию, до которой блок будет зафиксирован 
      		    stopPos = document.getElementById('stop-position').offsetHeight; 
      
      		var newcss = (topPos < window.pageYOffset) ? 
      			'top:20px; position: fixed;' : 'position:static;';
      
      		if ( window.pageYOffset > stopPos ) 
      			newcss = 'position:static;';
      
      		block.setAttribute( 'style', newcss );
      	}
      }
      </script>
  • Александра, здравствуйте.
    Спасибо за статью, все заработало. Несколько вариантов пробовал из Гугла, все отказывались работать, в том числе и «волшебный» Q2W3 Fixed Widget (скорее всего из-за inline-стилей виджетов в сайдбаре, которые я так и не понял, где задаются в теме).

    Вопрос в следующем — можно ли малыми усилиями сделать плавное появление блока в случае «getTopOffset( block ) + X;» ?

    • Sheff, если фиксирование блока должно происходить раньше или позже, чем прокрутка достигает его положения, то нужно применять другой метод. Простой вариант (как в этой статье) со сменой статичной позиции на фиксированную не подойдет. А плавное появление — это управление свойством opacity (можно попробовать скомбинировать с CSS transition для плавной смены прозрачности блока), но как это будет выглядеть — нужно экспериментировать. Лучше, конечно же, сразу писать скрипт на jQuery под свои нужды.

  • И еще один вопросик вдогонку — как сделать так, чтобы скрипт работал только при ширине, большей определенного значения? При ширине, меньшей 1230px, сайдбар уходит вниз, а этот блок так и левитирует:(

    • Добавьте проверку на ширину экрана. Например, замените условие в строке

      if ( null != block ) {

      на:

      if ( null != block && window.innerWidth >= 1230 ) {
           // код скрипта
      }
      • Ммм. Не совсем то. Скрипт проверяет это условие только при загрузке страницы. Точнее, все то, просто я, видимо, неправильно описал условие) нужна адаптация при изменении ширины экрана. То есть я изменяю ширину туда-сюда, а скрипт только при ширине >1230px фиксирует блок, а при меньшей — возвращает его на свое место. Нужно копать в сторону window.resize видимо. Буду признателен за помощь.

  • Sheff, да — при таком условии нужно запускать функцию каждый раз, когда изменяется ширина экрана.
    Попробуйте заключить код функцию:

    window.onresize = function(event) {
        // весь код начиная с var block = ....
    };
    • Не все так просто. Теперь блок фиксируется только когда изменяется ширина. Нужна более хитрая логика. Спасибо за помощь, покумекаю на досуге.

      • Sheff, точно — упустила этот момент. Функцию нужно запускать на два события — скролл и ресайз. Вот такой вариант должен сработать (привожу только измененный кусок кода):

        window.onscroll = window.onresize = function() {
                         var w = window.innerWidth 
                                    || document.documentElement.clientWidth 
                                    || document.body.clientWidth;
                         var newcss = (topPos < window.pageYOffset  && w >= 1230) ? 
                                    'top:20px; position: fixed;' : 'position:static;';
                         block.setAttribute( 'style', newcss );
                }
  • Aaaaa! Волшебство, все работает:) Спасибо большое:)

  • Здравствуйте. Увидел на сайте рекламный блок, который зафиксирован над футером, именно горизонтальный и он работает только на мобильной версии. То есть прокручиваю страницу, а внизу рекламный блок постоянно висит над футером.

    • Андрей, о каком именно рекламном блоке над футером идет речь? На нашем сайте нету рекламных блоков вообще…

      • Я увидел блок на западном ресурсе в мобильной версии. Надеялся, что Вы вкурсе как включить такой блок именно для мобильных устройств.

        • Андрей, если я правильно Вас поняла, то такой блок можно реализовать с помощью обычного CSS c медиа запросом (для проверки ширины экрана).
          Например, настраиваем фиксированный блок в CSS:

          .fixed-adblock {
              position: fixed;
              bottom: 0;
              left: 0;
              width: 100%;
              height: 50px;
              background-color: green;
          }

          и для экранов больше 1024 пикселей просто скрываем его:

          @media screen and (min-width: 1024px){
              .fixed-adblock { display: none; }
          }

          Пример работы на codepen оставила.

  • Александра, большое спасибо за статью. Решил я у себя это дело реализовать. Начал читать в интернете, а там какие-то огромные куски кода, да еще притом не работает…
    Увидел вашу статью, пара минут, все работает. Вот, что значит Мастер. Еще раз спасибо. 🙂
    Код для плагина Functions я взял из вашего ответа на первый комментарий.

    • Василий, спасибо за такие слова! Рада, что удается таки пользу приносить и упрощать жизнь 🙂

  • Вставила код, блок зафиксировался, но вышел из сайдбара и теперь закрывает весь контент. Как можно его зафиксировать в боковой колонке?

    • Добрый день, Арина!
      Не совсем понятно, как именно вышел из сайдбара. Сразу блок становится некорректно или после фиксации начинает перекрывать контент? При какой ширине окна, в левом или правом сайдбаре? Вариант с указанием точной ширины блока пробовали?

      • Здравствуйте, Александра! Рекламный блок у меня изначально размещался в правом сайдбаре. В соответствии с вашими рекомендациями, я его заключила в div, в подвале вставила скрипт и после этого он переместился в левую сторону на контент, правда, в зафиксированном положении. Сейчас я уже исправила ситуацию, прописав параметр margin-left: 680px, но не знаю, насколько это верно. Проверяла на разных устройствах, работает корректно. Большое Вам спасибо за статью! Еще одним плагином уж очень не хотелось нагружать сайт.

        • Арина, отлично, что все заработало!
          Не все плагины нагружают сайт, рекомендую ознакомиться с моей статьей. Плагины нужно тщательно выбирать, чтобы они не увеличивали нагрузку и не влияли на скорость загрузки сайта.

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

    • Алексей, попробуйте в скрипте идентификатор fixed заменить на id блока, в котором стоит реклама.

  • Здравствуйте, у меня в фиксированном сайдбаре кнопка, при ее нажатии сайдбар увеличивается по высоте, т.е. в нем становиться больше контента. Вставила ваш код, но при нажатии моей кнопки в сайдбаре, он удлинняется и все равно налезает на подвал. Как исправить такое? Буду признательна за ответ!

    • Оля, с динамическим контентом много тонкостей. Если использовать предпоследний вариант из статьи, то при определенных условиях все будет работать и блок не будет пересекаться с подвалом. Но если высота блока с текстом большая, то вряд ли выйдет настроить все идеально.
      Оставьте в подписи ссылку на свой сайт — возможно, на конкретном примере смогу помочь.

  • Доброго времени суток. Уже задавал Вам вопрос. Но недавно переделал сайт и теперь произошла проблема с фиксацией блока. После окончания сайтбара, блок почему-то не фиксируется, но при дальнейшем скроле страницы, он появляется и тогда фиксируется.
    Может вы знаете в чем может быть проблема?

    • Юрий, проверьте код, который вставляли на сайт. Возможно есть статическое значение еще, которое влияет на более позднюю фиксацию. Может topPos + какое-то число, или что-то в этом роде.

      • <!--fixed bill-->
        <script type="text/javascript">
        function getTopOffset(e) { 
        	var y = 0;
        	do { y += e.offsetTop; } while (e = e.offsetParent);
        	return y;
        }
        var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
        if ( null != block ) {
        	var topPos = getTopOffset( block );
        
        	window.onscroll = function() {
        		var scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
        
        		    // высота рекламного блока
        		    blockHeight = 600, 
        
        		    // высота подвала
        		    footerHeight =  160, 
        
        		    // считаем позицию, до которой блок будет зафиксирован 
        		    stopPos = scrollHeight - blockHeight - footerHeight; 
        
        		var newcss = (topPos < window.pageYOffset) ? 
        			'top:20px; position: fixed;' : 'position:static;';
        
        		if ( window.pageYOffset > stopPos ) 
        			newcss = 'position:static;';
        
        		block.setAttribute( 'style', newcss );
        	}
        }
        </script>
        <!--end fixed bill-->

        В вашем коде ничего не менял. Вот этот участок, стоит в футере.

  • Попробуйте заменить строчку
    var topPos = getTopOffset( block );
    на:
    var topPos = block.offsetTop;

    Все равно не работает.
    Подскажите, может еще что то можно изменить?

    • Можно попробовать прописать точное значение, в пикселах. Судя по Google Developer Tools http://prntscr.com/aiuiwp, пробуйте значения от 1950 до 2100:

      var topPos = 1980;
      • Спасибо,

        «var topPos = 1980;»

        , — получилось.
        Скинул на ЯнДенги 200 руб.
        Спасибо за помощь.

        • Юрий, отлично, что получилось! Спасибо Вам за поддержку 🙂
          Единственное, не забывайте, что с фиксированным значением будет точно работать, если выше этого блока не появится другой информации (когда ее станет значительно больше или меньше).

  • Здравствуйте. Скрипт отличный но есть маленькая проблемка. Тема уже подымалась но решения не нашлось.
    Суть в следующем: У сайта длинный сайтбар, фиксирующийся блок в самом низу. Если контента на странице мало, то после прокрутки страницы до конца сайтбара происходит скачек вверх до начала нужного нам блока. Получается что посетитель не может посмотреть подвал сайта.
    Проще показать, чем объяснить.. Пример здесь
    Как можно решить эту проблему. Заранее спасибо!

    • Сергей, случай редкий и под него код не адаптирован.

      • Вы знаете, суть проблемы оказалась в том что перед блоком стоял виджет «Одноклассников». Убрал и всё стало нормально.

  • Александра, Вы — чудо, давно путался сделать такое, но..не силен в скриптописании и вообще коде (сам я врач). Есть только один вопрос, если не сложно, данный скрипт как воспринимается гугл адсенсом? Если я код зафигачу рекламный под этот скрипт? Меня не забанят? Если знаете ответ-напишите, пожалуйста, буду признателен.

  • Александра, здравствуйте.

    Попробовал первый (базовый) вариант размещения скользящего блока — работает.
    Есть особенность которую я не смог одолеть.

    Блок должен быть строго по центру области вывода, я сделал это так:

    блок отцентровался, но как только он начинает скользить, то смещается влево (т.е. выравнивается по левому краю области)
    Скачек маленький, но неприемлемый.

    Подскажите, пожалуйста, как отцентровать скользящий блок?

    Спасибо

    • Тимофей, самый простой способ — дописать в css внешний отступ. Нужно в этой строчке:

      'top:20px; position: fixed;'

      добавить свои значения margin для левой и/или правой стороны. Например:

      'top:20px; position: fixed; margin-left: 20px;'

      или

      'top:20px; position: fixed; margin: 0 20px;'

      или

      'top:20px; position: fixed; margin-left: 20px; margin-right: 20px'
  • Добрый день.
    Такой нюанс, при обновлении страницы, она загружается там том же месте скролла, на котором и была перезагружена, как это можно исправить?

    • Игорь, обратиться к разработчикам браузера )))) Это их поведение, не сайта.

  • Александра, здравствуйте. Ставил данный скрипт много раз (благодаря вам)))) Все было ОК. И вот сегодня в очередной раз решил поставить на новый сайт и обнаружил, что в хроме фиксированный блок вместо фиксации просто исчезает, как только блок касается верхней кромки. А остальные браузеры отрабатывают скрипт на ура. Причем на старых сайтах такой проблемы не наблюдаю. Что это может быть, всю голову сломааааал)

    • Федор, у вас в стилях сайта прописано скрытие контента, который выходит за рамки виджета:

      .widget {
          overflow: hidden;
      }

      Возможно, проблема в этом. Просто в стилях уберите этот кусок CSS и все должно заработать.

    • У меня такая же проблема с Хромом, overflow: hidden; менял на none и visible, но не помогло:(

  • у меня добавленнъIй объект добавлется в подвале ….вместо сайд-бара

    подскажите как мне разместить в боковой колонке сайд-бара?

    • Вячеслав, видимо не туда код добавляете. Создайте текстовый виджет и добавьте код в него

  • Александра, спасибо огромное. Второй день пытаюсь зафиксировать меню на своём DLE блоге . Практически проштудировал всю матчасть по jQuery и всю безрезультатно. А тут ваша незатейливая статейка с таким простым методом без всяких этих заморочек с библиотеками jQuery.
    Спасибо огромное. Поставил сразу, обернув меню под хидером в нужные дивы, потом испробовал варианты с двумя блоками — всё работает!!! Правда, не знаю как у всех, у меня фиксированная строка меню, да и оекламные блоки в сайдбаре при прокрутке скрывались за основными картинками на странице. Вылечил добавлением к свойствам параметра z-index.
    Спасибо!

  • Лично реализовал. Делал для себя. Прошу прощения за такие комменты

    Имеем левую колонку (высокую) которая фиксируется при достижении нижней части окна браузера.

    /* Фиксируем левую колонку при скролинге */
    $(window).scroll(function(){ // срабатывает функция когда происходит скролинг
    	var top = $(document).scrollTop();  // количество пикселей проскроленно вниз от верхней части окна браузера
    	var height = $('#aside1').outerHeight(); // общая высота левого блока
    	var heightBody = $(window).height(); // высота окна браузера (то что узреваем перед собой в окошке)
    	var pip = $('#aside1').offset().top; // координаты верхней части блока относительно самого вверха
    	if(top >= (height - heightBody + 120)) $('#aside1').addClass('fixed'); // 120 это высота шапки сайта(у вас своя,если она есть, если нет нужно убрать ' + 120', что тут происходит, мы проверяем количество пикселяндров опущенных вниз, если их больше высоты самого левого блока, мы фиксируем блок к низу экрана, учитываем шапку, если она ёпть присутствует)
    	else $('#aside1').removeClass('fixed'); // ну а здесь отменяем фиксацию если будет все иначе чем выше сказанное.
    }); // закрываем функцию и радуемся )
  • Здравствуйте, поставил ваш код работает отлично за что вам огромное спасибо. Единственное с чем столкнулся, не могу настроить второй сайтбар, плавает только один из виджетов. Не поможете решить проблему?http://povar-life.ru/

    • Александр, для второгой сайдбара нужно сменить название id fixblock на fixblock2 например (в html и js)

  • День добрый.
    А как реализовать смену баннера при прокрутке по достижению определенной высоты?
    Как на сайте _https://vc.ru/p/2017-deathwatch

    • если говорить о доработке кода выше — то проверяйте соответствие переменной window.pageYOffset нужной позиции (например, 2000 пикселов) — если условие сработало, замените html блока фиксированного

      if ( topPos > 2000 ){
           block.innerHTML = "здесь html код нового баннера";
      }
      • А не могли бы Вы сказать куда это вставить?

        if ( topPos > 2000 ){
             block.innerHTML = "здесь html код нового баннера";
        }

        Вставлял после if ( window.pageYOffset > stopPos )
        newcss = 'position:static;';

  • Класс! Спасибо ! Все получилось. Скажите, для WordPress лучше плагин использовать или код добавить. Плагины не сильно сайт загружают?

  • Данный скрипт мне отлично подошел в сайд бар на DLE сайт имеет некоторые приблуды в виде табов диалоговых окон и других jqwery. Ничего не конфликтует все ок. За что вам Александра спасибо! Будем тестировать главно теперь чтобы пользователей это не бесило.
    И имел честь пообщаться по телефону с куратором аккаунта из адсенс. Рассказали о всяких плюшках как поднять показатели Active view и тд и разрешили сделать блок в сайдбаре плавающим, честно сказать руки чесались давно так сделать но боялся бана так как на этот счет много противоречивой инфы на форумах, и как выяснилось не напрасно мне подтвердили что на данную фичу нужно получить разрешение у куратора, так что у кого маленькие аккаунты (без куратора или он еще вам не дозвонился) и те кто такой аппрув не получил, подумайте прежде чем рисковать. Инфа наисвежайшая диалог с гуглом был 18 апреля. Часто игнорю вызовы из других стран и ранее были звонки с похожих номеров, трубку не снимал а вчера ответил и оказалось блин это из гугла))

  • Супер! Спасибо большое, всё работает.
    Но есть один нюанс. При прокрутке содержимое виджета слегка сдвигается влево.
    Так и должно быть, или можно как-то поправить?

    • можно попробовать добавить отступ как в этом примере

      • Здравствуйте! Используя ваш пример, пытаюсь сделать так: два блока справа появляются внизу 2900px фиксируются и пропадают у футера.

        мой код

        <script type="text/javascript">
        function getTopOffset(e) { 
        	var y = 2900;
        	do { y += e.offsetTop; } while (e = e.offsetParent);
        	return y;
        }
        var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
        var block2 = document.getElementById('fixblock2'); /* fixblock2 - значение атрибута id блока */
            if ( null != block || null != block2 ) {
        	var topPos = getTopOffset( block ),
        	scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
        	blockHeight = 400,  /* высота рекламного блока */
        	footerHeight = 500, /* высота футера */
        	/* считаем позицию, до которой блок будет зафиксирован */
        	stopPos = scrollHeight - blockHeight - footerHeight; 
        
        	var topPos2 = getTopOffset( block2 ),
        	scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
        	blockHeight = 500,  /* высота рекламного блока */
        	footerHeight = 600, /* высота футера */
        	/* считаем позицию, до которой блок будет зафиксирован */
        	stopPos = scrollHeight - blockHeight - footerHeight; 
        	
        	window.onscroll = function() {
        	    var newcss = (topPos < window.pageYOffset) ? 
        		'width: 335px; top:90px; position: fixed;z-index:200;' : 'position:static;';
        	    var newcss2 = (topPos2 < window.pageYOffset) ? 
        		'width: 335px; top:320px; position: fixed;z-index:200;' : 'position:static;';
        	    block.setAttribute( 'style', newcss );
        	    block2.setAttribute( 'style', newcss2 );
        	}
        }
        </script>
        
        <script type="text/javascript"> 
         $(document).ready(function () {
         $(".ulightbox")
         .attr('rel', 'gallery')
         .fancybox({
         beforeLoad:function() {
         this.title = $(this.element).attr('caption');
         }
         });
         });
        </script>
        

        но в нём что то не так, я использовал ваш код выше, но там на один блок, подскажите как сделать на 2?

        • в коде рассчитываются позиции двух блоков, но записываются в одну переменную stopPos. Прежде всего, нужно использовать разные переменные, ну и дописать код — stopPos нигде не проверяется как в примере:

          if ( window.pageYOffset > stopPos ) 
          			newcss = 'position:static;';

          Самое простое решение — фиксировать один блок, а в него добавить html ваших двух блоков — они ведь идут друг под другом в одной стороне.

          • скажу честно в js полный ноль. Подумал два дня сделал так:

            Два блока, они исчезают в самом низу, совместил все ваши скрипты, которые выше.

            <!-- <фиксируем блоки> -->
            <script type="text/javascript">
             window.onload = function() {
             function getTopOffset(e) { 
             var y = 2900;
             do { y += e.offsetTop; } while (e = e.offsetParent);
             return y;
             }
             var block = document.getElementById('fixblock'); /* fixblock - значение атрибута id блока */
             var block2 = document.getElementById('fixblock2'); /* fixblock2 - значение атрибута id блока */
             if ( null != block || null != block2 ) {
             var topPos = getTopOffset( block ),
             scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
             blockHeight = 400, /* высота рекламного блока */
             footerHeight = 500, /* высота футера */
             /* считаем позицию, до которой блок будет зафиксирован */
             stopPos = scrollHeight - blockHeight - footerHeight;
             var topPos2 = getTopOffset( block2 ),
             scrollHeight = Math.max( document.documentElement.scrollHeight, document.documentElement.clientHeight),
             blockHeight = 400, /* высота рекламного блока */
             footerHeight = 500, /* высота футера */
             /* считаем позицию, до которой блок будет зафиксирован */
             stopPos = scrollHeight - blockHeight - footerHeight;
             window.onscroll = function() {
             var newcss = (topPos < window.pageYOffset) ? 
             'width: 335px; top:90px; position: fixed;z-index:70;' : 'position:static;';
             if ( window.pageYOffset > stopPos )
             newcss = 'position:static;';
             var newcss2 = (topPos2 < window.pageYOffset) ? 
             'width: 335px; top:320px; position: fixed;z-index:70;' : 'position:static;';
             if ( window.pageYOffset > stopPos )
             newcss2 = 'position:static;'; 
             block.setAttribute( 'style', newcss );
             block2.setAttribute( 'style', newcss2 );
             }
             }
             }
            </script>
            <!-- </фиксируем блоки> -->
            

            Возникла одна проблема, на некоторых страницах для картинок стоит ленивая загрузка. И при скролинге вниз, блоки пропадают раньше того как опустишься в самый низ. Подскажите что можно сделать именно в этом скрипте. Если можно очень подробно в js полный ноль.

          • Как я и советовала ранее — используйте код для одного блока, а в сам div с id="fixblock" добавьте html код ваших двух блоков. Это самое оптимальное решение, т.к. в коде выше вероятны конфликты.
            С ленивой загрузкой — здесь ничего посоветовать не могу, пробуйте вручную подбирать значение для высоты футера, например.

  • А как вы это реализовали:
    Кружку кофе с надписью Как отблагодарить авторов?

  • Спасибо! Действительно рабочий метод.

  • У меня этот блок, находясь в правой колонке, сильно сдвигался вправо при скроллинге, пикселей на 300. Я дописала в коде:

    ‘top:20px; left:820px; position: fixed;’ : ‘position:static;’;

    где 820px — расстояние от левого края до блока. Сейчас все хорошо.

Комментировать

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

wp-puzzle.com logo