Yeah that worked.  I'm not certain I understand why though :)

It does make sense that the closure would actually have to be created inside
the event handler but .apply(self) is a new one for me.  What exactly is
that doing?


Blair Mitchelmore-2 wrote:
> 
> I understand your frustration. When I first got into JavaScript all I 
> ever heard was closures and I had no idea what they were, but you've 
> pretty much got it. The problem you're having with the code you have 
> there is that window.setTimeout doesn't modify scope, it uses the window 
> as the scope of the function. That's why this.id doesn't work when using 
> the timeout method. I forgot that my plug-in fixed that problem so I 
> didn't write the setTimeout section properly. What you need to do is 
> create a function that calls that function in the proper scope. There 
> used to be a closure plug-in at <http://mg.to/jquery-code/closure.js> 
> but it's fairly dated by now. Here's a quick rewrite of your solution 
> that should fix the setTimeout problems you have:
> 
> $(document).ready( function() {
>       var timer;
>       var fn = function(e) {
>               if (e && e.type == 'blur') {
>                       if (timer)
>                               window.clearTimeout(timer);
>               }
>               // Do stuff
>               alert(this.id);
>       }
>       $('#test').blur(fn).keyup(function() {
>                       var self = this;
>                       timer = window.setTimeout(function() {
>                               fn.apply(self);
>                       },2000);
>       }).keydown(function() {
>               if (timer) window.clearTimeout(timer);
>       });
> });
> 
> The fn function now gets called inside the setTimeout function with a
> reassigned scope so even in the setTimeout situation this refers to the
> DOM element in question.
> 
> 
> -blair
> 
> Daemach wrote:
>> I appreciate you taking the time to lay this out.  I'm really just trying
>> to
>> understand more than anything.  Obviously this isn't the right forum to
>> be
>> asking questions about closures specifically, but if I can just get a
>> grip
>> on this...
>>
>> I tested this yesterday with the following code.  At the moment it tries
>> to
>> pop 2 alert boxes because the first alert blurs the text field -
>> interestingly, in the second alert box "this.id" is undefined.  Would
>> that
>> be because the timer function wasn't being created inside of the blur
>> function like it is on the keyup?  Closures are all about context right? 
>> I'm assuming the reason the fn function knows about "this" being the dom
>> element is because the timer function is being created inside the keyup
>> event, but that's just a guess.
>>
>> Thanks again for all the help.
>>
>> <script language="JavaScript" type="text/javascript">
>> $(document).ready( function() {
>>      var timer;
>>      var fn = function(e) {
>>              if (e && e.type == 'blur') {
>>                      if (timer)
>>                              window.clearTimeout(timer);
>>              }
>>              // Do stuff
>>              alert(this.id);
>>      }
>>      $('#test').blur(fn).keyup(function() {
>>                      var el = this.id;
>>                      timer = window.setTimeout(fn,2000);
>>      }).keydown(function() {
>>              if (timer) window.clearTimeout(timer);
>>      });
>> });
>> </script>
>>
>>
>> <input type="text" id="test" name="test" value="">
>>
>>
>>
>> Blair Mitchelmore-2 wrote:
>>>> $(document).ready( function() {
>>>>     $('[EMAIL PROTECTED]').each( function() {
>>>>         $(this).blur( function() {
>>>>             $.AjaxCFC({
>>>>                 url: "/namechangedtoprotecttheinnocent.cfc",
>>>>                 method: "updateAttendee",
>>>>                 data: {
>>>>                     fid:this.id,
>>>>                     field:this.id.split("_")[0],
>>>>                     id:this.id.split("_")[1],
>>>>                     value:this.value
>>>>                 },
>>>>                 success: function(r){
>>>>                     $('#'+r).css("backgroundColor","#ddFFdd");
>>>>                 }
>>>>             });
>>>>             $(this).css("backgroundColor","#FFdddd");
>>>>         });
>>>>     });
>>>> }); 
>>> Well it looks like the variables you need to access are all a part of 
>>> the DOM element, right? So you can access that element by the same 
>>> 'this' variable because both the blur and the once function reassign 
>>> 'this' to be the DOM element. I am again using my plugin to make the 
>>> code simpler, but you don't need to.
>>>
>>> Code:
>>>
>>> var fn = function(e) {
>>>     if (e && e.type == 'blur') $(this).stop();
>>>     $.AjaxCFC({
>>>             url: "/namechangedtoprotecttheinnocent.cfc",
>>>             method: "updateAttendee",
>>>             data: {
>>>                     fid:this.id,
>>>                     field:this.id.split("_")[0],
>>>                     id:this.id.split("_")[1],
>>>                     value:this.value
>>>             },
>>>             success: function(r){
>>>                     $('#'+r).css("backgroundColor","#ddFFdd");
>>>             }
>>>     });
>>>     $(this).css("backgroundColor","#FFdddd");
>>> }
>>> $(whatever).blur(fn).keyup(function() {
>>>     $(this).once(2000,fn);
>>> }).keydown(function() {
>>>     $(this).stop();
>>> });
>>>
>>> Let me know if that works.
>>>
>>> -blair
>>>
>>> Daemach wrote:
>>>> Grrr Nabble is tricky ;)  Try this thread: 
>>>> http://www.nabble.com/forum/ViewPost.jtp?post=9089663&framed=y
>>>>
>>>>
>>>>
>>>> Blair Mitchelmore-2 wrote:
>>>>> Could I maybe see the code? It's hard to customize something to a 
>>>>> situation I nothing about.
>>>>>
>>>>> -blair
>>>>>
>>>>> Daemach wrote:
>>>>>> OK I played around with this for a while with a fresh head.  As I
>>>>>> understand
>>>>>> it, the main power of closures is that they retain the environment in
>>>>>> which
>>>>>> they were created.  I'm not sure how that applies here, since
>>>>>> closures
>>>>>> have
>>>>>> to be defined inside of another function then returned to retain that
>>>>>> environment, but I'm sure it's something I'm overlooking.
>>>>>>
>>>>>> The problem with the code below is that I need to pass other
>>>>>> variables
>>>>>> in
>>>>>> addition to the event, such as the id and  value of the input element
>>>>>> that
>>>>>> this event handler is being registered on - how can I do this with
>>>>>> the
>>>>>> below
>>>>>> code?
> 
> _______________________________________________
> jQuery mailing list
> [email protected]
> http://jquery.com/discuss/
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Gmail-style-updates-tf3269331.html#a9110390
Sent from the JQuery mailing list archive at Nabble.com.


_______________________________________________
jQuery mailing list
[email protected]
http://jquery.com/discuss/

Reply via email to