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!
function setup() { noCanvas(); createP('Drag me into "Drag Here!"'); createP('Drag Here!').dragOver(highlight); } function highlight() { this.style('background-color', 'red'); clearTimeout(highlight.id); highlight.id = setTimeout(() => this.style('background-color', 'gray'), 400); }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 ofthisfor setListStyle(). Therefore, you can't re-use that same callbackfunctionfor 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
function setup() { noCanvas(); createP('Drag me into "Drag Here!"'); createP('Drag Here!') .style('background-color: gray') .dragOver(function () { changeBG.call(this, 'red'); }) .dragLeave(function () { changeBG.call(this, 'gray'); }); } function changeBG(colour) { this.style('background-color', colour); }And a much concise 1 based on Function::bind() method.
No need to wrap up callback changeBG() w/ another
functionthis time: :-bdhttps://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
function setup() { noCanvas(); createP('Drag me into "Drag Here!"'); const p = createP('Drag Here!').style('background-color: gray'); p.dragOver(changeBG.bind(p, 'red')).dragLeave(changeBG.bind(p, 'gray')); } function changeBG(colour) { this.style('background-color', colour); }@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
thisto 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
thisto a specific object. :ar!There's some slightly bottleneck when we force a function's
thisto 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/
function setup() { noCanvas(); createP('Drag me into "Drag Here!"'); createP('Drag Here!') .style('background-color: gray') .dragOver(function () { changeBG(this, 'red'); }) .dragLeave(function () { changeBG(this, 'gray'); }); } function changeBG(p5Element, colour) { p5Element.style('background-color', colour); }Answer 2:
A) call() case:
thisis a p5.Element reference.changeBG.call(this, 'red');invokes changeBG() via call(), forcing it to have itsthisto be the same as wrapper's p5.Element referencethisas well. :ar!B) bind() case:
thisset to some object reference.thisto some object reference for later calls of the wrapper. :-Bthisis b/c the bind()'s wrapper is being created, not called.thisis 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. :-@
returnreturns 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.functioncan be accessed, thus becoming a closure, from its nested functions & classes. \m/var,let,const,function&class. B-)