diff --git a/google_analytics.libraries.yml b/google_analytics.libraries.yml
index 7bc8d17..d960850 100644
--- a/google_analytics.libraries.yml
+++ b/google_analytics.libraries.yml
@@ -3,7 +3,6 @@ google_analytics:
   js:
     js/google_analytics.js: {}
   dependencies:
-    - core/jquery
     - core/drupal
     - core/drupalSettings
 
diff --git a/js/google_analytics.js b/js/google_analytics.js
index e7ef09b..a83fd55 100644
--- a/js/google_analytics.js
+++ b/js/google_analytics.js
@@ -3,74 +3,77 @@
  * Attaches several event listener to a web page.
  */
 
-(function ($, Drupal, drupalSettings) {
+(function (Drupal, drupalSettings) {
 
   "use strict";
 
   Drupal.google_analytics = {};
 
-  $(document).ready(function () {
+  domready(function () {
 
     // Attach mousedown, keyup, touchstart events to document only and catch
     // clicks on all elements.
-    $(document.body).on("mousedown keyup touchstart", function (event) {
+    Drupal.google_analytics.addListenerMulti(document.body, 'mousedown keyup touchstart', function(event) {
 
       // Catch the closest surrounding link of a clicked element.
-      $(event.target).closest("a,area").each(function () {
+      var elementClicked = Drupal.google_analytics.getClosest(event.target, "a,area");
+
+      if (elementClicked !== null) {
+        var href = elementClicked.getAttribute('href');
+        var fullHref = elementClicked.href;
 
         // Is the clicked URL internal?
-        if (Drupal.google_analytics.isInternal(this.href)) {
+        if (Drupal.google_analytics.isInternal(fullHref)) {
           // Skip 'click' tracking, if custom tracking events are bound.
-          if ($(this).is('.colorbox') && (drupalSettings.google_analytics.trackColorbox)) {
+          if (elementClicked.className.indexOf("colorbox") > -1 && (drupalSettings.google_analytics.trackColorbox)) {
             // Do nothing here. The custom event will handle all tracking.
-            // console.info("Click on .colorbox item has been detected.");
           }
           // Is download tracking activated and the file extension configured
           // for download tracking?
-          else if (drupalSettings.google_analytics.trackDownload && Drupal.google_analytics.isDownload(this.href)) {
+          else if (drupalSettings.google_analytics.trackDownload && Drupal.google_analytics.isDownload(fullHref)) {
             // Download link clicked.
             ga("send", {
               "hitType": "event",
               "eventCategory": "Downloads",
-              "eventAction": Drupal.google_analytics.getDownloadExtension(this.href).toUpperCase(),
-              "eventLabel": Drupal.google_analytics.getPageUrl(this.href),
+              "eventAction": Drupal.google_analytics.getDownloadExtension(fullHref).toUpperCase(),
+              "eventLabel": Drupal.google_analytics.getPageUrl(fullHref),
               "transport": "beacon"
             });
           }
-          else if (Drupal.google_analytics.isInternalSpecial(this.href)) {
+          else if (Drupal.google_analytics.isInternalSpecial(fullHref)) {
             // Keep the internal URL for Google Analytics website overlay intact.
             ga("send", {
               "hitType": "pageview",
-              "page": Drupal.google_analytics.getPageUrl(this.href),
+              "page": Drupal.google_analytics.getPageUrl(fullHref),
               "transport": "beacon"
             });
           }
         }
         else {
-          if (drupalSettings.google_analytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
+          if (drupalSettings.google_analytics.trackMailto && href.indexOf('mailto') > -1) {
             // Mailto link clicked.
             ga("send", {
               "hitType": "event",
               "eventCategory": "Mails",
               "eventAction": "Click",
-              "eventLabel": this.href.substring(7),
+              "eventLabel": fullHref.substring(7),
               "transport": "beacon"
             });
           }
-          else if (drupalSettings.google_analytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
-            if (drupalSettings.google_analytics.trackDomainMode !== 2 || (drupalSettings.google_analytics.trackDomainMode === 2 && !Drupal.google_analytics.isCrossDomain(this.hostname, drupalSettings.google_analytics.trackCrossDomains))) {
+          else if (drupalSettings.google_analytics.trackOutbound && fullHref.match(/^\w+:\/\//i)) {
+            if (drupalSettings.google_analytics.trackDomainMode !== 2 || (drupalSettings.google_analytics.trackDomainMode === 2 && !Drupal.google_analytics.isCrossDomain(elementClicked.hostname, drupalSettings.google_analytics.trackCrossDomains))) {
               // External link clicked / No top-level cross domain clicked.
               ga("send", {
                 "hitType": "event",
                 "eventCategory": "Outbound links",
                 "eventAction": "Click",
-                "eventLabel": this.href,
+                "eventLabel": fullHref,
                 "transport": "beacon"
               });
             }
           }
         }
-      });
+      }
     });
 
     // Track hash changes as unique pageviews, if this option has been enabled.
@@ -86,7 +89,7 @@
     // Colorbox: This event triggers when the transition has completed and the
     // newly loaded content has been revealed.
     if (drupalSettings.google_analytics.trackColorbox) {
-      $(document).on("cbox_complete", function () {
+      document.addEventListener("cbox_complete", function () {
         var href = $.colorbox.element().attr("href");
         if (href) {
           ga("send", {
@@ -100,6 +103,47 @@
   });
 
   /**
+   * Helper function to add multiple event listeners.
+   *
+   * @param {string} selector
+   *   The selector to which we will attach events (single selector).
+   * @param {string} events
+   *   A string of events separated by a space
+   * @param {function} fn
+   *   The callback function
+   */
+  Drupal.google_analytics.addListenerMulti = function (selector, events, fn) {
+    var evts = events.split(' ');
+    for (var i=0, iLen=evts.length; i<iLen; i++) {
+      selector.addEventListener(evts[i], fn, false);
+    }
+  }
+
+  /**
+   * Get the closest matching element up the DOM tree.
+   * @param  {Element} elem
+   *     Starting element
+   * @param  {String} selector
+   *     Selector to match against (tag)
+   *
+   * @return {Boolean|Element} null or element
+   */
+  Drupal.google_analytics.getClosest = function (elem, selector) {
+    var selectors = selector.split(',');
+    // Get closest match
+    for ( ; elem && elem !== document && elem.nodeType === 1; elem = elem.parentNode ) {
+      for (var i = 0, len = selectors.length; i < len; i++) {
+        // If selector is a tag
+        if ( elem.tagName.toLowerCase() === selectors[i] ) {
+          return elem;
+        }
+      }
+      return null;
+    }
+    return null;
+  };
+
+  /**
    * Check whether the hostname is part of the cross domains or not.
    *
    * @param {string} hostname
@@ -110,7 +154,7 @@
    * @return {boolean} isCrossDomain
    */
   Drupal.google_analytics.isCrossDomain = function (hostname, crossDomains) {
-    return $.inArray(hostname, crossDomains) > -1 ? true : false;
+    return crossDomains.indexOf(hostname) > -1 ? true : false;
   };
 
   /**
@@ -188,4 +232,4 @@
     return (extension === null) ? '' : extension[1];
   };
 
-})(jQuery, Drupal, drupalSettings);
+})(Drupal, drupalSettings);
