We are about to switch to a new forum software. Until then we have removed the registration on this forum.
This is what I have in my html:
<p id="dz"> Dropzone </p>
and in my sketch.js I have this:
function setup() {
noCanvas();
var dzPtr=select("#dz");
dzPtr.dragOver(highlight);
dzPtr.dragLeave(unhighlight);
}
function highlight(){
this.style('background-color','#ccc');
}
function unhighlight(){
this.style('background-color','#fff');
}
Question: Instead of having two function to work on the paragraph element, could I use one with parameters? How to implement something like this? I understand I will need a closure. Could somebody provide me an example?
Kf
Answers
Like all regular callbacks, we don't choose which parameters are sent when its trigger invokes it. [-X
Nonetheless, I did an example w/ dragOver() only, relying on setTimeout() in order to dehighlight it after 400 ms; and clearTimeout() in order to cancel it when highlight() is re-invoked before 400 ms: :ar!
This next attempt doesn't work, but should it?
In setup():
And then using a closure:
Using a different indirect approach, in the console log I can do:
and it works, my HTML element's style gets updated. So I guess I cannot pass a closure's function as a callback?
Kf
This next worked using anonymous functions following this link:
In setup():
And the extra definition:
Kf
In your latest example, you're still using both dragOver() & dragLeave() events.
I thought you wanted to use dragOver() only?! :-/
You're also relying on
global variable _dzPtr_select() to a specific Element instead ofthis
for setListStyle(). Therefore, you can't re-use that same callbackfunction
for another p5.Element. #-oYou're still creating 2 distinct callback wrappers for callback setListStyle().
1 for dragOver() and the other for dragLeave(). 8-|
Now that I think I understand what you actually wanted, I've made the following variation example below based on Function::call() method: :bz
https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
And a much concise 1 based on Function::bind() method.
No need to wrap up callback changeBG() w/ another
function
this time: :-bdhttps://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
@GoToLoop
I have both dragOver and dragLeave and instead of having highlight and unhighlight functions, I would like to use a callback function with a parameter. My last attempt worked... I was hoping one could do it some other way...
Kf
@GoToLoop Thank you!
Question 1: Any big difference between using your call() version and my setListStyle() version related to efficiency? Would one be more proper over the other?
Question 2: Could you comment on the difference between bind and call? They have almost the same signature, The subtle difference is how they access the object to modify. On one you use 'this' and on the second you use the actual reference to the element, aka. 'p'. Also, I can see the second parameter of bind and call gets assigned as the parameter for changeBG(). This is very neat. Could I do something like this, passing multiple param instead of only one?
createP('Drag Here!').dragOver(function () { changeCol.call(this, 'red', 'blue'); })
then
Question 3: Related to my closure attempt (my post where I use highlight2() above), why it doesn't work? Any ideas?
Kf
Answer 1:
The diff. is that your setListStyle() can only act upon the HTMLElement whose attribute id is '#dz':
https://developer.Mozilla.org/en-US/docs/Web/HTML/Global_attributes/id
While my changeBG() callback expects its
this
to be any p5.Element object:https://p5js.org/reference/#/p5.Element
That enforcement is achieved by call(), apply() or bind(), which change a function's
this
to a specific object. :ar!There's some slightly bottleneck when we force a function's
this
to become some other object. But I doubt it to be any perceptible amount for most cases. ;;)As a bonus, here's a version in which changeBG() callback doesn't rely on
this
.Instead, it requests a p5.Element object as its 1st argument; thus still keeping its flexibility to act upon on any HTMLElement on the HTML page: \m/
Answer 2:
A) call() case:
this
is a p5.Element reference.changeBG.call(this, 'red');
invokes changeBG() via call(), forcing it to have itsthis
to be the same as wrapper's p5.Element referencethis
as well. :ar!B) bind() case:
this
set to some object reference.this
to some object reference for later calls of the wrapper. :-Bthis
is b/c the bind()'s wrapper is being created, not called.this
is the global Window object rather than the p5.Element object at that moment. @-)Answer 3:
I didn't see any closure technique there. That was merely an ordinary prototypal OOP pattern. :-@
return
returns undefined.h0 = h0.highlight2();
is run, variable h0 is reassigned to undefined. @-)dzPtr.dragLeave(h0);
, undefined is the argument passed to dragLeave()! #-oThxs @GoToLoop!
Kf
@GoToLoop
This is my new attempt and it works :-bd :
button_olist.js
Index.html
Now I get one question. One of the things I was doing wrong before was:
Could you comment why this.val is different to var val?
Kf
this
. :-Bfunction
.object
. ;;).
dot.function
can be accessed, thus becoming a closure, from its nested functions & classes. \m/var
,let
,const
,function
&class
. B-)