Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Помогите найти скрипт затухания ссылок


Автор: Morg 31.3.2007, 05:33
Здраствуйте! Возникла потребность в плавном затухании/"зажигании" фона ссылок при маусовере, при этом в зависимости от класса css (селектора) в котором находится ссылка параметры затухания (цвет, скорость...) должны быть разные, и желательная реализация посредством прозрачности (ссылки будут находится на текстурном фоне). Ну и кроссбраузерность конечно требуецо...

Полноценного скрипта, удовлетворяющего потребности я так и не нашел. Кое что нашел http://forum.vingrad.ru/index.php?act=Print&client=printer&f=10&t=60704, но там проблема с совместимостью + нет зависимости от класса. Есть и такой вариант:

Код

<html>
<head>
<title>WOweb.ru - Scripts - JavaScript - Fading Link</title>
<META http-equiv="Content-Type" content="text/html; charset=windows-1251">
<META NAME="description" CONTENT="Коллекции CGI, PHP, JavaScript скриптов, Java апплеты, огромное количество документации по разным языкам программирования, анимированные гифы, фоны, полезные программы, форум, ссылки по теме.">
<META NAME="keywords" CONTENT="perl scripts, perl, cgi scripts, cgi, перл, java, java scripts, веб-программирование, web-programming,  html,  каталог ссылок, документация по веб-программированию, cgi скрипты, java скрипты, игры, java апплеты,  апплеты, гифы, скрипты, скрипт, книги по веб-программированию, форум по perl, CGI, Perl, script, HTML">

 <Style>
   A:Link{ Color: white; Text-decoration: underline}
   A:Visited{ Color: white; Text-decoration: underline}
   A:Hover{ Color: white; Text-decoration: none}
 td, body {font-family: verdana, arial, helvetica; font-size:11px;}  
 </Style>

<!-- HEAD START HERE -->


<script LANGUAGE="JavaScript"><!--

document.onmouseover = domouseover;
document.onmouseout = domouseout;

function domouseover() {
  if(document.all){
  srcElement = window.event.srcElement;
  if (srcElement.className.indexOf("fade") > -1) {
        var linkName = srcElement.name;
      fadein(linkName);
      }
      }
}

function domouseout() {
  if (document.all){
  srcElement = window.event.srcElement;
  if (srcElement.className.indexOf("fade") > -1) {
        var linkName = srcElement.name;
      fadeout(linkName);
      }
      }
}

function makearray(n) {
    this.length = n;
    for(var i = 1; i <= n; i++)
        this[i] = 0;
    return this;
}

hexa = new makearray(16);
for(var i = 0; i < 10; i++)
    hexa[i] = i;
hexa[10]="a"; hexa[11]="b"; hexa[12]="c";
hexa[13]="d"; hexa[14]="e"; hexa[15]="f";

function hex(i) {
    if (i < 0)
        return "00";
    else if (i > 255)
        return "ff";
    else
       return "" + hexa[Math.floor(i/16)] + hexa[i%16];}

function setbgColor(r, g, b, element) {
      var hr = hex(r); var hg = hex(g); var hb = hex(b);
      element.style.color = "#"+hr+hg+hb;
}

function fade(sr, sg, sb, er, eg, eb, step, direction, element){
    for(var i = 0; i <= step; i++) {
setTimeout("setbgColor(Math.floor(" +sr+ " *(( " +step+ " - " +i+ " )/ " +step+ " ) + " +er+ " * (" +i+ "/" +step+ ")),Math.floor(" +sg+ " * (( " +step+ " - " +i+ " )/ " +step+ " ) + " +eg+ " * (" +i+ "/" +step+ ")),Math.floor(" +sb+ " * ((" +step+ "-" +i+ ")/" +step+ ") + " +eb+ " * (" +i+ "/" +step+ ")),"+element+");",i*step);
    }
}
function fadeout(element) {
    fade(255,150,0, 255,255,255, 30, 1, element);
}
function fadein(element) {
    fade(255,255,255, 255,150,0, 23, 1, element);
}
//--></SCRIPT>


