tags:

views:

33

answers:

2

I have a jQuery toggler that I am fighting with. I can get it to toggle the visibility of multiple divs at once, but as soon as I implement the next() function, the only thing that toggles is the plus/minus portion of the script, not the visibility of the div. Anything stand out in this code?

This works, but toggles all divs instead of just the closes one:

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';
    });
});
});

This only toggles the more +/less - and not the .hiddenText div. (the only difference in these two is the addition of next() in the third line).

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';
    });
});
});

Any ideas?

PS: I am using jQuery instead of the $ because of a conflict with the CMS this code lives. in.

A: 

From the way you write

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

I'm guessing that you want to find the next .hiddentText after jQuery(this)? That's not how .next() works. I't will find the next sibling, but filter it by the optional selector.

You could possibly use

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

if there is only one .hiddentText in the parent of jQuery(this).

geon
+1  A: 
jQuery(this).html(function(i,html) {

Don't futz with the html()/innerHTML. It is not doing what you think.

When you do this, you're asking the browser to serialise its current document model to an HTML string. You then fiddle with the HTML and write it back, at which point the browser has to destroy all the existing element content and replace it with new DOM nodes parsed from the HTML string.

Apart from being slow and unreliable (because you really don't know what exact format the browser will choose to serialise the content in; it won't be the same as the original HTML you fed it), this also necessarily destroys all information in the DOM that cannot be converted to a string of HTML markup. That includes form field values, JavaScript references, and event handlers.

So, when you write the HTML back, you will have lost all click events on element in that markup, including those on the open/close arrows.

Forget HTML string hacking. Work directly on the DOM elements, changing the text() of each element with the More/Less text content directly.

bobince