开发者

How can I avoid having the focus moved to the Google search bar in a Chrome extension?

I'm writing an extension for Chrome with a few of the functions I find most useful in the vimperator plugin for Firefox.

Currently I'm having some trouble capturing keystrokes before the web page does. The "easiest" example is google.com. When I type something without having the focus in the search field the field is automatically selected and whatever text I enter is entered into the field.

Essentially I want to stop this behavior so that when I press a button the focus is not moved to the search field. (After that I want the extension to react according to what key was pressed, but I already have this working more or less, if I can stop the focus from being moved.)

So far I have tried various combinations of removeEventListener() and jQuery unbind() and a few other things (or mad guesses, if you like) in the content script of my extension, but no luck so far. The focus is still moved to the search field when an alphanumeric key is pressed. Does anyone have any suggestions about how this can be done or where I could look for an answer?

I do apologize of this has been asked before, but I was unable to get any help from any of the questions I found.

PS: If you should be interested in some more context the code I have so far can be found here . But I should think 开发者_运维百科that the question can be answered without anyone having to get a headache from looking at this (mess).


After reading up on the element.focus() method, I wrote the following code to blur elements that were focused by the document before the focus() call returns to the event loop.

The idea is that we add a focus listener to every element, and then remove the focus listener after onload so that websites that call focus() after a user event (such as jsfiddle.com or the Google results page) will still work properly after the page has loaded.

Caveat: I haven't been able to figure out how to get Chrome to disable autofocus fields though.

Content script (call it unfocus.js):

document.addEventListener('DOMNodeInsertedIntoDocument', onInsertedIntoDocument, true);
document.addEventListener('DOMNodeRemovedFromDocument', onRemovedFromDocument, true);
window.addEventListener('load', function(e) {
  setTimeout(function() {
    removeOnFocus(document.documentElement);
    document.removeEventListener('DOMNodeInsertedIntoDocument', onInsertedIntoDocument, true);
    document.removeEventListener('DOMNodeRemovedFromDocument', onRemovedFromDocument, true);
  }, 1);
}, false);


// Whenever an element is inserted into document, listen for
// simple event named 'focus'.
function onInsertedIntoDocument(e) {
  var elt = e.target;
  if (elt.nodeType === 1)
    elt.addEventListener('focus', onfocus, false);
}
function onRemovedFromDocument(e) {
  var elt = e.target;
  if (elt.nodeType === 1)
      removeOnFocus(elt);
}
function onfocus(e) {
  // In Chrome, caller is null if the user initiated the focus,
  // and non-null if the focus was caused by a call to element.focus().
  var causedByUser = (onfocus.caller == null);

  console.log('onfocus ' + e.target.nodeName +
      ': caused by user? ' +causedByUser +
      (e.target.autofocus ? ' autofocus' : ''));

  if (! causedByUser) {
    e.target.blur();
  }
}
// Clean up by removing all the 'focus' event listeners.
function removeOnFocus(elt) {
  elt.removeEventListener('focus', onfocus, false);
  for (var i = 0; i < elt.children.length; i++)
    removeOnFocus(elt.children[i]);
}

And this manifest.json:

{
  "name": "unfocus",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "js": ["unfocus.js"],
      "run_at": "document_start"
    }
  ]
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