<!-- HEAD END HERE -->




</head>
<body bgcolor="#EDEDED" text="#000000" link="#FFFFFF" topmargin="0" leftmargin="0">
<center>

<!-- BODY START HERE -->


<TABLE ALIGN=CENTER WIDTH="8%" BORDER="0" BGCOLOR="#400040">
<TR>
 <TD><center><a href="http://www.woweb.ru" name="fading_link_1" class="fade">WOweb.ru</a>  </TD>
</TR>
</TABLE>



<!-- BODY END HERE -->

</body>
</html>


Но в мозилле он не работает, да и ослик ругается на "активное содержимое". И опять же нет зависимости от класса. Пожалуйста, помогите, думаю такой скриптец будет интересен многим! Я JS знаю на уровне "о, вот это js, а вот тут можно изменить чекбокс на радио"   smile Спасибо за внимание!

Автор: butionok 3.4.2007, 01:16
Morg,  привет!

По той ссылке что ты дал можно найти хороший кроссброузерный вариант. Надо только немного доработать. Вот что я сделал на скорую руку:

Код

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<title>Переливы фона</title>
<style type="text/css">
#background {
  
  float:left;
  border: 1px solid navy;
  padding: 10px;
  _filter: alpha(opacity=0); /* IE */
  -moz-opacity: 0; /* mozilla */
  -khtml-opacity: 0; /* KHTML Engine(Konquerror) */
  opacity: 0; /* За*бали различия браузров? Используй CSS3! */
                    }
</style>
<script type="text/javascript">
<!--
var timer;

function showElement(show, obj, time, resolution) {
  resolution=(resolution>0? resolution: 100); //пауза между фреймами, не ставь мало, у тебя не такая крутая машина ;-)
  var step=(show? 1: -1)*(1/(time>0? time: 5000))*resolution; //шаг в процентах от заданного времени
  
  var opacity=(typeof(obj.style.KhtmlOpacity)!="undefined")? parseFloat(obj.style.KhtmlOpacity): //konquerror и его семейство
              (typeof(obj.style.MozOpacity)!="undefined")? parseFloat(obj.style.MozOpacity): //мозилла и прочие Gecko. кстати, долбанная мозилла не покажет какое сейчас значение, если его не меняли...
              (typeof(obj.filters)!="undefined")? obj.filters.Alpha.opacity/100: //ИЕ вариант
              (typeof(obj.style.opacity)!="undefined")? parseFloat(obj.style.opacity): //не стоит доверять, может не undefined для понту, а всё равно не поддерживаеться CSS3
              null; //нет прозрачности как таковой
              
  if(opacity==null) return;
  opacity=isNaN(opacity)? (show? 0: 1) : opacity; //тест на вшивость
  //и так здесь мозилла(возможно konquerror) обложалась, мы не можем узнать значение opacity если оно не менялось
  //потому в первый раз возьмём как будто мы находимся на границе, либо 0, либо 1

  window.clearInterval(timer);//убьём интервал если уже запущен, т.о. устраним глюк с мерцанием
  timer=window.setInterval(function() {
     if((opacity+=step)>=1||opacity<=0)
    {
    window.clearInterval(timer);
    opacity=(step<0?0:1);
    if(obj.filters) obj.filters.Alpha.opacity=opacity*100;
    else {obj.style.KhtmlOpacity=obj.style.MozOpacity=obj.style.opacity=opacity;}
    }
     else
    {
    if(obj.filters) obj.filters.Alpha.opacity=Math.round(opacity*100);
    else obj.style.KhtmlOpacity=obj.style.MozOpacity=obj.style.opacity=opacity;
    }
  }, resolution);
}
//-->
</script>
</head>

