7b392cbce42b3629202ba2934040c53cc52ce244
chmalee
  Wed Oct 29 14:57:30 2025 -0700
Prevent multiple click events from happening for each gear/x button, refs #36620

diff --git src/hg/js/utils.js src/hg/js/utils.js
index bf776f59a68..cf9f4e26544 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -3846,30 +3846,31 @@
         if (id.length > 0) {
             if ( ! imageV2.lastTrack || imageV2.lastTrack.id !== id) {
                 imageV2.lastTrack = rightClick.makeMapItem(id);
                 // currentMapItem gets set by mapItemMapOver.   This is just backup
             }
 
             if (typeof greyBarIcons !== 'undefined' && greyBarIcons === true) {
                 // show the gear icon over the grey bar to bring up the context menu
                 let tdBtn = document.getElementById("td_btn_" + id);
                 if (tdBtn) {
                     let span = document.getElementById("gear_btn_" + id);
                     if (span) {
                         // hide any gears that may be present from dragging
                         $(document.querySelectorAll("[id^=gear_btn]")).hide();
                         $(span).show();
+                        if (!span.dataset.alreadySetup) {
                             tdBtn.style.position = "relative";
                             let tdbKey = tdBtn.id.replace("td_btn_","");
                             let tdb = hgTracks.trackDb[tdbKey];
                             let tooltip = " click or right click to configure... drag to reorder";
                             if (typeof tdb.parentLabel !== 'undefined') {
                                 addMouseover(span, tdb.parentLabel + tooltip + " highlighted subtracks");
                             } else {
                                 addMouseover(span, tdb.shortLabel + tooltip);
                             }
                             span.addEventListener("click", (e) => {
                                 // trigger a click on the <a> of the td
                                 e.preventDefault();
                                 e.stopPropagation();
                                 e.stopImmediatePropagation();
                                 const clickEvent = new MouseEvent("click", {
@@ -3880,56 +3881,63 @@
                                     clientY: tdBtn.getBoundingClientRect().top,
                                     button: 1,
                                 });
                                 tdBtn.children[0].dispatchEvent(clickEvent);
                             });
                             let tdp = tdBtn.querySelector("p.btn");
                             if (tdp) {
                                 span.addEventListener("pointerenter", (e) => {
                                     // trigger a mouseover on the actual btn
                                     dragReorder.buttonMouseOver.call(tdp, e);
                                 });
                                 span.addEventListener("pointerleave", (e) => {
                                     dragReorder.buttonMouseOut.call(tdp, e);
                                 });
                             }
+                            // prevent attaching multiple events every time the tr is moused over
+                            span.dataset.alreadySetup = "true";
+                        }
                     }
                 }
 
                 // add an 'x' icon in the label area to hide the track
                 let tdSide = document.getElementById("td_side_" + id);
                 if (tdSide) {
                     // mouseover event fires if you stop moving the mouse while still
                     // hovering the element and then move it again, don't make
                     // duplicate btns in that case
                     let btn = document.getElementById("close_btn_" + id);
                     if (btn) {
                         // hide any shown 'x' buttons from dragging
                         $(document.querySelectorAll("[id^=close_btn]")).hide();
                         $(btn).show();
+                        if (!btn.dataset.alreadySetup) {
                             addMouseover(btn, btn.title);
                             tdSide.style.position = "relative";
                             if (hgTracks && hgTracks.revCmplDisp) {
                                 // set up 'x' icon to the right
                                 btn.classList.add("hgTracksCloseIconRight");
                             } else {
                                 // set up 'x' icon to the left
                                 btn.classList.add("hgTracksCloseIconLeft");
                             }
                             btn.addEventListener("click", (e) => {
                                rightClick.hideTracks([id]);
                             });
+                            // prevent attaching multiple events every time the tr is moused over
+                            btn.dataset.alreadySetup = "true";
+                        }
                     }
                 }
             }
         }
     },
 
     trMouseLeave: function(e)
     {
         var id = '';
         var a = /tr_(.*)/.exec($(this).attr('id'));  // voodoo
         if (a && a[1]) {
             id = a[1];
         }
         if (id.length > 0) {
             // hide 'x' icon in the label area to hide the track