Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome Extension - first link is auto-focused in popup

How do I stop my Google Chrome extension's default action to auto-focus the first link in my popup.html? I know I could probably do some roundabout hack with JS or change the :focus CSS, but I think this is throwing off something else I'm trying to do and I'd prefer to stop the root cause of it.

like image 525
Ryan Grush Avatar asked May 22 '13 20:05

Ryan Grush


3 Answers

The easiest (and javascript free!) way is to simply add tabindex="-1" to any element which you don't want to receive automatic focus.

like image 58
Paul Ferrett Avatar answered Sep 19 '22 10:09

Paul Ferrett


Perhaps auto-focus was intended for a convenience, but often it does a disservice. Since I see no way to stop the root cause, I found some roundabouts. One is using JavaScript. Chrome puts auto-focus after a short delay after displaying the popup. It's possible to unfocus it with blur() but unfocusing it too late will flash it momentarily, and trying to unfocus too early will do nothing. So to find the right time to unfocus is not easy, and this solution tries to do this several times during the first second after the popup is displayed:

document.addEventListener("DOMContentLoaded", function () {
  var blurTimerId = window.setInterval(function() {
    if (document.activeElement != document.body) {
      document.activeElement.blur();
    }
  }, 200);
  window.setTimeout(function() {
    window.clearInterval(blurTimerId);
  }, 1000);
});

Another pure HTML solution is to add tabindex="1" to the body tag.

like image 27
link0ff Avatar answered Sep 18 '22 10:09

link0ff


Wrangling the initially focused element with a tabindex attribute is probably the best way to go, using:

  • tabindex="-1", as suggested by Paul Ferret to prevent an element from getting focus
  • tabindex="1", as suggested by link0ff, to specify which element should start with focus

If your situation is more complicated and you do want to bring in some javascript, I'd recommend using link0ff's solution, except, instead of trying to guess when to blur with timeouts, listen for the initial focus in event:

function onInitialFocus(event) {
  // Any custom behavior your want to perform when the initial element is focused.

  // For example: If this is an anchor tag, remove focus
  if (event.target.tagName == "A") {
    event.target.blur();
  }

  // ALSO, remove this event listener after it is triggered,
  // so it's not applied to subsequent focus events
  document.removeEventListener("focusin", onInitialFocus);
}

// NOTE: the "focusin" event bubbles up to the document,
// but the "focus" event does not.
document.addEventListener("focusin", onInitialFocus);

I don't believe the focus event is cancelable, so you can't just suppress the event.

like image 22
TheMadDeveloper Avatar answered Sep 22 '22 10:09

TheMadDeveloper