Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 28.09.2008, 14:01
Новичок на форуме
Отправить личное сообщение для vasiliyb Посмотреть профиль Найти все сообщения от vasiliyb
 
Регистрация: 28.09.2008
Сообщений: 7

Помогите сделать полноценную замену тэгу <marquee>
На сайте необходима бегущая строка с актуальной информацией,
после месяца поисков имеется самописный скрипт, добрый человек помог. Проблема всех найденых готовых скриптов одна - необходимо задавать жесткие размеры анимированного слоя и отказ от ресайза окна.
Тот скрипт, что написал добродетель - работает и с ресайзом и с % шириной, но 1 неприятный момент, если содержимое (текст бегущей строки) изначально большой, то он "распирает" страницу и как итог - горизонтальная прокрутка. И уж в пику тегу marquee здорово было бы зациклить прокрутку не дожидаясь ухода последнего символа ("строка + разделитель + строка", т.е. "самый полноценный скрипт бегущей строки | Это на сегодняшний день".
Вот имеющийся у меня код:
<script>
// настройка скорости
delay = 30;
step = 2;

is_start = true;
fullwidth = 0;
cpos = 0;
scrollw = 0;

function start_scroll()
{
  var scrolltext = document.getElementById('scrolltext');
  var scroll = document.getElementById('scroll');

  fullwidth = scrolltext.offsetWidth;
  scrolltext.style.left = scroll.offsetWidth;
  scrollw = scroll.offsetWidth;
  scrolltext.style.position = 'relative';
  
  myinterval = setInterval(do_scroll, delay);
}

function do_scroll()
{
  var scroll = document.getElementById('scroll');
  var scrolltext = document.getElementById('scrolltext');
  
  if (is_start)
  {
    cpos = scroll.offsetWidth;
    scrolltext.style.left = cpos;
    is_start = false;
  }
  else
  {
    cpos -= step;
    scrolltext.style.left = cpos;
    if (cpos < -fullwidth) { is_start = true; }
  }
}

function stop_scroll()
{
  clearInterval(myinterval);
}

function continue_scroll()
{
  myinterval = setInterval(do_scroll, delay);
}

function do_resize()
{
  var scroll = document.getElementById('scroll');
  newscrollw = scroll.offsetWidth;
  
  if (cpos >= 0) { absstp = scrollw - cpos; }
  else { absstp = scrollw + Math.abs(cpos); }

  oldprc = absstp / (scrollw + fullwidth);
  newlen = newscrollw + fullwidth;
  newabsstp = newlen * oldprc;

  if (newabsstp <= newscrollw) { cpos = newscrollw - newabsstp; }
  else { cpos = -(newabsstp - newscrollw); }

  scrollw = newscrollw;
}
</script>

<style>
#scroll {width: 100%;
         background-color: f0f0f0;
         white-space: nowrap;
         overflow: hidden;
         position: relative}
#scrolltext {position: absolute}
</style>

<body onload='start_scroll()' onresize='do_resize()'>

  <div style='width:100%'>

      <div id='scroll' onmouseover='stop_scroll()'
      onmouseout='continue_scroll()'>
       <div id='scrolltext'>
        Здесь скроллируемый текст,
        его скорость настраивается,
        в нем есть <a href=''>ссылка</a>,
        при наведении мыши он останавливается
       </div>
      </div>

  </div>

</body>
Ответить с цитированием
  #2 (permalink)  
Старый 28.09.2008, 14:10
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Выкиньте этот скрипт и забудьте о существовании бегущих строк.
Ответить с цитированием
  #3 (permalink)  
Старый 28.09.2008, 14:22
Новичок на форуме
Отправить личное сообщение для vasiliyb Посмотреть профиль Найти все сообщения от vasiliyb
 
Регистрация: 28.09.2008
Сообщений: 7

Вопрос не в эстетике или юзабилити, а в реализации? Вы ни разу не видели дизайнерские работы, где страница прокручивается горизонтально или поп-арт с картинками вырви-глаз? Вопрос в решении задачи, доведении до ума..
Ответить с цитированием
  #4 (permalink)  
