Плавное изменение opacity

 
0
 
JavaScript
ava
MagicDew | 17.10.2011, 11:47
Добрый день, Уважаемые форумчане!

Я начинаю изучать JavaScript и хотелось бы решить следующую задачу: на странице есть несколько участков текста, облаченных в тег <p></p> и ссылка-кнопка, при нажатии на которую у текста свойство "opacity" должно ПЛАВНО уменьшиться с 1 до 0.4. Вот то, что я смог наваять:


<script type="text/javascript">
var txtList = document.getElementsByTagName("p");
function m_setOpacity(value){
for (var i=0;i<txtList.length;i++){
txtList[i].style.opacity = value/10;
}
}
function m_changeOpacity(){
for (var i=0;i<txtList.length;i++){
setTimeout(setOpacity(i), 100);
}
return false;
}
</script>



<div id="content-column">
<p>content column<p><br />
<p>Lorem ipsum dolor sit amet...</p>
<p>Lorem ipsum dolor sit amet...</p>
<p>Lorem ipsum dolor sit amet...</p>
<p>Lorem ipsum dolor sit amet...</p>
<p>Lorem ipsum dolor sit amet...</p>
<p>Lorem ipsum dolor sit amet...</p>

<a href="#" onClick="m_changeOpacity()">Click Me!</a>
</div>


Вот суть проблемы:
я не понимаю как работает функция setTimeout() и как получить и проверить текущее значение свойства "opacity"
Kommentare (16)
ava
mcTep | 17.10.2011, 14:21 #
setTimeout(foo, duration) говорит браузеру выполнять функцию foo c интервалом в duration миллисекунд. В foo вам надо передать именно функцию, которая будет выполняться с этим интервалом. Сейчас у вас `setOpacity(i)` это вызов функции, в результате которой возвращается какое-то значение, которое вряд ли будет функцией, судя по вашему примеру.
Т.е. в вашем примере просто произойдет несколько вызовов фунции setOpacity и, увы, больше ничего.

Сделать стоит примерно следующее:


function downgradeOpacity(elem) {
var opa = elem.style.opacity;
if (opa > 0.4) {
elem.style.opacity = opa - 0.1;
} else {
clearInterval(elem.animationInterval);
}
}

var pars = document.getElementsByTagName('p');
for (var i = 0, c = pars.length; i < c; i++) {
var par = pars[i];
par.animationInterval = setInterval(function downgradeOpacityForPar() {
downgradeOpacity(par);
}, 100);
}



Здесь мы заводим обработчики для каждого параграфа, и создаем ссылку на них в par.animationInterval для каждого элемента. При достижении значения 0.4 и меньше, мы этот обработчик сбрасываем через clearInteval.
ava
MagicDew | 17.10.2011, 15:51 #
Поясните пожалуйста вот этот код:


var pars = document.getElementsByTagName('p');
for (var i = 0, c = pars.length; i < c; i++) {
var par = pars[i];
par.animationInterval = setInterval(function downgradeOpacityForPar() {
downgradeOpacity(par);
}, 100);
}


и как вызывать и работать с этим функциями?
ava
mcTep | 18.10.2011, 08:59 #
Здесь мы берем нужные параграфы, потом проходясь по циклу каждому параграфу в свойство animationInterval добавляем интервал вызова функции downgradeOpacityForPar, в которой с интервалом 100 миллисекунд понижаем прозрачность конкретного параграфа.
Этот участок кода можно обрамить в функцию и вызвать ее при, например при клике или когда вам угодно.


function startAnimation() {
var pars = document.getElementsByTagName('p');
for (var i = 0, c = pars.length; i < c; i++) {
var par = pars[i];
par.animationInterval = setInterval(function downgradeOpacityForPar() {
downgradeOpacity(par);
}, 100);
}
}



<a href="javascript:void(0)" onclick="startAnimation()">Click Me!</a>
ava
&#036;дмитрий | 18.10.2011, 14:20 #
Небольшая оптимизация

setInterval(function downgradeOpacityForPar() {
downgradeOpacity(par);
}, 100);

Можно заменить на

setInterval("downgradeOpacity(par)", 100);
ava
mcTep | 18.10.2011, 14:40 #
Данный подход подобен использованию eval(), где текст выполняется как код. Данный подход не рекомендуется.

ava
&#036;дмитрий | 18.10.2011, 14:53 #
Не вижу смысла в функции которая не делает ничего, кроме вызова другой функции smile
ava
mcTep | 18.10.2011, 15:19 #
Ваш пример делает тоже самое :)