<body>
<div id="background" style="position:absolute;left:0px;top:0px;width:110px;height:80px">
<img src="aac00004.jpg">
</div>
<div id="link" style="position:absolute;left:0px;top:0px;width:110px;height:80px">
<a href="http://forum.vingrad.ru/topic-143795/kw-css-%D0%B7%D0%B0%D1%82%D1%83%D1%85%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BB%D0%B0%D0%B2%D0%BD%D0%BE-%D0%BA%D0%BB%D0%B0%D1%81%D1%81.html" 
onmouseover="showElement(true, document.getElementById('background'))" onmouseout="showElement(false, document.getElementById('background'))">YOUR TOPIC</a></div>

</body>
</html>


Работает на ура в IE, FF, Мозилле, Нетскэйпе и Опере, правда последняя тявкает по поводу CSS, ну можно забить на неё, всё-равно её практически никто не юзает из-за тормознутости.

Автор: Morg 3.4.2007, 15:04
butionok, как то неизящно ;) каждая ссылка должна быть с абсолютным позиционированием (или я туговато соображаю)... Хоть конечно и работоспособней всех вариантов которые я видел smile но напрягает необходимость каждой сылке прописывать онмаусовер, да и мне надо то - плавное всплытие бэкграунда ссылки, а не дива при наведении...

Если не сложно - доработай пожалуйста!


ЗЫ Оперу никто не юзает? Из за тормознутости? Я юзаю. И все мои друзья. И куча знакомых. Из за ее скорости   smile 

Автор: butionok 3.4.2007, 16:45
Morg, 

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

Цитата

да и мне надо то - плавное всплытие бэкграунда ссылки


вроде то, что я тебе написал как раз это и делает.

У тебя очень много ссылок? Ну допустим. Тогда чтобы не прописывать onmouseover каждый раз делаем так:
Ставим в атрибут "flink" у каждой ссылки id её фона, при загрузке тела инициализируем линки.

Код

<style type="text/css">
.background {
   float:left;
  border: 1px solid navy;
  _filter: alpha(opacity=0); /* IE */
  -moz-opacity: 0; /* mozilla */
  -khtml-opacity: 0; /* KHTML Engine(Konquerror) */
  opacity: 0; /* За*бали различия браузров? Используй CSS3! */
                    }
</style>


Код

<body onload='initlinks("A")'>
<div class="background" id="link1" style="position:absolute;left:0px;top:0px;width:110px;height:80px">
           <img src="picture.jpg">
</div>
<div style="position:absolute;left:0px;top:0px;width:110px;height:80px">
          <a flink="link1">LINK</a>
</div>


Код

function initlinks() {// инициализация линков
    var  tags=document.body.getElementsByTagName(arguments[0]); // берём все линки
        for(var i=0; i<tags.length; i++)
            if(tags[i].getAttribute("flink")) // ищем линки с атрибутом "flink"
               superlinks(tags[i],document.getElementById(tags[i].getAttribute("flink"))) }// для каждой вызываем функцию

function superlinks(obj,bgobj)
{
    if((!obj||obj.nodeType!=1) || (!bgobj||bgobj.nodeType!=1) ) throw "Illigal argument exception";

    obj.onmouseout=function () // для каждой ссылки ставим обработчики событий
          {
           showElement(false, bgobj); // прячем фон
          }
    obj.onmouseover=function()
           {
            showElement(true, bgobj); //показываем фон
           }
}


Цитата

ЗЫ Оперу никто не юзает? Из за тормознутости? Я юзаю. И все мои друзья.


Значит плохо юзаете. По тормознутости она может легко сравнится Netscape 8.1

Автор: Sardar 4.4.2007, 20:03
Цитата(Morg @  3.4.2007,  14:04 Найти цитируемый пост)
каждая ссылка должна быть с абсолютным позиционированием

Нет, это необязательно. 

Цитата(Morg @  3.4.2007,  14:04 Найти цитируемый пост)
но напрягает необходимость каждой сылке прописывать онмаусовер

Вешать обработчиков по любому потребуеться, хоть в вёрстке, хоть пробегая по document.links. Это элементарно, функция самого фейда общая. Где сложности?

