diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 76ffee49a4d6427b023b93eb1629c46bda3235ff..60dbcb320eae7522c1567703d09c97de60e441f6 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -529,6 +529,7 @@ drupal.debounce:
 drupal.dialog:
   version: VERSION
   js:
+    misc/dialog/dialog-deprecation.js: {}
     misc/dialog/dialog.js: {}
     misc/dialog/dialog.position.js: {}
     misc/dialog/dialog.jquery-ui.js: {}
@@ -561,6 +562,7 @@ drupal.dialog:
     - core/drupalSettings
     - core/drupal.debounce
     - core/drupal.displace
+    - core/once
     - core/drupal.jquery.position
     - core/tabbable
 
diff --git a/core/misc/dialog/dialog-deprecation.js b/core/misc/dialog/dialog-deprecation.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e2f960cf8d32fa60c8b99643cf16cd7f2fd702d
--- /dev/null
+++ b/core/misc/dialog/dialog-deprecation.js
@@ -0,0 +1,40 @@
+/**
+ * @file
+ * Maintains and deprecates Dialog jQuery events.
+ */
+
+(function ($, Drupal, once) {
+  if (once('drupal-dialog-deprecation-listener', 'html').length) {
+    const eventSpecial = {
+      handle($event) {
+        const $element = $($event.target);
+        const event = $event.originalEvent;
+        const dialog = event.dialog;
+        const dialogArguments = [$event, dialog, $element, event?.settings];
+        $event.handleObj.handler.apply(this, dialogArguments);
+      },
+    };
+
+    $.event.special['dialog:beforecreate'] = eventSpecial;
+    $.event.special['dialog:aftercreate'] = eventSpecial;
+    $.event.special['dialog:beforeclose'] = eventSpecial;
+    $.event.special['dialog:afterclose'] = eventSpecial;
+
+    const listenDialogEvent = (event) => {
+      const windowEvents = $._data(window, 'events');
+      const isWindowHasDialogListener = windowEvents[event.type];
+      if (isWindowHasDialogListener) {
+        Drupal.deprecationError({
+          message: `jQuery event ${event.type} is deprecated in 10.3.0 and is removed from Drupal:12.0.0. See https://www.drupal.org/node/3422670`,
+        });
+      }
+    };
+
+    [
+      'dialog:beforecreate',
+      'dialog:aftercreate',
+      'dialog:beforeclose',
+      'dialog:afterclose',
+    ].forEach((e) => window.addEventListener(e, listenDialogEvent));
+  }
+})(jQuery, Drupal, once);
diff --git a/core/misc/dialog/dialog.ajax.js b/core/misc/dialog/dialog.ajax.js
index f8a1b5f90cf8eed3ab64d1315b3523b5550a12ba..6a839e4d8bc4db6c5c2176588ce1cd885a5aa230 100644
--- a/core/misc/dialog/dialog.ajax.js
+++ b/core/misc/dialog/dialog.ajax.js
@@ -270,7 +270,9 @@
    * @param {object} [settings]
    *   Dialog settings.
    */