Старый 30.09.2008, 04:01
Отправить личное сообщение для Андрей Параничев Посмотреть профиль Найти все сообщения от Андрей Параничев
 
Регистрация: 21.02.2008
Сообщений: 1,250

vasiliyb,
Вот написал вариант решения, правда он не сильно оптимизирован, но тормоза будут заметны только на 3-4 одновременно ползущих строках. Скрипт поддерживает неограниченное число "субтитр" в прокручиваемом элементе, работает при любой ширине, и т.д.

<html>
<head>
	<style>
		#scroll {
			width: 50%;
			position: relative;
			overflow: hidden;
			height: 20px;
			background-color: #f0f0f0;
		}
		
		#scroll .subtitle {
			position: absolute;
			top: 0;
			visibility: hidden;
			white-space: nowrap;
		}
	</style>
	<script>
	function scroll(id, speed, step) {
		// Настройки скорости по умолчанию:
		var speed = speed || 20; // Задержка в мс
		var step  = step  || 1;  // Перемещение в пикселах
		
		// Берем элемент, внутри которого будет скроллится контент.
		var element = document.getElementById(id);
		
		// Берем всех "детей" элемента (они и будут двигаться):
		var children = element.childNodes;
		
		// Переберём всех "детей" в массив, без пробелов (nodeType = 3)
		var childrenArray = [];
		for (var i = 0, l = children.length; i < l; i++) {
			if (children[i].nodeType != 3) {
				// Сдвинем их на начальную позицию:
				children[i].style.left = element.offsetWidth;
				childrenArray.push(children[i]);
			}
		}
		
		// Определяем локальное замыкание для интервала:
		var moveText = function() {
			// Объявим локально только те переменные, с которыми будет работа:
			var steps        = step,
				container    = element,
				scrolling    = childrenArray,
				current      = 0,
				currentWidth = element.offsetWidth;
			
			// Инициализируем первый элемент:
			scrolling[current].style.left = currentWidth;
			scrolling[current].style.visibility = "visible";
			
			return function() {
				// Если изменился размер контейнера:
				if (container.offsetWidth != currentWidth) {
					// Высчитываем разность:
					var delta = parseInt(currentWidth) - parseInt(container.offsetWidth);
					currentWidth = container.offsetWidth;
					// Сдвигаем элемент на это значение:
					scrolling[current].style.left = parseInt(scrolling[current].style.left) - delta;
				}
				
				// Если текущий элемент уже за левой границей:
				if ((Math.abs(scrolling[current].offsetLeft) >=  scrolling[current].offsetWidth) &&
				     scrolling[current].offsetLeft < 0) {
					// Переходим к следующему элементу, а этот прячем: 
					scrolling[current].style.visibility = "hidden";
					
					// Переходим к следующему:
					current++;
					
					// Если элементы кончились - начинаем заново
					if (current >= scrolling.length) current = 0;
					
					// Показываем элемент
					scrolling[current].style.left = parseInt(currentWidth);
					scrolling[current].style.visibility = "visible";
				} else {
					// Просто двигаем элемент, ни о чем не задумываясь.
					scrolling[current].style.left = parseInt(scrolling[current].style.left) - steps;
				}
			}
		}();
		
		var interval = setInterval(moveText, speed);
		
		// Устанавливаем событие на элемент (остановка скроллинга)
		element.onmouseover = function() {
			interval = clearInterval(interval);
		}
		
		element.onmouseout = function() {
			interval = setInterval(moveText, speed);
		}
	}
	</script>
</head>
<body onload="scroll('scroll')">
	<div id="scroll">
		<span class="subtitle">
		Cтрока №1 <a href="#">Cтрока №1</a> Cтрока №1
		</span>
		
		<span class="subtitle">
		Cтрока №2 Cтрока №2 Cтрока №2
		</span>
		
		<span class="subtitle">
		Cтрока №N Cтрока №N Cтрока №N
		</span>
	</div>
</body>
</html>


Не уверен, что будет работать во всех DOCTYPE, но уже голова пухнет, не могу проверить.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите сделать простое меню debugger Элементы интерфейса 1 09.09.2008 23:14