Цитата(butionok @  3.4.2007,  15:45 Найти цитируемый пост)
Значит плохо юзаете. По тормознутости она может легко сравнится Netscape 8.1

На этом и остановимся, для религиозных войн есть свой раздел  smile 

Автор: Morg 9.4.2007, 23:47
Sardar, хотелось бы упростить - применять буду в движке сию штуку, а тамочки будет тяжеловато каждой ссылке автоматом еще и дописывать и слои с обработчиками - по крайней мере, не меняя код самого движка - хотел обойтись изменениями шаблонов, а для этого нужно чтобы наши ссылочки, находясь просто друг за другом (ну или друг за br'ом   smile ) форматировались сами по себе стилями и скриптами. Просто ссылки (без ничего), находящиеся в определнном диве должны обладать своими параметрами (отступы, шрифт, etc) и плавно менять фон smile если нельзя просто уменьшать плавно прозрачность фона ссылки - может просто можно пробегать от одного цвета фона до другого?

ЗЫ простите, если туплю - спать очень хочется :( 
ЗЗЫ холиварам - нет smile 

Автор: butionok 10.4.2007, 00:27
Morg, 

Если сумеешь добиться желаемого эффекта другим способом напиши. Интересно.

Автор: Sardar 10.4.2007, 16:51
Morg, стилей здающих динамику (окромя не поддерживамого никем blink) нет, потому скриптами. Для этого скрипт должен получать события, по которым выполняем аимацию. Для этого тебе нужно уметь выделять ссылки, способов масса, пример:

Код
function applyDynamicFade(objs) {
   for(var i=0; i<objs.length; i++) {
      var o = objs[i];
      objs[i].onmouseover = function() { showElement(true, o); }
      objs[i].onmouseout = function() { showElement(false, o); }
   }
}


//положи это в конец страницы или сразу после блока ссылками, или повесь на window.onload
var d = document.getElementById("mylinks"); //все ссылки положим в один слой с id="mylinks"
var lnks = d.getElementsByTagName("a"); //все ссылки внутри слоя
applyDynamicFade(lnks);



M
Sardar
butionok, спасибо, поправил. Читаю по диагонали, код пишу на коленке, бывает :)

Автор: butionok 10.4.2007, 21:28
Sardar, 

По моему у тебя ошибочка, я бы так сделал

Код

for(var i=0; i<objs.length; i++)


А потом то, что ты написал будет вызывать изменения самих ссылок, а не фона. А Morg, хочет чтобы именно фон затухал/появлялся. Мало того 
Цитата
и желательная реализация посредством прозрачности (ссылки будут находится на текстурном фоне).

Автор: Morg 10.4.2007, 21:42
butionok, да, ты меня правильно понял smile хотя не обязательно - это не критично, я думаю. Данный эффект я хочу приложить к ссылкам верхней навигации и справа http://www.yomoto.ru/test2/. Постепенное появление не нужно, только затухание smile Кстати такой скрипт никому не помешает я думаю - и красиво, и цивильно.

Автор: butionok 10.4.2007, 22:44
Morg, 

Затухание можно и так сделать:

Код

<html>
    <head>
       <title>rgb fade</title>
       <style type="text/css">
       #flink{background-color : rgb(255, 0, 0)};
       </style>
       <script type="text/javascript">
           var green=0,blue=0;
           function fadebgoflink()
                 {
                 window.setInterval('document.getElementById("flink").style.backgroundColor="rgb(255,"+(green++)+","+(blue++)+")"',5);
                 }
        </script>
     </head>
<body style="background:gray" onload="fadebgoflink()">
    <div>
       <a id="flink">link with fading background</a>
    </div>
</body>
</html>


Только с текстурами проблема. Как только ты задаёшь цвет фона он становится непрозрачным. Следовательно сделать так чтобы текстура плавно появлялась нельзя.

Автор: Morg 11.4.2007, 22:00
butionok, если сделать достаточно быстрый процесс затухания-перехода фона то если текстура неяркая (как у меня), думаю заметно не будет.

 smile а можно посредством css сделать градиентный фон? smile

Автор: butionok 12.4.2007, 12:04
Morg, 

Цитата

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



Возможно, но тогда об универсальности и пользе для всех уже не придётся говорить.

Цитата

а можно посредством css сделать градиентный фон?


По-моему только в IE. Вот почитай здесь http://forum.vingrad.ru/topic-47033.html

Автор: Morg 12.4.2007, 23:27
butionok, мда, это точно. Но польза все равно останется - но только придется всем вручную вбивать нужное :(


И что-то я запутался, какой наиболее рабочий тут скрипт smile

Автор: butionok 13.4.2007, 19:22
Morg, 

Я думаю что самое лучшее решение это от 3.4.2007. Я его немного доработал:
Код

<style type="text/css">
.outer {
    position:absolute;
    border: 1px solid navy;
    _filter: alpha(opacity=0); /* IE */
    -moz-opacity: 0; /* mozilla */
    -khtml-opacity: 0; /* KHTML Engine(Konquerror) */
    opacity: 0; /* За*бали различия браузров? Используй CSS3! */
    }

</style>


Код

function initlinks() // инициализация линков
    {
    var  tags=document.body.getElementsByTagName(arguments[0]); // берём все линки
    var num=tags.length;
    for(var i=0; i<num; i++)
        if(tags[i].getAttribute("flink")) // ищем линки с атрибутом "flink"
        {
        var outerDiv=document.createElement("DIV"); //создаём слой
        var CloneNodeA=tags[i].cloneNode(true);// клонируем элемент

        outerDiv.className="outer";
        CloneNodeA.style.position="absolute";
        CloneNodeA.style.top=tags[i].offsetTop;//у клона та же позиция что и у линка
        CloneNodeA.style.left=tags[i].offsetLeft;
            
        outerDiv.style.background=tags[i].getAttribute("flink");//берём фон из аттрибута 
        outerDiv.style.top=tags[i].offsetTop;//у слоя те же параметры что и у линка
        outerDiv.style.left=tags[i].offsetLeft;
        outerDiv.style.height=tags[i].offsetHeight;
        outerDiv.style.width=tags[i].offsetWidth;
        
        tags[i].parentNode.appendChild(outerDiv);//прикрепляем слой
        tags[i].parentNode.appendChild(CloneNodeA);//прикрепляем клон
            
        superlinks(CloneNodeA,outerDiv);// для каждого клона вызываем функцию прикрепителя событий
        //tags[i].parentNode.removeChild(tags[i]); //а вот это не работает! Не знаю почему.
        tags[i].style.visibility='hidden';//Хотелось бы поудалять оригинальные линки. По этому просто скрываем.
        }
    }


ещё вместо timer в функции showElement надо поставить obj.timer, ведь объектов-то несколько!

Использование простое: никаких слоев самому создавать не надо. В аттрибуте "flink" задаёшь параметры фона, как если бы ты это делал в стилях.

Код

<body onload='initlinks("A")'>
<a flink="url('SOUND.GIF')">LINK1</a><a flink="url('SOUND.GIF')">LINK2</a>

<div id="test" style='position:absolute;left:100px;top:100px;border:1px green solid'>
Let's check if links stay at the same place
<a flink="red">LINK3</a>
<a flink="blue">LINK4</a>
<a flink="yellow">LINK5</a>
<a flink="gray">LINK6</a>
</div>
</body>
 

Кстати всё-равно пришлось делать фон абсолютно позиционированным. По другому у меня не получилось. Я прикрепил файл с работающим примером. 
Осталось только не решённым почему 
Код
tags[i].parentNode.removeChild(tags[i]); 
 не работает.

Автор: Morg 16.4.2007, 00:01
butionok, ух ты ептыть! Отлично! Супер! Спасибо smile буду пытацо вставить это в дизигн...

Автор: Morg 16.4.2007, 01:31
После небольшого "теста", выяснилось:

а. ссылки загораются плавно, а нужно чтобы сразу "вспыхивали", только затухали плавно.
б. абсолютное позиционирование суксь - дизайн равняется по центру, в итоге получается полное г... на разных разрешениях

Пункт б. решил добавлением в свойства ссылки _position:relative;_left:0px; однако при ресайзе окна в ИЕ ссылки остаются на том же месте - и глючат. Тестирование в мозиле не производил.

ПыСы осталось совсем чутьчуть для универсализации скрипта smile

Добавлено через 4 минуты и 18 секунд
ПыПыСы в мозиле полный 3,14здец. Затухание вообще не работает, и позиционирование все к чертям... http://yomoto.ru/test2/

Добавлено через 10 минут и 16 секунд
и еще - если для верхнего меню работает flink, то для правого - нет. 

Автор: butionok 16.4.2007, 12:53
Morg, 

a. можно легко доработать.

А вот с остальным плохо. Все твои проблемы из-за того что мой скрипт работает нормально только с абсолютно позиционированными слоями. Попытаюсь доделать.

Автор: Morg 18.4.2007, 05:10
butionok, надеюсь и жду!  smile 

Автор: SelenIT 18.4.2007, 07:16
Morg, мне кажется, для Вашего конкретного и довольно специфического случая не нужно гнаться за большой универсальностью. Гляньте http://silverflame.at.tut.by/morq/index.html, например - может, Вам такого и хватит? ;)

Автор: Wolf1994 18.4.2007, 08:45
http://www.wolf-ware.ru/ - "логотип". Время вспыхивания и затухания определяется просто - одной переменной шага... Не помню, как сделано  smile ... Сейчас приведу код:
Код

var db_color2=new Array(0,0,0);//начальный цвет
var db_adj_go=new Array(0,0,0);//изменяющийся цвет - временный, промежуточный массив
var db_adj_to=new Array(54,255,47);//подсвеченный вариант - цвет
var db_count=0;//счётчик шагов
var db_iter=10;//количество шагов - чем меньше, тем быстрее

function draw_back_hi(t)
{
 if (typeof(db_ti)!="undefined") clearTimeout(db_ti);
 if((t>0&&db_count<db_iter)||(t<0&&db_count>0))
 {
  var beg,res,step;
  res=t?db_adj_to[i]:db_color2[i];
  beg=t?db_color2[i]:db_adj_to[i];
  step=Math.floor((res-beg)/db_iter);
  db_adj_go[i]=beg+step*db_count;
  document.getElementById('test').style.color=rgb(db_adj_go);
  db_count+=t;
  db_ti=setTimeout("draw_back_hi("+t+")",100);
 }
}
function rgb(t)
{
 return "rgb("+t[0]+","+t[1]+","+t[2]+")";
}

document.getElementById('test').onmouseover=function(){draw_back_hi(1)};
document.getElementById('test')..onmouseout=function(){draw_back_hi(-1)};


Код

<a href="#" id="test">Test</a>


Скрипт рипнутый, не тистировался. Отдаю на опыты smile Скорость можно изменить ещё в setTimeout - вместо 100 - 50... 25...

Автор: Morg 23.4.2007, 21:37
SelenIT, ну я же не только ради себя прошу, все таки такая штука много кому пригодится, ее можно юзать практически в любой навигации хоть на бизнес сайте хоть на игропортале (фу, слово "портал") smile А то получается я так нагло использую "бесплатную рабочую силу" для собственных целей - стыдобственно сиё как-то  smile 

Классный вариант, вроде все отлично! SelenIT  smile 

Автор: Morg 23.4.2007, 22:31
примастрячил вариант selenIT, отлично вообще! еще бы для http://yomoto.ru/test2/ такую штуку сделать smile

Автор: Morg 24.4.2007, 18:33
В обещм спасибо, не буду больше беспокоить - главное что нужно было мне, уже сделано =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)