Mitch,

In your working code:

jQuery.fn.toggleVis = function() {
   if(cheshireCat.style.visibility == 'hidden') {
      cheshireCat.style.visibility = 'visible';
   } else {
      cheshireCat.style.visibility = 'hidden';
   }
};


That can only work if there is a variable called 'cheshireCat' which is
accessible from within jQuery. My best guess is that at some point in your
code you've written

cheshireCat = $("#cheshireCat")[0];

or something similar. The best way to avoid this 'namespace pollution' is to
always use the keyword 'var' when declaring a variable, e.g.

var cheshireCat = $("#cheshireCat")[0];

That prevents the variable from becoming globally available, and I guess
will break the previously working code you have.

Now, the question is, how can you fix the code that I've just broken?
If you add a function to jQuery as you've done, that function will be
available to any jQuery object, and should work upon that object as
expected. So, if you write

$("#cheshireCat").toggleVis();

you should expect that the element with ID 'cheshireCat' will be toggled,
and nothing else. You should also be able to expect that the toggleVis()
function will return the same jQuery object it operated on, which is the
same one you got with $(...), so that you can do other things as well, like
(for example):

 $("#cheshireCat").toggleVis().append('toggled');


Now, this code block:

jQuery.fn.toggleVis = function() {
   if(this.style.visibility == 'hidden') {
      this.style.visibility = 'visible';
   } else {
      this.style.visibility = 'hidden';
   }
};

doesn't work because in a jQuery function, 'this' is not a DOM object (i.e.
the <div> element), it's a jQuery object containing the matching element(s).
How can you get them out? Two ways:
this[0] - will give you the first DOM element in the object, and assumes
that there IS one. If there aren't, you're accessing an array out-of-bounds.
this.each() - will iterate through any and all contained DOM elements. This
is by far the best way to achieve this.

So first off your if..else needs to be wrapped to act on all contained
elements:

this.each(function() {
   if (this.style.visibility == 'hidden') {
      this.style.visibility = 'visible';
   } else {
      this.style.visibility = 'hidden';
   }
});


Within the function passed to .each(), 'this' refers to the actual DOM
element we are currently dealing with, so that part of the code is now
alright.
It still won't allow you to chain function calls though, so one final touch
is to return the result of .each(), and we're done:

jQuery.fn.toggleVis = function() {
   this.each(function() {
      if (this.style.visibility == 'hidden') {
         this.style.visibility = 'visible';
      } else {
         this.style.visibility = 'hidden';
      }
   });
};



I hope that's explained it all a bit better - it took a lot of 'hammering'
before I understood the way jQuery fits together, especially in terms of
what 'this' means when.
Put that function in your code, then try $("#cheshireCat").toggleVis() and
see what happens :-)

--rob


On 7/25/07, Mitchell Waite <[EMAIL PROTECTED]> wrote:


I'm sorry for my apparent ignorance. I tried your approach and it did not
work

DOESN'T WORK
http://www.whatbird.com/wwwroot/Alice_1.html

        jQuery.fn.toggleVis = function() {
        if(this.style.visibility == 'hidden') {
            this.style.visibility = 'visible';
        } else {
            this.style.visibility = 'hidden';
                }
};

WORKS
http://www.whatbird.com/wwwroot/Alice_1.html


        jQuery.fn.toggleVis = function() {
        if(cheshireCat.style.visibility == 'hidden') {
            cheshireCat.style.visibility = 'visible';
        } else {
            cheshireCat.style.visibility = 'hidden';
                }
};

I was under the impression that the object #chesireCat would be the only
object affected by this function, and that its using jQuery's ability to
figure out the object by name.

<div id="cheshireCat"><img src="images/alice24.gif" /></div>

Take a look at the code examples and tell me if I am missing something
here.

Mitch

-----Original Message-----
From: jquery-en@googlegroups.com [mailto:[EMAIL PROTECTED] On
Behalf Of Stephan Beal
Sent: Tuesday, July 24, 2007 11:31 PM
To: jQuery (English)
Subject: [jQuery] Re: Toggling an objects visiblty without show and hide


On Jul 25, 12:41 am, "Mitchell Waite" <[EMAIL PROTECTED]> wrote:
> I know this is trivial but what it turned out I needed was something
this
> simple
>
> jQuery.fn.toggleVis = function() {
>
>         if(chesireCat.style.visibility == 'hidden') {
>
>            chesireCat.style.visibility = 'visible';
>
>         } else {
>
>            chesireCat.style.visibility = 'hidden';
>
>         }
>
> };

Eeeek! What you're doing here is adding a toggleVis() function to ALL
selectable jQuery elements, but then in the function you're applying
the change to a specific element. Thus this will trigger your
function:

$('div').toggleVis();

that will toggle the cheshireCat element, not the selected element(s),
which certainly isn't desired.

What i *think* you meant was to either make that a standalone function
(not using jQuery.fn.) or:

jQuery.fn.toggleVis = function() {
        if(this.style.visibility == 'hidden') {
           this.style.visibility = 'visible';
        } else {
           this.style.visibility = 'hidden';
        }
};








--
Rob Desbois
Eml: [EMAIL PROTECTED]
Tel: 01452 760631
Mob: 07946 705987
"There's a whale there's a whale there's a whale fish" he cried, and the
whale was in full view.
...Then ooh welcome. Ahhh. Ooh mug welcome.

Reply via email to