Помогите сделать полноценную замену тэгу <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>
|
Выкиньте этот скрипт и забудьте о существовании бегущих строк.
|
Вопрос не в эстетике или юзабилити, а в реализации? Вы ни разу не видели дизайнерские работы, где страница прокручивается горизонтально или поп-арт с картинками вырви-глаз? Вопрос в решении задачи, доведении до ума..
|
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, но уже голова пухнет, не могу проверить. |
| Часовой пояс GMT +3, время: 09:17. |