Improved scroll guard for dialogs
authorAlexander Ebert <ebert@woltlab.com>
Fri, 5 May 2017 11:57:29 +0000 (13:57 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 5 May 2017 11:57:29 +0000 (13:57 +0200)
`event.target` and the parent nodes are now evaluated to allow scrolling
inside overflow containers, while still preventing page scrolling.

See #2237

wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js

index a04e1ba9da6175cddc573771b70f6698787b0b9c..b388c8922cb1208b1e9c17ea9030dce6471d2575 100644 (file)
@@ -341,11 +341,34 @@ define(
                        dialog.appendChild(contentContainer);
                        
                        contentContainer.addEventListener('wheel', function (event) {
-                               // positive value: scrolling up
-                               if (event.wheelDelta > 0 && contentContainer.scrollTop === 0) {
-                                       event.preventDefault();
+                               var allowScroll = false;
+                               var element = event.target, clientHeight, scrollHeight, scrollTop;
+                               while (true) {
+                                       clientHeight = element.clientHeight;
+                                       scrollHeight = element.scrollHeight;
+                                       
+                                       if (clientHeight < scrollHeight) {
+                                               scrollTop = element.scrollTop;
+                                               
+                                               // positive value: scrolling up
+                                               if (event.wheelDelta > 0 && scrollTop > 0) {
+                                                       allowScroll = true;
+                                                       break;
+                                               }
+                                               else if (event.wheelDelta < 0 && (scrollTop + clientHeight < scrollHeight)) {
+                                                       allowScroll = true;
+                                                       break;
+                                               }
+                                       }
+                                       
+                                       if (!element || element === contentContainer) {
+                                               break;
+                                       }
+                                       
+                                       element = element.parentNode;
                                }
-                               else if (event.wheelDelta < 0 && (contentContainer.scrollTop + contentContainer.clientHeight === contentContainer.scrollHeight)) {
+                               
+                               if (allowScroll === false) {
                                        event.preventDefault();
                                }
                        });