jscl
jscl copied to clipboard
passing lambda as a callback
I'm trying to use MutationObserver
object to catch a DOM change using the following code (can be reproduced in JSCL console):
(defparameter obs (jscl::make-new (jscl::oget (jscl::%js-vref "window") "MutationObserver") (lambda (&rest args) (format t "~A~%" args))))
(defparameter cfg (jscl::new))
(setf (jscl::oget cfg "childList") t)
((jscl::oget obs "observe") ((jscl::oget (jscl::%js-vref "document") "getElementById") "console") cfg)
When I'm adding a node (using developer tools) to console
div, getting the following:
(#<JS-OBJECT [object MutationObserver]>)
So, the lambda is called with just one argument, but MutationObserver
callback should receive two. The first one is not passed to the lambda.
In JS console the code works fine, both args are passed:
obs=new MutationObserver((x,y)=>{console.log(x,y)})
MutationObserver { }
obs.observe(document.getElementById("console"),{childList:true})
undefined
Array [ MutationRecord ] MutationObserver { }
For MutationObserver
(as well as for Promise
and some others) you need to use such a constructor instead of make-new
:
var make_Instance = function () {
var args = [].concat(null,Array.prototype.slice.call(arguments,2));
var fn = arguments[0][arguments[1]];
return new (Function.prototype.bind.apply(fn,args))();
};
https://github.com/vlad-km/web-api/blob/master/mutation-observer/package.lisp#:~:text=(eval%2Dwhen%20(%3Acompile,make%2Dinstance%2Dproto))))
see its use:
(defun new-observer (fun)
"Constructor for instantiating new DOM mutation observers"
(#j:make_Instance #j:window "MutationObserver"
(lambda (mutations observer)
;; mutations - array of MutationRecord
;; observer - some mutant observer
(funcall fun mutations))))
https://github.com/vlad-km/web-api/blob/master/mutation-observer/observer.lisp#:~:text=(defun%20new%2Dobserver,funcall%20fun%20mutations))))