[Proto-Scripty] Re: Anchor button triggers window.onbeforeunload in IE
@JoJo: I start this off responding to Eric, but there's some info (useful, I hope) for you below as well. @Eric: > T.J.'s blog has many very well written articles that will explain you > why... You're very kind!! :-) > Also note that I am 80% sure (please somebody confirm) that since your > parameter is a local variable, javascript will implicitly create a > closure for you. Not *implicitly*, no, but your rewrite has an explicit closure and should absolutely work. You probably know this, but JoJo's mechanism (or, as you point out, Function#curry) is necessary in situations where you're going to change `localVariable` later, for instance loops: var index, localVariable; for (index = 0; index < 10; ++index) { localVariable = "Hi, I'm index " + index; dynamicAnchor = new Element( 'a', { href: 'javascript:void(0)' } ).observe( 'click', function(event) { // <=== Problem window.status = localVariable; event.stop(); } ); } The above would create a bunch of anchors *all* of which would show the message "Hi, I'm index 9", because that's the value of `localVariable` at the end of the loop. So instead, you need to do something like what JoJo did, though if you do *exactly* what JoJo did in a loop, it has to create the factory function on every loop, which is unnecessary as it's invariant: var index, localVariable; for (index = 0; index < 10; ++index) { localVariable = "I'm index " + index; dynamicAnchor = new Element( 'a', { href: 'javascript:void(0)' }; ).observe( 'click', (function(parameter) { // <== This factory function gets duplicated return function(event) { window.status = parameter; Event.stop(event); } })(localVariable); ); } Since nothing keeps a reference to the factory functions, it doesn't matter much. @JoJo: Like Eric, I'd probably use Function#curry. FWIW, this is how I'd write it: // Somewhere useful where I can reuse it, because this looks like // something we'll need to do somewhere else, too function showStatMsgAndStopHandler(message, event) { window.status = message; event.stop(); } // Use it dynamicAnchor = new Element( 'a', { href: 'javascript:void(0)' }; ).observe( 'click', showStatMsgAndStopHandler.curry(localVariable) ); A couple of reasons I'd do it that way: 1. Reuse 2. Well-controlled closures 3. I'm a fan of named functions rather than anonymous ones[1] ;-) 4. Readability (maybe) With the rewrite, _nothing_ closes over the local variables in the context in which this dynamic anchor is being created. Assuming you define `showStatMsgAndStopHandler` in a place you're defining other generally-useful stuff, the only closures in the rewrite are generated in the well-controlled scope of Function#curry. So we're not keeping stuff in memory we don't need. [1] http://blog.niftysnippets.org/2010/03/anonymouses-anonymous.html HTH, -- T.J. Crowder Independent Software Engineer tj / crowder software / com www / crowder software / com On Oct 25, 4:10 pm, Eric wrote: > Hi JoJo, > > It seems you're doing a closure "by hand". You may want to look at > Function.bind() or Function.curry() in prototype documentation, since > they do it for you. > Your solution may become : > dynamicAnchor = new Element( > 'a', { > href: 'javascript:void(0)' > } > ).observe( > 'click', > (function(parameter,event) { > window.status = parameter; > event.stop(); > }).curry(localVariable) > ); > > Also note that I am 80% sure (please somebody confirm) that since your > parameter is a local variable, javascript will implicitly create a > closure for you. > > In other words, this should work: > var localVariable= 'Hi!'; > dynamicAnchor = new Element( > 'a', { > href: 'javascript:void(0)' > } > ).observe( > 'click', > function(event) { > window.status = localVariable; > event.stop(); > } > ); > > T.J.'s blog has many very well written articles that will explain you > why (http://blog.niftysnippets.org/search/label/closures). > > Eric > > On Oct 22, 8:47 pm, JoJo wrote: > > > > > > > > > Thanks T.J. > > > The solution is: > > > dynamicAnchor = new Element( > > 'a', { > > href: 'javascript:void(0)' > > } > > ).observe( > > 'click', > > function(parameter) { > > return function(event) { > > window.status = parameter; > > Event.stop(event); > > } > > }(localVariable) > > ); > > > On Oct 22, 4:39 am, "T.J. Crowder" wrote: > > > > Hi, > > > > See the documentation for `Event.observe`[1] (which is what you're > > > calling indirectly from the `Element#observe` function), specifically > > > the "Preventing the Default Event Action and Bubbling" part, and the > > > `Event` object[2]: You don't return fa
[Proto-Scripty] Re: Anchor button triggers window.onbeforeunload in IE
Hi, On Oct 22, 7:47 pm, JoJo wrote: > Thanks T.J. > > The solution is: > ... FWIW, it's a bit off-topic, but regarding your code where you're defining and then calling a function: function(parameter) { // ... }(localVariable) To ensure that that works reliably across implementations, you'll want to wrap the function expression in parentheses: (function(parameter) { // ... })(localVariable) I don't remember my source for the information, but I remember that I trusted the source. It seems to me your version _should_ work according to the spec, and I know it does for other things, but I think some significant implementation has an issue with generating the call without clarifying it as with the parens above. Happy coding, -- T.J. Crowder Independent Software Engineer tj / crowder software / com www / crowder software / com On Oct 22, 7:47 pm, JoJo wrote: > Thanks T.J. > > The solution is: > > dynamicAnchor = new Element( > 'a', { > href: 'javascript:void(0)' > } > ).observe( > 'click', > function(parameter) { > return function(event) { > window.status = parameter; > Event.stop(event); > } > }(localVariable) > ); > > On Oct 22, 4:39 am, "T.J. Crowder" wrote: > > > > > > > > > Hi, > > > See the documentation for `Event.observe`[1] (which is what you're > > calling indirectly from the `Element#observe` function), specifically > > the "Preventing the Default Event Action and Bubbling" part, and the > > `Event` object[2]: You don't return false to cancel the `click` event, > > you use the `Event#preventDefault` function (which is a standard DOM > > function[3] that Prototype ensures is present even on implementations > > that lack it) or, more likely, `Event#stop`[4] which both prevents the > > default action and stops the event bubbling. > > > [1]http://api.prototypejs.org/dom/event/observe/ > > [2]http://api.prototypejs.org/dom/event/ > > [3]http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-prev... > > [4]http://api.prototypejs.org/dom/event/stop/ > > > HTH, > > -- > > T.J. Crowder > > Independent Software Engineer > > tj / crowder software / com > > www / crowder software / com > > > On Oct 22, 2:41 am, JoJo wrote: > > > > I use anchors to call javascript functions. Usually, I do this: > > > > > > > call the function > > > > > > > This works fine in all browsers. Window.onbeforeunload is never > > > triggered because the ONCLICK returns false, and thus the HREF if not > > > executed. When HREF is not executed, the browser does not believe that > > > the window in unloading. Now, I'm trying to create a dynamic anchor to > > > accomplish the same thing. It looks nearly identical to the HTML > > > anchor, but now it's triggering window.onbeforeunload in IE8. How do I > > > not trigger it? > > > > dynamicAnchor = new Element( > > > 'a', { > > > href: 'javascript:void(0)', > > > } > > > ).observe( > > > 'click', > > > function(parameter) { > > > return function() { > > > window.status = parameter; > > > return false; > > > } > > > }(localVariable) > > > ); -- 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-scriptacul...@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: Anchor button triggers window.onbeforeunload in IE
Hi JoJo, It seems you're doing a closure "by hand". You may want to look at Function.bind() or Function.curry() in prototype documentation, since they do it for you. Your solution may become : dynamicAnchor = new Element( 'a', { href: 'javascript:void(0)' } ).observe( 'click', (function(parameter,event) { window.status = parameter; event.stop(); }).curry(localVariable) ); Also note that I am 80% sure (please somebody confirm) that since your parameter is a local variable, javascript will implicitly create a closure for you. In other words, this should work: var localVariable= 'Hi!'; dynamicAnchor = new Element( 'a', { href: 'javascript:void(0)' } ).observe( 'click', function(event) { window.status = localVariable; event.stop(); } ); T.J.'s blog has many very well written articles that will explain you why (http://blog.niftysnippets.org/search/label/closures). Eric On Oct 22, 8:47 pm, JoJo wrote: > Thanks T.J. > > The solution is: > > dynamicAnchor = new Element( > 'a', { > href: 'javascript:void(0)' > } > ).observe( > 'click', > function(parameter) { > return function(event) { > window.status = parameter; > Event.stop(event); > } > }(localVariable) > ); > > On Oct 22, 4:39 am, "T.J. Crowder" wrote: > > > Hi, > > > See the documentation for `Event.observe`[1] (which is what you're > > calling indirectly from the `Element#observe` function), specifically > > the "Preventing the Default Event Action and Bubbling" part, and the > > `Event` object[2]: You don't return false to cancel the `click` event, > > you use the `Event#preventDefault` function (which is a standard DOM > > function[3] that Prototype ensures is present even on implementations > > that lack it) or, more likely, `Event#stop`[4] which both prevents the > > default action and stops the event bubbling. > > > [1]http://api.prototypejs.org/dom/event/observe/ > > [2]http://api.prototypejs.org/dom/event/ > > [3]http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-prev... > > [4]http://api.prototypejs.org/dom/event/stop/ > > > HTH, > > -- > > T.J. Crowder > > Independent Software Engineer > > tj / crowder software / com > > www / crowder software / com > > > On Oct 22, 2:41 am, JoJo wrote: > > > > I use anchors to call javascript functions. Usually, I do this: > > > > > > > call the function > > > > > > > This works fine in all browsers. Window.onbeforeunload is never > > > triggered because the ONCLICK returns false, and thus the HREF if not > > > executed. When HREF is not executed, the browser does not believe that > > > the window in unloading. Now, I'm trying to create a dynamic anchor to > > > accomplish the same thing. It looks nearly identical to the HTML > > > anchor, but now it's triggering window.onbeforeunload in IE8. How do I > > > not trigger it? > > > > dynamicAnchor = new Element( > > > 'a', { > > > href: 'javascript:void(0)', > > > } > > > ).observe( > > > 'click', > > > function(parameter) { > > > return function() { > > > window.status = parameter; > > > return false; > > > } > > > }(localVariable) > > > ); > > -- 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-scriptacul...@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: Anchor button triggers window.onbeforeunload in IE
Thanks T.J. The solution is: dynamicAnchor = new Element( 'a', { href: 'javascript:void(0)' } ).observe( 'click', function(parameter) { return function(event) { window.status = parameter; Event.stop(event); } }(localVariable) ); On Oct 22, 4:39 am, "T.J. Crowder" wrote: > Hi, > > See the documentation for `Event.observe`[1] (which is what you're > calling indirectly from the `Element#observe` function), specifically > the "Preventing the Default Event Action and Bubbling" part, and the > `Event` object[2]: You don't return false to cancel the `click` event, > you use the `Event#preventDefault` function (which is a standard DOM > function[3] that Prototype ensures is present even on implementations > that lack it) or, more likely, `Event#stop`[4] which both prevents the > default action and stops the event bubbling. > > [1]http://api.prototypejs.org/dom/event/observe/ > [2]http://api.prototypejs.org/dom/event/ > [3]http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-prev... > [4]http://api.prototypejs.org/dom/event/stop/ > > HTH, > -- > T.J. Crowder > Independent Software Engineer > tj / crowder software / com > www / crowder software / com > > On Oct 22, 2:41 am, JoJo wrote: > > > I use anchors to call javascript functions. Usually, I do this: > > > > > call the function > > > > > This works fine in all browsers. Window.onbeforeunload is never > > triggered because the ONCLICK returns false, and thus the HREF if not > > executed. When HREF is not executed, the browser does not believe that > > the window in unloading. Now, I'm trying to create a dynamic anchor to > > accomplish the same thing. It looks nearly identical to the HTML > > anchor, but now it's triggering window.onbeforeunload in IE8. How do I > > not trigger it? > > > dynamicAnchor = new Element( > > 'a', { > > href: 'javascript:void(0)', > > } > > ).observe( > > 'click', > > function(parameter) { > > return function() { > > window.status = parameter; > > return false; > > } > > }(localVariable) > > ); -- 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-scriptacul...@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: Anchor button triggers window.onbeforeunload in IE
Hi, See the documentation for `Event.observe`[1] (which is what you're calling indirectly from the `Element#observe` function), specifically the "Preventing the Default Event Action and Bubbling" part, and the `Event` object[2]: You don't return false to cancel the `click` event, you use the `Event#preventDefault` function (which is a standard DOM function[3] that Prototype ensures is present even on implementations that lack it) or, more likely, `Event#stop`[4] which both prevents the default action and stops the event bubbling. [1] http://api.prototypejs.org/dom/event/observe/ [2] http://api.prototypejs.org/dom/event/ [3] http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-preventDefault [4] http://api.prototypejs.org/dom/event/stop/ HTH, -- T.J. Crowder Independent Software Engineer tj / crowder software / com www / crowder software / com On Oct 22, 2:41 am, JoJo wrote: > I use anchors to call javascript functions. Usually, I do this: > > > call the function > > > This works fine in all browsers. Window.onbeforeunload is never > triggered because the ONCLICK returns false, and thus the HREF if not > executed. When HREF is not executed, the browser does not believe that > the window in unloading. Now, I'm trying to create a dynamic anchor to > accomplish the same thing. It looks nearly identical to the HTML > anchor, but now it's triggering window.onbeforeunload in IE8. How do I > not trigger it? > > dynamicAnchor = new Element( > 'a', { > href: 'javascript:void(0)', > } > ).observe( > 'click', > function(parameter) { > return function() { > window.status = parameter; > return false; > } > }(localVariable) > ); -- 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-scriptacul...@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.