Skip to content

Commit 48f44aa

Browse files
authored
Merge pull request #154 from ocsigen/popup
Ot_popup/drawer: improve hack for preventing background scroll when a popup/drawer is open on mobile devices
2 parents 52e0b83 + 3abf2e4 commit 48f44aa

File tree

6 files changed

+24
-21
lines changed

6 files changed

+24
-21
lines changed

css/ot_drawer.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
/* Generic drawer stylesheet. */
22

3+
html.ot-drawer-open, html.ot-drawer-open > body {
4+
overflow: hidden;
5+
position: fixed ; /* To prevent scroll on mobile devices.
6+
One must also set top property manually
7+
to prevent scrolling page to top. */
8+
}
9+
310
/* .ot-dr-container.open .ot-dr-toggle-button { */
411
/* display: none; */
512
/* } */

css/ot_popup.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
html.ot-with-popup, html.ot-with-popup > body {
2+
overflow: hidden;
3+
position: fixed ; /* To prevent scroll on mobile devices.
4+
One must also set top property manually
5+
to prevent scrolling page to top. */
6+
}
17
.ot-popup-background {
28
position: fixed ;
39
right: 0 ;

src/widgets/ot_drawer.eliom

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ let%shared drawer
8282
?(position = `Left)
8383
?(opened = false)
8484
?(swipe = true)
85-
?(ios_scroll_pos_fix=true)
8685
?(onclose : (unit -> unit) Eliom_client_value.t option)
8786
?(onopen : (unit -> unit) Eliom_client_value.t option)
8887
?(wrap_close = fun f -> f)
@@ -114,8 +113,8 @@ let%shared drawer
114113
let close = [%client
115114
((fun () ->
116115
remove_class ~%bckgrnd "open";
117-
if ~%ios_scroll_pos_fix then
118-
Dom_html.document##.body##.scrollTop := !scroll_pos;
116+
Dom_html.document##.body##.style##.top := Js.string "";
117+
Dom_html.window##scroll 0 !scroll_pos;
119118
add_class ~%bckgrnd "closing";
120119
Lwt.cancel !(~%touch_thread);
121120
Lwt_js_events.async (fun () ->
@@ -129,12 +128,11 @@ let%shared drawer
129128

130129
let open_ = [%client
131130
((fun () ->
132-
if ~%ios_scroll_pos_fix then
133-
scroll_pos := Dom_html.document##.body##.scrollTop;
131+
scroll_pos := (Js.Unsafe.coerce Dom_html.window)##.pageYOffset;
134132
add_class ~%bckgrnd "open";
135133
Eliom_lib.Option.iter (fun f -> f ()) ~%onopen;
136-
if ~%ios_scroll_pos_fix then
137-
Dom_html.document##.body##.scrollTop := !scroll_pos;
134+
Dom_html.document##.body##.style##.top :=
135+
Js.string (Printf.sprintf "%dpx" (- !scroll_pos));
138136
add_class ~%bckgrnd "opening";
139137
Lwt.cancel !(~%touch_thread);
140138
Lwt.async (fun () ->

src/widgets/ot_drawer.eliomi

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@
3434
If [swipe] is true (default), the user can swipe to open or close the
3535
drawer.
3636
37-
If [ios_scroll_pos_fix] is true (default) each time after the drawer is
38-
opened, the scroll position of the document body is set to the value it
39-
had just before opening the drawer. This is a workaround for a bug in iOS
40-
mobile where if one prevents document scrolling by CSS (requires on iOS the
41-
CSS code: html.dr-drawer-open, html.dr-drawer-open>body {overflow: hidden})
42-
the document is scrolled to the top.
43-
4437
If present, function [onclose] is called just after the drawer is closed,
4538
and function [onopen] just before it starts opening.
4639
@@ -53,7 +46,6 @@ val drawer :
5346
?position:[ `Left | `Right ] ->
5447
?opened:bool ->
5548
?swipe:bool ->
56-
?ios_scroll_pos_fix:bool ->
5749
?onclose:(unit -> unit) Eliom_client_value.t ->
5850
?onopen:(unit -> unit) Eliom_client_value.t ->
5951
?wrap_close:((unit -> unit) Eliom_client_value.t ->

src/widgets/ot_popup.eliom

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ let%client popup
3838
?(onclose = fun () -> Lwt.return_unit)
3939
?(close_on_background_click=false)
4040
?(close_on_escape=close_button <> None)
41-
?(ios_scroll_pos_fix=true)
4241
gen_content =
4342
let a = (a :> Html_types.div_attrib attrib list) in
4443
let gen_content =
@@ -59,18 +58,20 @@ let%client popup
5958
| None -> ()
6059
in
6160

62-
if ios_scroll_pos_fix then scroll_pos := Dom_html.document##.body##.scrollTop;
61+
(* Hack to prevent body scrolling behind the popup on mobile devices: *)
62+
scroll_pos := (Js.Unsafe.coerce Dom_html.window)##.pageYOffset;
6363
html_ManipClass_add "ot-with-popup";
64-
if ios_scroll_pos_fix then Dom_html.document##.body##.scrollTop := !scroll_pos;
64+
Dom_html.document##.body##.style##.top :=
65+
Js.string (Printf.sprintf "%dpx" (- !scroll_pos));
6566

6667
let kill_keydown_thread = ref @@ fun () -> () in
6768

6869
let do_close () =
6970
if (Dom_html.document##getElementsByClassName (Js.string "ot-popup"))
7071
##.length = 1 then begin
7172
html_ManipClass_remove "ot-with-popup";
72-
if ios_scroll_pos_fix then
73-
Dom_html.document##.body##.scrollTop := !scroll_pos
73+
Dom_html.document##.body##.style##.top := Js.string "";
74+
Dom_html.window##scroll 0 !scroll_pos
7475
end;
7576
let () = Eliom_lib.Option.iter Manip.removeSelf !popup in
7677
!kill_keydown_thread ();

src/widgets/ot_popup.eliomi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ val popup :
7171
-> ?onclose:(unit -> unit Lwt.t)
7272
-> ?close_on_background_click:bool
7373
-> ?close_on_escape:bool
74-
-> ?ios_scroll_pos_fix:bool
7574
-> ((unit -> unit Lwt.t) -> [< div_content ] elt Lwt.t)
7675
-> [> `Div ] elt Lwt.t
7776

0 commit comments

Comments
 (0)