Поведение переключателя jQuery не соответствует ожиданиям

У меня есть переключатель jQuery, с которым я борюсь. Я могу заставить его переключать видимость нескольких div одновременно, но как только я реализую функцию next(), единственное, что переключается, — это плюс/минус часть скрипта, а не видимость div. Что-нибудь особенное в этом коде?

Это работает, но переключает все div, а не только закрывающий:

jQuery(function(){
 jQuery(".toggleText").click(function(){
  jQuery(".hiddenText").slideToggle("fast");
        jQuery(this).html(function(i,html) {
            if (html.indexOf('More') != -1 ){
               html = html.replace('More','Less');
            } else {
               html = html.replace('Less','More');
            }
            return html;
        }).find('img').attr('src',function(i,src){
        return (src.indexOf('plus.gif') != -1)? 'minus.gif' :'plus.gif';
    });
});
});

Это только переключает больше +/меньше, а не .hiddenText div. (единственная разница в этих двух — добавление next() в третьей строке).

jQuery(function(){
 jQuery(".toggleText").click(function(){
 jQuery(this).next(".hiddenText").slideToggle("none");
        jQuery(this).html(function(i,html) {
            if (html.indexOf('More') != -1 ){
               html = html.replace('More','Less');
            } else {
               html = html.replace('Less','More');
            }
            return html;
        }).find('img').attr('src',function(i,src){
        return (src.indexOf('plus.gif') != -1)? 'minus.gif' :'plus.gif';
    });
});
});

Любые идеи?

PS: я использую jQuery вместо $ из-за конфликта с CMS, в котором живет этот код. в.


person Peachy    schedule 28.10.2010    source источник


Ответы (2)


jQuery(this).html(function(i,html) {

Не путайтесь с html()/innerHTML. Это не то, что вы думаете.

Когда вы делаете это, вы просите браузер сериализовать свою текущую модель документа в строку HTML. Затем вы возитесь с HTML и записываете его обратно, после чего браузер должен уничтожить все существующее содержимое элемента и заменить его новыми узлами DOM, проанализированными из строки HTML.

Помимо того, что он медленный и ненадежный (потому что вы действительно не знаете, какой именно формат браузер выберет для сериализации контента; он не будет совпадать с исходным HTML-кодом, который вы ему передали), это также обязательно уничтожает всю информацию в DOM, которую нельзя преобразовать в строку HTML-разметки. Сюда входят значения полей формы, ссылки на JavaScript и обработчики событий.

Таким образом, когда вы вернете HTML, вы потеряете все события click для элемента в этой разметке, в том числе и для стрелок открытия/закрытия.

Забудьте о взломе HTML-строки. Работайте непосредственно с элементами DOM, напрямую изменяя text() каждого элемента с текстовым содержимым More/Less.

person bobince    schedule 28.10.2010

Судя по тому, как ты пишешь

jQuery(this).next(".hiddenText")

Я предполагаю, что вы хотите найти следующий .hiddentText после jQuery(this)? .next() работает не так. Я не найду следующего брата, но отфильтрую его с помощью дополнительного селектора.

Вы могли бы использовать

jQuery(this).parent().children(".hiddenText")

если в родительском элементе jQuery(this) есть только один .hiddentText.

person geon    schedule 28.10.2010