Andy Daykin wrote:
> The way that my script is working on that page http://andydaykin.com/Home
> (http://andydaykin.com/Home/public/js/Home.js is the link to the javascript
> file) is how I want it to work, but I want to make my script fit the
> prototype conventions a little bit more.
>
> So if I try and make instance variables, the doSlide function can't see
> them. As I stated before the scope of this inside of the map function is
> what is causing the problem I believe. The click handler (doSlide) won't
> recognize an instance variable.
>
> For instance if I say this.varName in my init function, and try and access
> this.varName in the doSlide function, the variable won't be recognized.
>
> To solve this I am using "var varName" outside of the class, but I would
> like to do this the "proper" way.
>
> -Andy
Alright, I'll just post how I believe it should work.
//============================================================
initialize: function (parentDiv, featuresWrapper) {
var features = $(featuresWrapper).descendants ();
$(parentDiv).descendants ().map (function (e, i) {
$(e).observe ('click',
this.doSlide.bind (this, features[i].id));
}, this);
slides = $$('.featureImage').map (function (e) {
return e.id;
});
},
//============================================================
1) I threw out the dom:loaded-handling stuff: The particular SlideShow
object should be created in such a handler, of course, but listening
for the event in the constructor would limit the class' use to this
application only.
Instead, put
var mySlide = new SlideShow ('featureList', 'featuresWrapper');
in your global dom:loaded handler in the main HTML file. (But make
sure to load Home.js first.)
2) The featuresWrapper Element is passed as constructor arg now, too.
No point in hard-coding it, I think.
3) Note "this" as the second parameter to the map-call. That's the
"context"-param T. J. pointed out. By passing "this", we ensure
that "this" is the same inside and outside the mapping-function.
4) The mapping-function takes a second parameter "i", which is just
the old counter "i", but readily provided by the map-iteration.
I hope this works -- I have not tested it myself.
Have fun
----Daniel
> --------------------------------------------------
> From: "Daniel Rubin" <[email protected]>
> Sent: Tuesday, August 25, 2009 3:06 AM
> To: <[email protected]>
> Subject: [Proto-Scripty] Re: this keyword inside of the map function
>
>> Andy Daykin wrote:
>>> The doSlide function was what I was referring to. I tried using TJ's
>>> suggestion of using this as the 2nd parameter, but the handler still
>>> wasn't
>>> getting called. You can find a prototype of what I am doing at
>>> http://andydaykin.com/Home. The slideshow (images obviously missing) is
>>> on
>>> the main page. The javascript file for the class is
>>> http://andydaykin.com/Home/public/js/Home.js
>> Could you please provide the current state once more? Perhaps stripped
>> down to the vital parts of HTML and scripts? I think we need to have a
>> look at the details here.
>>
>> ----Daniel
>>
>>
>>
>>> --------------------------------------------------
>>> From: "Daniel Rubin" <[email protected]>
>>> Sent: Friday, August 21, 2009 3:38 AM
>>> To: <[email protected]>
>>> Subject: [Proto-Scripty] Re: this keyword inside of the map function
>>>
>>>> Andy Daykin wrote:
>>>>> I tried the first suggestion, but the function still isn't getting
>>>>> called.
>>>> Exactly which function do you refer to? The map-iterator-func ("function
>>>> (e) { ... }") or the click-handler (this.doSlide)?
>>>>
>>>> ----Daniel
>>>>
>>>>
>>>>
>>>>> TJ, can you explain more, or show an example of what the context param
>>>>> would
>>>>> look like? Should I just put the doSlide function as the 2nd parameter?
>>>>>
>>>>> -Andy
>>>>>
>>>>> --------------------------------------------------
>>>>> From: "T.J. Crowder" <[email protected]>
>>>>> Sent: Thursday, August 20, 2009 3:56 AM
>>>>> To: "Prototype & script.aculo.us"
>>>>> <[email protected]>
>>>>> Subject: [Proto-Scripty] Re: this keyword inside of the map function
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> Rather than binding it, use the second parameter to map (aka collect
>>>>>> [1]), that's what the second param ("context") is for. You'll find
>>>>>> that most of the Enumerable methods that take callbacks also take a
>>>>>> context parameter so the callback can be a method.
>>>>>>
>>>>>> [1] http://prototypejs.org/api/enumerable/collect
>>>>>>
>>>>>> HTH,
>>>>>> --
>>>>>> T.J. Crowder
>>>>>> tj / crowder software / com
>>>>>> Independent Software Engineer, consulting services available
>>>>>>
>>>>>>
>>>>>> On Aug 20, 8:34 am, Daniel Rubin <[email protected]> wrote:
>>>>>>> Andy Daykin wrote:
>>>>>>>> Hello, I am having some difficulties writing a class, in my code I
>>>>>>>> have
>>>>>>>> a class where I need to be able to bind event listeners to values.
>>>>>>>> In
>>>>>>>> my code I want the variable pointerIndex to be accessible outside of
>>>>>>>> the initialize function, but right now it is not. If I make a global
>>>>>>>> variable for pointerIndex I can solve the problem, but I would
>>>>>>>> rather
>>>>>>>> have a class variable using the this keyword.
>>>>>>>> I am not positive, but I believe the problem is from my event
>>>>>>>> listeners
>>>>>>>> on the line:
>>>>>>>> Now: $(e).observe('click',
>>>>>>>> this.doSlide.bind(featuresWrapper[i].id));
>>>>>>>> Before: (working) $(e).observe('click',
>>>>>>>> mySlide.doSlide.curry(featuresWrapper[i].id));
>>>>>>>> With the new way of calling the doSlide function I can't even seem
>>>>>>>> to
>>>>>>>> be able to call the function, nothing happens when the function
>>>>>>>> should
>>>>>>>> get called. Before I was using the curry function to try and pass
>>>>>>>> the
>>>>>>>> values of the featuresWrapper array to the doSlide function. I was
>>>>>>>> able
>>>>>>>> to get that to work, but I would rather just use bind and this to
>>>>>>>> make
>>>>>>>> the code more object oriented. Based on my alert statements I can
>>>>>>>> tell
>>>>>>>> that the this keyword is different inside and outside of the map
>>>>>>>> function.
>>>>>>> Hi Andy,
>>>>>>>
>>>>>>> the last observation is crucial. Because this is not your expected
>>>>>>> SlideShow instance when you do this.doSlide.bind (...), this.doSlide
>>>>>>> is
>>>>>>> undefined and thus the call to this.doSlide.bind fails (there should
>>>>>>> be
>>>>>>> an exception in the error console somewhere).
>>>>>>>
>>>>>>> You can solve it by bind()-ing the map function, too:
>>>>>>> $(parentDiv).childElements().map( (function(e) {
>>>>>>> $(e).observe('click',
>>>>>>> this.doSlide.bind(this, featuresWrapper[i].id));
>>>>>>> }).bind (this) );
>>>>>>>
>>>>>>> (Note: Passing this as first arg to the inner bind call, as Kevin
>>>>>>> suggested, is needed, too.)
>>>>>>>
>>>>>>> Have fun
>>>>>>> ----Daniel
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> var SlideShow = Class.create({
>>>>>>>> initialize: function(parentDiv) {
>>>>>>>> this.pointerIndex = 0;
>>>>>>>> //pointerIndex = 0;
>>>>>>>> // Load the event listener for each section
>>>>>>>> document.observe("dom:loaded", function() {
>>>>>>>> var featuresWrapper = $('featuresWrapper').childElements();
>>>>>>>> var i = 0;
>>>>>>>> alert(this);
>>>>>>>> $(parentDiv).childElements().map(function(e) {
>>>>>>>> alert(this);
>>>>>>>> $(e).observe('click', this.doSlide.bind(featuresWrapper[i].id));
>>>>>>>> //$(e).observe('click',
>>>>>>>> mySlide.doSlide.curry(featuresWrapper[i].id));
>>>>>>>> i++;
>>>>>>>> });
>>>>>>>> slides = $$('.featureImage').map(function(e) {
>>>>>>>> return e.id;
>>>>>>>> });
>>>>>>>> });
>>>>>>>> },
>>>>>>>> doSlide: function(slideClicked) {
>>>>>>>> alert('here');
>>>>>>>> if(active == 0) {
>>>>>>>> active = 1;
>>>>>>>> var yValCurrent = $(slides[this.pointerIndex]).viewportOffset().top;
>>>>>>>> //var yValCurrent = $(slides[pointerIndex]).viewportOffset().top;
>>>>>>>> var yValClick = $(slideClicked).viewportOffset().top;
>>>>>>>> var yValDiff = yValClick - yValCurrent;
>>>>>>>> var pointerShift = 0;
>>>>>>>> if (Math.abs(yValDiff) == Math.abs(210)) {
>>>>>>>> pointerShift = 70; // Change this to get the height as well as a few
>>>>>>>> more
>>>>>>>> }
>>>>>>>> else {
>>>>>>>> pointerShift = 140;
>>>>>>>> }
>>>>>>>> if (yValDiff > 0) {
>>>>>>>> $$('.featureImage').map(function(e) {
>>>>>>>> new Effect.Move(e, { y: -yValDiff, duration: .8, afterFinish:
>>>>>>>> function(e) { active = 0; } });
>>>>>>>> });
>>>>>>>> new Effect.Move('featurePointer', { y: pointerShift });
>>>>>>>> }
>>>>>>>> else if (yValDiff < 0) {
>>>>>>>> $$('.featureImage').map(function(e) {
>>>>>>>> new Effect.Move(e, { y: -yValDiff, duration: .8, afterFinish:
>>>>>>>> function(e) { active = 0; } });
>>>>>>>> });
>>>>>>>> new Effect.Move('featurePointer', { y: -pointerShift });
>>>>>>>> }
>>>>>>>> this.pointerIndex = slides.indexOf(slideClicked);
>>>>>>>> }
>>>>>>>> }
>>>>>>>> });
>>>>>>>> var slides;
>>>>>>>> var active = 0;
>>>>>>>> //var pointerIndex = 0;
>>>>>>>> var mySlide = new SlideShow('featureList');
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---