js_of_ocaml icon indicating copy to clipboard operation
js_of_ocaml copied to clipboard

Add mutation observers in Lwt_js_events

Open balat opened this issue 10 years ago • 10 comments

balat avatar Feb 06 '15 13:02 balat

Hum, What is it ? Why ? How ? ^^'

Drup avatar Feb 06 '15 16:02 Drup

https://developer.mozilla.org/fr/docs/Web/API/MutationObserver

balat avatar Feb 11 '15 15:02 balat

Mutation events ( https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events ) are marked as deprecated. This patch adds support of replacement. Looks like it will be required in the nearest future.

johnlepikhin avatar Nov 08 '15 20:11 johnlepikhin

@johnlepikhin, is there a patch somewhere?

@balat, while it looks useful generally, do we have a concrete immediate application?

Also, would a React layer over this be of service?

vasilisp avatar Nov 09 '15 12:11 vasilisp

An example of practical use is with Material Design Lite ( http://www.getmdl.io ). When you use this framework with dynamic DOM, you have to register new elements ( http://www.getmdl.io/started/index.html#dynamic and http://quaintous.com/2015/07/09/react-components-with-mdl/ ). A trick to do that is to use MutationObserver to automagically call the MDL javascript function upgradeDom ( https://github.com/google/material-design-lite/issues/917 ) :

var observer = new MutationObserver(function(mutations) {
        var upgrade = false;

        for (var i = 0; i < mutations.length; i++) {
            if (mutations[i].addedNodes.length > 0) {
                upgrade = true;
                break;
            } 
        }
        if (upgrade) {
            // If there is at least a new element, upgrade the DOM.
            // Note: upgrading elements one by one seems to insert bugs in MDL 
            window.componentHandler.upgradeDom();
        }
    });
observer.observe(document, {
    childList : true,
    subtree : true
});

slegrand45 avatar Nov 21 '15 16:11 slegrand45

I'm using this for example with a reactive list of comments, when I want to keep it scrolled to the bottom.

Bs_lib.content_changes %d (fun mutations -> Bs_lib.scroll_to_bottom %d);

Another use: If you want to implement custom scrollbars (which is useful as braowser scrollbars are not customizable and horrible), you want the scrollbar position to get updated automatically when the contents change.

A basic implmentation of this is Lwt_js_events would be something like:

(* Content change observer: *)
let content_changes elt f =
  let observer =
    jsnew (Js.Unsafe.global##_MutationObserver)(Js.wrap_callback f)
  in
  observer##observe(To_dom.of_element elt,
                    Js.Unsafe.obj [|("childList", Js.Unsafe.inject Js._true);
                                    ("subtree", Js.Unsafe.inject Js._true)|]);
  ()

balat avatar Nov 24 '15 13:11 balat

(Note that with a reactive implementation, it is difficult to scroll to the bottom without this ...)

balat avatar Nov 24 '15 13:11 balat

mutationObserver.ml was added in 2016

hhugo avatar Nov 11 '19 14:11 hhugo

It is still not in Lwt_js_events if I'm right.

balat avatar Nov 12 '19 10:11 balat

I've now updated the title

hhugo avatar Nov 12 '19 10:11 hhugo