diff --git a/bower.json b/bower.json
index 362ee25ea78945692e8bae9fd1d74efcbe15e1cd..8aa20b7d0850f18fa1adef0d324f4e96962c1ced 100644
--- a/bower.json
+++ b/bower.json
@@ -15,7 +15,7 @@
   ],
   "dependencies": {
     "leaflet": "~0.7.7",
-    "jquery": "~2.1.4",
+    "jquery": "~2.2.3",
     "leaflet.markercluster": "~0.4.0",
     "leaflet-marker-rotate": "https://git.xhost.io/anton/leaflet-marker-rotate.git",
     "Leaflet.label": "~0.2.1"
diff --git a/static/js/embed.js b/static/js/embed.js
index 0096c7988c8d428e5b57d2fdab193ca92eea7dd3..4fa38ab1a71e8cf3000c0f90de0e53a60013e1e5 100644
--- a/static/js/embed.js
+++ b/static/js/embed.js
@@ -47,28 +47,28 @@ BusMap.Embed = function(opts) {
 
     var bindEventHandlers = function() {
         // OnChange event handlers for Embed Options form
-        $("#embed-height").change(function() {
+        $("#embed-height").on('change', function() {
             if ($(this).val() != "") {
                 $("#embed-preview iframe").attr('height', $(this).val() + "px");
             } else {
                 $("#embed-preview iframe").removeAttr('height');
             }
         });
-        $("#embed-width").change(function() {
+        $("#embed-width").on('change', function() {
             if ($(this).val() != "") {
                 $("#embed-preview iframe").attr('width', $(this).val() + "px");
             } else {
                 $("#embed-preview iframe").removeAttr('width');
             }
         });
-        $("#embed-responsive").change(function() {
+        $("#embed-responsive").on('change', function() {
             if ($(this).prop("checked")) {
                 $("#embed-preview iframe").css('max-width', '100%');
             } else {
                 $("#embed-preview iframe").css('max-width', '');
             }
         });
-        $("#embed-mode").change(function() {
+        $("#embed-mode").on('change', function() {
             embedVars['mode'] = $(this).val();
             updateEmbedUrl();
             if ($(this).val() == "m") {
@@ -77,7 +77,7 @@ BusMap.Embed = function(opts) {
                 $("label[for=embed-popup]").hide();
             }
         });
-        $("#embed-stop").change(function() {
+        $("#embed-stop").on('change', function() {
             if ($(this).val()) {
                 embedVars['stop'] = $(this).val();
             } else {
@@ -85,7 +85,7 @@ BusMap.Embed = function(opts) {
             }
             updateEmbedUrl();
         });
-        $("#embed-popup").change(function() {
+        $("#embed-popup").on('change', function() {
             if ($(this).prop("checked")) {
                 embedVars['popup'] = true;
             } else {
@@ -94,7 +94,7 @@ BusMap.Embed = function(opts) {
             updateEmbedUrl();
         });
         // After ANY field is updated...
-        $("#embed-form :input").change(function() {
+        $("#embed-form :input").on('change', function() {
             updateEmbedCode();
         });
         // Hilight code for easy copying on click, key, focus.
diff --git a/static/js/map.js b/static/js/map.js
index ed54ce9f5be804289890e395c092e2e9acc9730a..fdedad74c5a6a521da85d10eb50c4f7e775a11dc 100644
--- a/static/js/map.js
+++ b/static/js/map.js
@@ -454,8 +454,15 @@ BusMap.Map = function(opts) {
             var modalName = $(".modal").attr('id').split('-')[1];
             view += ";" + modalName;
         }
+        if (window.location.hash == "#" + view) {
+            // Bail out if old hash == new hash.
+            // Otherwise, we'll set hashChangedProgrammatically, but
+            // the change handler will never fire, and it won't be unset.
+            // TODO: unfuck this bad design before it breaks something else
+            return;
+        }
         that.hashChangedProgrammatically = true; // avoid infinite loop!
-        window.location.replace("#" + view);
+        window.location.href.replace(window.location.hash, "#" + view);
     }
 
     init();