später ergänzt:
К томуже эта функция вызывает другую в нужном нам окружении. Мы могли бы конечно сделать что-то вроде


var pars = document.getElementsByTagName('p');
for (var i = 0, c = pars.length; i < c; i++) {
var par = pars[i];
par.foo = downgradeOpacity;
par.animationInterval = setInterval(par.foo, 100);
}


и в downgradeOpacity обращаться к параграфу через this.
ava
MagicDew | 28.10.2011, 10:51 #
Уважаемые mcTep и $дмитрий, спасибо, что отозвались, но, увы, приведенный вами код у меня не работает. Вот то, что я написал по вашим советам:


<script type="text/javascript">
function downgradeOpacity(elem) {
var opa = elem.style.opacity;
if (opa > 0.4) {
elem.style.opacity = opa - 0.1;
}
else {
clearInterval(elem.animationInterval);
}
}
function startAnimation() {
var pars = document.getElementsByTagName('p');
for (var i = 0, c = pars.length; i < c; i++) {
var par = pars[i];
par.animationInterval = setInterval(function downgradeOpacityForPar() {
downgradeOpacity(par);
}, 100);
// par.animationInterval = setInterval("downgradeOpacity(par)", 100); опробовал и такой вариант
}
}
</script>



<a href="javascript:void(0)" onclick="startAnimation()">Click Me!</a>


ava
Absinthe | 28.10.2011, 12:14 #
Цитата


Данный подход подобен использованию eval(), где текст выполняется как код.

Не правда.

Цитата


Данный подход не рекомендуется.

Не правда.
ava
MagicDew | 02.11.2011, 15:39 #
Проблема осталась не решенной, помогите, плиз
ava
magelan | 02.11.2011, 17:31 #
MagicDew,
1я проблема - опасити изначально не определен, я с этим поборолся тупо, лень смотреть как по умному.
2я проблема - лоическая downgradeOpacityForPar вычисляется только один раз, в связи с чем только последний параграф будет высветляться.


<script type="text/javascript">
function downgradeOpacity( elem )
{
if ( elem.style.opacity > 0.4 )
elem.style.opacity -= 0.1;
else
clearInterval( elem.animationInterval );
}
function startAnimation()
{
var pars = document.getElementsByTagName( 'p' );

for( var i = 0; i < pars.length; i++ )
{
var par = pars[i];
par.style.opacity = 1;
runElOpacity( par )
}
}
var runElOpacity = function( el )
{
el.animationInterval = setInterval( function downgradeOpacityForPar() { downgradeOpacity( el ); }, 100 );
}
</script>

ava
Absinthe | 02.11.2011, 17:43 #
Цитата


Проблема осталась не решенной, помогите, плиз

Я бы просто воспользовался .animate() в jQuery.
Без jQuery таким не занимался, т.к. не вижу смысла.
ava
ksnk | 02.11.2011, 20:16 #

<script type="text/javascript">
function opacity(e,o){
e.style.filter = "alpha(opacity=" + Math.round(o*100) + ")";
e.style.opacity = o;
}

function fade(e,o_from,o_to,msec) {
if (!msec) msec=2000;
var
delta=50,
disp = (o_to-o_from)/(msec/delta),
cnt = Math.round((o_to-o_from)/disp);
x = function (){
if (--cnt){
o_from+=disp;
opacity(e,o_from);
setTimeout(x,delta);
} else {
opacity(e,o_to);
}
};
setTimeout(x,delta);
}
</script>

<button onclick="fade(document.getElementById('test'),0,1);">fadein</button>
<button onclick="fade(document.getElementById('test'),1,0,4000);">fadeout</button>
<div id="test" style="background:red; height:100px;"></div>
ava
SelenIT | 03.11.2011, 01:16 #
Цитата (Absinthe @ 28.10.2011, 12:14 findReferencedText)
Цитата

Данный подход не рекомендуется.
  Не правда.

Absinthe, в пользу слов mcTepа высказываются Мозилла и Опера, да и это вроде как давно общепринятое мнение в сообществе. Я, как обычно, проспал какую-то революцию? Буду дико благодарен за ссылки!
ava
Absinthe | 03.11.2011, 12:45 #
SelenIT, прошу прошения, я думал, что это было высказывания про анонимные функции, не дочитал smile
ava
mcTep | 03.11.2011, 18:13 #
Цитата (magelan @ 2.11.2011, 17:31 findReferencedText)
MagicDew,

1я проблема - опасити изначально не определен, я с этим поборолся тупо, лень смотреть как по умному.

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


Ох, да.. Конкретно затупил.. :-( Простите, пожалуйста.


Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
advanced
Absenden