[Proto-Scripty] Re: this keyword inside of the map function
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 dru...@dimedis.de Sent: Tuesday, August 25, 2009 3:06 AM To: prototype-scriptaculous@googlegroups.com 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 dru...@dimedis.de Sent: Friday, August 21, 2009 3:38 AM To: prototype-scriptaculous@googlegroups.com 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 t...@crowdersoftware.com Sent: Thursday, August 20, 2009 3:56 AM To: Prototype script.aculo.us prototype-scriptaculous@googlegroups.com 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 dru...@dimedis.de 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
[Proto-Scripty] Re: this keyword inside of the map function
Thanks a lot! It's working perfectly now! -Andy -- From: Daniel Rubin dru...@dimedis.de Sent: Wednesday, August 26, 2009 3:01 AM To: prototype-scriptaculous@googlegroups.com Subject: [Proto-Scripty] Re: this keyword inside of the map function 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 dru...@dimedis.de Sent: Tuesday, August 25, 2009 3:06 AM To: prototype-scriptaculous@googlegroups.com 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 dru...@dimedis.de Sent: Friday, August 21, 2009 3:38 AM To: prototype-scriptaculous@googlegroups.com 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 t...@crowdersoftware.com Sent: Thursday, August 20, 2009 3:56 AM To: Prototype script.aculo.us prototype-scriptaculous@googlegroups.com 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 dru...@dimedis.de 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
[Proto-Scripty] Re: this keyword inside of the map function
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 prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[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 dru...@dimedis.de 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 prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: this keyword inside of the map function
I tried the first suggestion, but the function still isn't getting called. 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 t...@crowdersoftware.com Sent: Thursday, August 20, 2009 3:56 AM To: Prototype script.aculo.us prototype-scriptaculous@googlegroups.com 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 dru...@dimedis.de 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 prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options
[Proto-Scripty] Re: this keyword inside of the map function
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)); You need to pass 'this' as the first argument to bind(). regards, - Kev -- Kevin Porter Advanced Web Construction Ltd http://webutils.co.uk http://billiardsearch.net http://9ballpool.co.uk AJAX Blackjack - real-time multi-player blackjack game with no flash, java or software downloads required - http://blackjack.webutils.co.uk --~--~-~--~~~---~--~~ 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 prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: this keyword inside of the map function
I tried putting this as the first argument to bind, but the function doesn't get called. Am I using the right syntax for calling the function -Andy -- From: Kevin Porter k...@9ballpool.co.uk Sent: Wednesday, August 19, 2009 5:14 PM To: prototype-scriptaculous@googlegroups.com Subject: [Proto-Scripty] Re: this keyword inside of the map function 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)); You need to pass 'this' as the first argument to bind(). regards, - Kev -- Kevin Porter Advanced Web Construction Ltd http://webutils.co.uk http://billiardsearch.net http://9ballpool.co.uk AJAX Blackjack - real-time multi-player blackjack game with no flash, java or software downloads required - http://blackjack.webutils.co.uk --~--~-~--~~~---~--~~ 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 prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---