2012-07-04 3 views
0

Это сводит меня с ума ... У меня есть функция javascript, которая переключает видимость элемента, который я передаю, используя методы HTML5. Я хочу поменять изображение, отображаемое тегом img внутри инициирующего элемента привязки, чтобы оно соответствовало состоянию расширенного или свернутого элемента.JQuery toggle() function: switch related img src

Я использую следующий код:

$('a.expand-collapse').click(function() { 
    var targetID = $(this).attr('data-expcoltarget'); 
    var target = $('div#' + targetID); 
    debugger; 

    target.toggle('blind'); 

    if (target.is(':visible')) imgSrc = contentRoot + 'images/collapse.gif'; 
    else imgSrc = contentRoot + 'images/expand.gif'; 

    $(this).find('img').first().attr('src', imgSrc); 
}); 

К сожалению, target.is (': видимый') >> всегда < < возвращает истину, независимо от состояния видимости элемента мишени.

Что мне не хватает?

Edit:

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

Что такое «data-expcoltarget», это метод HTML5 для назначения произвольных значений элементам. Все, что содержит данные суффикса, игнорируется синтаксическим анализатором.

В этом примере я использую технику для передачи того, что составляет аргумент в функцию javascript. Это работает, потому что $ (this) указывает на элемент, вызвавший событие, поэтому я могу проверить его атрибуты для поиска аргумента.

+0

plz опубликовать разметку HTML. – undefined

+0

Что такое 'attr ('data-expcoltarget')'? – Dips

ответ

0

Проблема заключается в том, что вы вызываете .toggle() с параметром 'blind', что означает, что он функционирует как метод анимации. Анимация происходит асинхронно и не завершается до тех пор, пока остальная часть обработчика кликов не завершится.

Если вы вызываете .toggle() без параметров, то переключатель будет немедленным (без анимации), так что остальная часть вашего кода будет работать.

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

$('a.expand-collapse').click(function() { 
    var $this = $(this), 
     targetID = $this.attr('data-expcoltarget'), 
     target = $('#' + targetID); 

    target.toggle('blind', function() { 
     if (target.is(':visible')) 
      imgSrc = contentRoot + 'images/collapse.gif'; 
     else 
      imgSrc = contentRoot + 'images/expand.gif'; 

     $this.find('img').first().attr('src', imgSrc); 
    }); 
}); 

(Обратите внимание, что внутри функций обратного вызова this является элемент быть переключена, так что вам нужно, чтобы сохранить ссылку на $(this) снаружи, так что он будет ссылаться на якорь)

я бы, вероятно, «упростить» это далее:.

$('a.expand-collapse').click(function() { 
    var $this = $(this), 
     targetID = $this.attr('data-expcoltarget'), 
     target = $('#' + targetID); 

    target.toggle('blind', function() { 
     $this.find('img').first().attr('src', 
      contentRoot + (target.is(':visible') ? 'images/collapse.gif' 
               : 'images/expand.gif')); 
    }); 
}); 
+0

Спасибо, n^6, не только за решение и упрощение, но и за то, что нашли время, чтобы объяснить, почему возникла проблема. Я не понимал, что toggle() был асинхронным. –

+0

Добро пожаловать. Легко упускать из вида асинхронную вещь, особенно если версия no. Param. .toggle() 'не является async. На всякий случай, когда вы не знали: анимации _all_ jQuery являются асинхронными - они должны быть (с каждым «фреймом» анимации, выполняемой с помощью 'setTimeout()' или 'setInterval()'), потому что браузеры не обновляют страницу в то время как JS работает ... – nnnnnn

+0

Это хорошее напоминание RTFM ... даже когда у вас уже есть :) –