-  $(window).on('dialog:aftercreate', (e, dialog, $element, settings) => {
+  window.addEventListener('dialog:aftercreate', (event) => {
+    const $element = $(event.target);
+    const dialog = event.dialog;
     $element.on('click.dialog', '.dialog-cancel', (e) => {
       dialog.close('cancel');
       e.preventDefault();
@@ -288,7 +290,8 @@
    * @param {jQuery} $element
    *   jQuery collection of the dialog element.
    */
-  $(window).on('dialog:beforeclose', (e, dialog, $element) => {
+  window.addEventListener('dialog:beforeclose', (e) => {
+    const $element = $(e.target);
     $element.off('.dialog');
   });
 
diff --git a/core/misc/dialog/dialog.js b/core/misc/dialog/dialog.js
index 597ffde1ddf84a4aa3933d42adbe35d56e1805d3..76a0deea25b9b981970d0d6c54dc29d414bc4ee7 100644
--- a/core/misc/dialog/dialog.js
+++ b/core/misc/dialog/dialog.js
@@ -5,6 +5,14 @@
  * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#the-dialog-element
  */
 
+class DrupalDialogEvent extends Event {
+  constructor(type, dialog, settings = null) {
+    super(`dialog:${type}`, { bubbles: true });
+    this.dialog = dialog;
+    this.settings = settings;
+  }
+}
+
 (function ($, Drupal, drupalSettings, bodyScrollLock) {
   /**
    * Default dialog options.
@@ -59,7 +67,10 @@
    */
   Drupal.dialog = function (element, options) {
     let undef;
+
     const $element = $(element);
+    const domElement = $element.get(0);
+
     const dialog = {
       open: false,
       returnValue: undef,
@@ -68,28 +79,33 @@
     function openDialog(settings) {
       settings = $.extend({}, drupalSettings.dialog, options, settings);
       // Trigger a global event to allow scripts to bind events to the dialog.
-      $(window).trigger('dialog:beforecreate', [dialog, $element, settings]);
-      $element.dialog(settings);
+      const event = new DrupalDialogEvent('beforecreate', dialog, settings);
+      domElement.dispatchEvent(event);
+      $element.dialog(event.settings);
       dialog.open = true;
 
       // Locks the body scroll only when it opens in modal.
       if (settings.modal) {
         // Locks the body when the dialog opens.
-        bodyScrollLock.lock($element.get(0));
+        bodyScrollLock.lock(domElement);
       }
 
-      $(window).trigger('dialog:aftercreate', [dialog, $element, settings]);
+      domElement.dispatchEvent(
+        new DrupalDialogEvent('aftercreate', dialog, settings),
+      );
     }
 
     function closeDialog(value) {
-      $(window).trigger('dialog:beforeclose', [dialog, $element]);
+      domElement.dispatchEvent(new DrupalDialogEvent('beforeclose', dialog));
+
       // Unlocks the body when the dialog closes.
       bodyScrollLock.clearBodyLocks();
 
       $element.dialog('close');
       dialog.returnValue = value;
       dialog.open = false;
-      $(window).trigger('dialog:afterclose', [dialog, $element]);
+
+      domElement.dispatchEvent(new DrupalDialogEvent('afterclose', dialog));
     }
 
     dialog.show = () => {
diff --git a/core/misc/dialog/dialog.position.js b/core/misc/dialog/dialog.position.js
index 8864496cb0798f1fe3e9ba1c63d8c5c8e61c2bb2..9c1060f3cacbc80f505872e0534a83834de61a0a 100644
--- a/core/misc/dialog/dialog.position.js
+++ b/core/misc/dialog/dialog.position.js
@@ -113,28 +113,30 @@
       .trigger('dialogContentResize');
   }
 
-  $(window).on({
-    'dialog:aftercreate': function (event, dialog, $element, settings) {
-      const autoResize = debounce(resetSize, 20);
-      const eventData = { settings, $element };
-      if (settings.autoResize === true || settings.autoResize === 'true') {
-        const uiDialog = $element
-          .dialog('option', { resizable: false, draggable: false })
-          .dialog('widget');
-        uiDialog[0].style.position = 'fixed';
-        $(window)
-          .on('resize.dialogResize scroll.dialogResize', eventData, autoResize)
-          .trigger('resize.dialogResize');
-        $(document).on(
-          'drupalViewportOffsetChange.dialogResize',
-          eventData,
-          autoResize,
-        );
-      }
-    },
-    'dialog:beforeclose': function (event, dialog, $element) {
-      $(window).off('.dialogResize');
-      $(document).off('.dialogResize');
-    },
+  window.addEventListener('dialog:aftercreate', (e) => {
+    const autoResize = debounce(resetSize, 20);
+    const $element = $(e.target);
+    const { settings } = e;
+    const eventData = { settings, $element };
+
+    if (settings.autoResize === true || settings.autoResize === 'true') {
+      const uiDialog = $element
+        .dialog('option', { resizable: false, draggable: false })
+        .dialog('widget');
+      uiDialog[0].style.position = 'fixed';
+      $(window)
+        .on('resize.dialogResize scroll.dialogResize', eventData, autoResize)
+        .trigger('resize.dialogResize');
+      $(document).on(
+        'drupalViewportOffsetChange.dialogResize',
+        eventData,
+        autoResize,
+      );
+    }
+  });
+
+  window.addEventListener('dialog:beforeclose', () => {
+    $(window).off('.dialogResize');
+    $(document).off('.dialogResize');
   });
 })(jQuery, Drupal, drupalSettings, Drupal.debounce, Drupal.displace);
diff --git a/core/misc/dialog/off-canvas/js/off-canvas.js b/core/misc/dialog/off-canvas/js/off-canvas.js
index a85f3522ab8db72e0e355d0aa2be4df198031870..2517c3cd7757dc6b8930c1a88ce4324eb052c2dc 100644
--- a/core/misc/dialog/off-canvas/js/off-canvas.js
+++ b/core/misc/dialog/off-canvas/js/off-canvas.js
@@ -341,23 +341,39 @@
       if (!once('off-canvas', 'html').length) {
         return;
       }
-      $(window).on({
-        'dialog:beforecreate': (event, dialog, $element, settings) => {
-          if (Drupal.offCanvas.isOffCanvas($element)) {
-            Drupal.offCanvas.beforeCreate({ dialog, $element, settings });
-          }
-        },
-        'dialog:aftercreate': (event, dialog, $element, settings) => {
-          if (Drupal.offCanvas.isOffCanvas($element)) {
-            Drupal.offCanvas.render({ dialog, $element, settings });
-            Drupal.offCanvas.afterCreate({ $element, settings });
-          }
-        },
-        'dialog:beforeclose': (event, dialog, $element) => {
-          if (Drupal.offCanvas.isOffCanvas($element)) {
-            Drupal.offCanvas.beforeClose({ dialog, $element });
-          }
-        },
+
+      window.addEventListener('dialog:beforecreate', (e) => {
+        const $element = $(e.target);
+        if (Drupal.offCanvas.isOffCanvas($element)) {
+          Drupal.offCanvas.beforeCreate({
+            $element,
+            settings: e.settings,
+          });
+        }
+      });
+
+      window.addEventListener('dialog:aftercreate', (e) => {
+        const $element = $(e.target);
+        if (Drupal.offCanvas.isOffCanvas($element)) {
+          Drupal.offCanvas.render({
+            $element,
+            dialog: e.dialog,
+            settings: e.settings,
+          });
+          Drupal.offCanvas.afterCreate({
+            $element,
+            settings: e.settings,
+          });
+        }
+      });
+
+      window.addEventListener('dialog:beforeclose', (e) => {
+        const $element = $(e.target);
+        if (Drupal.offCanvas.isOffCanvas($element)) {
+          Drupal.offCanvas.beforeClose({
+            $element,
+          });
+        }
       });
     },
   };
diff --git a/core/modules/ckeditor5/js/ckeditor5.js b/core/modules/ckeditor5/js/ckeditor5.js
index 7bace8702c0f55fe3ef7ae061cd1f22c9a5bfcb6..f2c69f41b48a094ee04dff6737376ea809c19cae 100644
--- a/core/modules/ckeditor5/js/ckeditor5.js
+++ b/core/modules/ckeditor5/js/ckeditor5.js
@@ -650,7 +650,7 @@
   );
 
   // Respond to new dialogs that are opened by CKEditor, closing the AJAX loader.
-  $(window).on('dialog:beforecreate', () => {
+  window.addEventListener('dialog:beforecreate', () => {
     const dialogLoading = document.querySelector('.ckeditor5-dialog-loading');
 
     if (dialogLoading) {
@@ -673,7 +673,7 @@
   });
 
   // Respond to dialogs that are closed, removing the current save handler.
-  $(window).on('dialog:afterclose', () => {
+  window.addEventListener('dialog:afterclose', () => {
     if (Drupal.ckeditor5.saveCallback) {
       Drupal.ckeditor5.saveCallback = null;
     }
diff --git a/core/modules/layout_builder/js/layout-builder.js b/core/modules/layout_builder/js/layout-builder.js
index ef85ad8533e20230613d514ee8538b47e8958334..bf5b24ac2a9391f678369b28a667c7ae98bcebe0 100644
--- a/core/modules/layout_builder/js/layout-builder.js
+++ b/core/modules/layout_builder/js/layout-builder.js
@@ -219,7 +219,8 @@
   };
 
   // After a dialog opens, highlight element that the dialog is acting on.
-  $(window).on('dialog:aftercreate', (event, dialog, $element) => {
+  window.addEventListener('dialog:aftercreate', (e) => {
+    const $element = $(e.target);
     if (Drupal.offCanvas.isOffCanvas($element)) {
       // Start by removing any existing highlighted elements.
       $('.is-layout-builder-highlighted').removeClass(
@@ -309,7 +310,8 @@
     });
   }
 
-  $(window).on('dialog:afterclose', (event, dialog, $element) => {
+  window.addEventListener('dialog:afterclose', (e) => {
+    const $element = $(e.target);
     if (Drupal.offCanvas.isOffCanvas($element)) {
       // Remove the highlight from all elements.
       $('.is-layout-builder-highlighted').removeClass(
diff --git a/core/modules/media_library/js/media_library.ui.js b/core/modules/media_library/js/media_library.ui.js
index 07023660ad7d885a05a3d783e124133e7111f8e9..05429560f4e64243af5d337f50399fabee333b58 100644
--- a/core/modules/media_library/js/media_library.ui.js
+++ b/core/modules/media_library/js/media_library.ui.js
@@ -382,7 +382,7 @@
       if (!once('media-library-selection-info', 'html').length) {
         return;
       }
-      $(window).on('dialog:aftercreate', () => {
+      window.addEventListener('dialog:aftercreate', () => {
         // Since the dialog HTML is not part of the context, we can't use
         // context here.
         const $buttonPane = $(
@@ -410,7 +410,7 @@
       if (!once('media-library-clear-selection', 'html').length) {
         return;
       }
-      $(window).on('dialog:afterclose', () => {
+      window.addEventListener('dialog:afterclose', () => {
         Drupal.MediaLibrary.currentSelection = [];
       });
     },
diff --git a/core/modules/settings_tray/js/settings_tray.js b/core/modules/settings_tray/js/settings_tray.js
index 70e5df5a40a9e6a48a304ba07f1c3fe625319c07..5b627eafc4731d810a5c1f34331ef1f7f64f176c 100644
--- a/core/modules/settings_tray/js/settings_tray.js
+++ b/core/modules/settings_tray/js/settings_tray.js
@@ -237,24 +237,22 @@
   };
 
   // Manage Active editable class on opening and closing of the dialog.
-  $(window).on({
-    'dialog:beforecreate': (event, dialog, $element, settings) => {
-      if ($element[0].id === 'drupal-off-canvas') {
-        $('body .settings-tray-active-editable').removeClass(
-          'settings-tray-active-editable',
-        );
-        const $activeElement = $(`#${settings.settingsTrayActiveEditableId}`);
-        if ($activeElement.length) {
-          $activeElement.addClass('settings-tray-active-editable');
-        }
-      }
-    },
-    'dialog:beforeclose': (event, dialog, $element) => {
-      if ($element[0].id === 'drupal-off-canvas') {
-        $('body .settings-tray-active-editable').removeClass(
-          'settings-tray-active-editable',
-        );
+  window.addEventListener('dialog:beforecreate', (e) => {
+    if (e.target.id === 'drupal-off-canvas') {
+      $('body .settings-tray-active-editable').removeClass(
+        'settings-tray-active-editable',
+      );
+      const $activeElement = $(`#${e.settings.settingsTrayActiveEditableId}`);
+      if ($activeElement.length) {
+        $activeElement.addClass('settings-tray-active-editable');
       }
-    },
+    }
+  });
+  window.addEventListener('dialog:beforeclose', (e) => {
+    if (e.target.id === 'drupal-off-canvas') {
+      $('body .settings-tray-active-editable').removeClass(
+        'settings-tray-active-editable',
+      );
+    }
   });
 })(jQuery, Drupal);
diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js
index ece513c13f65ae087f462a52178af27f7d2f6f3e..ed741a374b185d5073b0df3b4e2bc2a8547bc255 100644
--- a/core/modules/toolbar/js/toolbar.js
+++ b/core/modules/toolbar/js/toolbar.js
@@ -205,34 +205,35 @@
           });
         }
 
-        $(window).on({
-          'dialog:aftercreate': (event, dialog, $element, settings) => {
-            const toolbarBar = document.getElementById('toolbar-bar');
-            if (toolbarBar) {
-              toolbarBar.style.marginTop = '0';
+        window.addEventListener('dialog:aftercreate', (e) => {
+          const $element = $(e.target);
+          const { settings } = e;
+          const toolbarBar = document.getElementById('toolbar-bar');
+          if (toolbarBar) {
+            toolbarBar.style.marginTop = '0';
 
-              // When off-canvas is positioned in top, toolbar has to be moved down.
-              if (settings.drupalOffCanvasPosition === 'top') {
-                const height = Drupal.offCanvas
+            // When off-canvas is positioned in top, toolbar has to be moved down.
+            if (settings.drupalOffCanvasPosition === 'top') {
+              const height = Drupal.offCanvas
+                .getContainer($element)
+                .outerHeight();
+              toolbarBar.style.marginTop = `${height}px`;
+
+              $element.on('dialogContentResize.off-canvas', () => {
+                const newHeight = Drupal.offCanvas
                   .getContainer($element)
                   .outerHeight();
-                toolbarBar.style.marginTop = `${height}px`;
-
-                $element.on('dialogContentResize.off-canvas', () => {
-                  const newHeight = Drupal.offCanvas
-                    .getContainer($element)
-                    .outerHeight();
-                  toolbarBar.style.marginTop = `${newHeight}px`;
-                });
-              }
+                toolbarBar.style.marginTop = `${newHeight}px`;
+              });
             }
-          },
-          'dialog:beforeclose': () => {
-            const toolbarBar = document.getElementById('toolbar-bar');
-            if (toolbarBar) {
-              toolbarBar.style.marginTop = '0';
-            }
-          },
+          }
+        });
+
+        window.addEventListener('dialog:beforeclose', () => {
+          const toolbarBar = document.getElementById('toolbar-bar');
+          if (toolbarBar) {
+            toolbarBar.style.marginTop = '0';
+          }
         });
       });
 
diff --git a/core/modules/views_ui/js/dialog.views.js b/core/modules/views_ui/js/dialog.views.js
index 48a0b8eb88c62342ac3f74e8ef56b54ff46f912c..4cc4c5e7c248b31065e67127fcd932198148ab9e 100644
--- a/core/modules/views_ui/js/dialog.views.js
+++ b/core/modules/views_ui/js/dialog.views.js
@@ -81,7 +81,8 @@
    * @param {jQuery} $element
    *   The jQuery collection of the dialog element.
    */
-  $(window).on('dialog:aftercreate', (e, dialog, $element) => {
+  window.addEventListener('dialog:aftercreate', (e) => {
+    const $element = $(e.target);
     const $scroll = $element.find('.scroll');
     if ($scroll.length) {
       bodyScrollLock.unlock($element.get(0));
diff --git a/core/themes/claro/js/media-library.ui.js b/core/themes/claro/js/media-library.ui.js
index 8eee2ad1fe18f7da30e5f4333ec9725d349a12f3..6767a3628cdaff78576b861e3d911e8631a1b897 100644
--- a/core/themes/claro/js/media-library.ui.js
+++ b/core/themes/claro/js/media-library.ui.js
@@ -20,53 +20,51 @@
       if (!once('media-library-selection-info-claro-event', 'html').length) {
         return;
       }
-      $(window).on(
-        'dialog:aftercreate',
-        (event, dialog, $element, settings) => {
-          // Since the dialog HTML is not part of the context, we can't use
-          // context here.
-          const moveCounter = ($selectedCount, $buttonPane) => {
-            const $moveSelectedCount = $selectedCount.detach();
-            $buttonPane.prepend($moveSelectedCount);
-          };
+      window.addEventListener('dialog:aftercreate', (e) => {
+        const $element = $(e.target);
+        // Since the dialog HTML is not part of the context, we can't use
+        // context here.
+        const moveCounter = ($selectedCount, $buttonPane) => {
+          const $moveSelectedCount = $selectedCount.detach();
+          $buttonPane.prepend($moveSelectedCount);
+        };
 
-          const $buttonPane = $element
-            .closest('.media-library-widget-modal')
-            .find('.ui-dialog-buttonpane');
-          if (!$buttonPane.length) {
-            return;
-          }
-          const $selectedCount = $buttonPane.find(
-            '.js-media-library-selected-count',
-          );
+        const $buttonPane = $element
+          .closest('.media-library-widget-modal')
+          .find('.ui-dialog-buttonpane');
+        if (!$buttonPane.length) {
+          return;
+        }
+        const $selectedCount = $buttonPane.find(
+          '.js-media-library-selected-count',
+        );
 
-          // If the `selected` counter is already present, it can be moved from
-          // the end of the button pane to the beginning.
-          if ($selectedCount.length) {
-            moveCounter($selectedCount, $buttonPane);
-          } else {
-            // If the `selected` counter is not yet present, create a mutation
-            // observer that checks for items added to the button pane. As soon
-            // as the counter is added, move it from the end of the button pane
-            // to the beginning.
-            const selectedCountObserver = new MutationObserver(() => {
-              const $selectedCountFind = $buttonPane.find(
-                '.js-media-library-selected-count',
-              );
-              if ($selectedCountFind.length) {
-                moveCounter($selectedCountFind, $buttonPane);
-                selectedCountObserver.disconnect();
-              }
-            });
-            selectedCountObserver.observe($buttonPane[0], {
-              attributes: false,
-              childList: true,
-              characterData: false,
-              subtree: true,
-            });
-          }
-        },
-      );
+        // If the `selected` counter is already present, it can be moved from
+        // the end of the button pane to the beginning.
+        if ($selectedCount.length) {
+          moveCounter($selectedCount, $buttonPane);
+        } else {
+          // If the `selected` counter is not yet present, create a mutation
+          // observer that checks for items added to the button pane. As soon
+          // as the counter is added, move it from the end of the button pane
+          // to the beginning.
+          const selectedCountObserver = new MutationObserver(() => {
+            const $selectedCountFind = $buttonPane.find(
+              '.js-media-library-selected-count',
+            );
+            if ($selectedCountFind.length) {
+              moveCounter($selectedCountFind, $buttonPane);
+              selectedCountObserver.disconnect();
+            }
+          });
+          selectedCountObserver.observe($buttonPane[0], {
+            attributes: false,
+            childList: true,
+            characterData: false,
+            subtree: true,
+          });
+        }
+      });
     },
   };
 })(jQuery, Drupal, window);