2

How would I write the following JavaScript:

var element = document.querySelector('.element')
element.style.color = 'red'

in Reason?

So far I have:

[@@@bs.config {no_export: no_export}];

external document : Dom.document = "document" [@@bs.val];

external query_selector : Dom.document => string => Dom.element = "querySelector" [@@bs.send];

let element = query_selector document ".element";

And that compiles just fine.

But how would I be able to set an attribute (i.e. style) on element?

glennsl
  • 28,186
  • 12
  • 57
  • 75
Raphael Rafatpanah
  • 19,082
  • 25
  • 92
  • 158

2 Answers2

3

So first of all, this is available in bs-webapi already. But if you want to recreate (and simplify) it, here's how:

external document : Dom.document = "document" [@@bs.val];
external querySelector : string => option Dom.element = "" [@@bs.send.pipe: Dom.document] [@@bs.return null_to_opt];
external style : Dom.element => Dom.cssStyleDeclaration = "" [@@bs.get];
external setColor : Dom.cssStyleDeclaration => string => unit = "color" [@@bs.set];

let () =
    switch (document |> querySelector ".element") {
      | Some element => setColor (style element) "red";
      | None => ()
    };

You can also throw type-safety out the window and just do it like this:

external document : Js.t {..} = "document" [@@bs.val];

let () = {
  let element = document##querySelector ".element";
  element##style##color #= "red"
};

But then I'm guessing you're doing this to learn, in which case the latter would be a terrible idea.

glennsl
  • 28,186
  • 12
  • 57
  • 75
0

One way to do it is:

[@@@bs.config {no_export: no_export}];

external document : Dom.document = "document" [@@bs.val];

external query_selector : Dom.document => string => Dom.element = "querySelector" [@@bs.send];

external set_attribute : Dom.element => string => string => unit = "setAttribute" [@@bs.send];

let element = query_selector document ".element";

set_attribute element "style" "color: red";

However, I'm not sure if there is a better way.

Notes:

[@@@bs.config {no_export: no_export}]; prevents Bucklescript from exporting ES6 modules.

The Dom module provides a bunch of types.

Unanswered Questions:

  • How can I take advantage of the Dom module's attr type instead of using string?
  • How can I take advantage of the Dom module's cssStyleDeclaration type instead of using string?
Raphael Rafatpanah
  • 19,082
  • 25
  • 92
  • 158