Использовать расширение Chrome, чтобы отменить привязку событий клика? - PullRequest
4 голосов
/ 03 апреля 2011

Я пытаюсь создать расширение, которое отменяет привязку события клика, добавленного самим сайтом.

Сайт использует jQuery, что сделает это безумно простым:

jQuery('a[rel]').unbind('click');

Проблема в том, что мое расширение (использующее "content_scripts") не может получить доступ к объекту jQuery веб-сайта и, следовательно, не имеет функций событий для отсоединения. Я могу включить jQuery в свое расширение, но это не поможет, потому что jQuery хранит «данные» в объекте jQuery (а не в элементах DOM). Мой jQuery не будет хранить эти события.

Есть ли другой способ? Это не должно быть красиво. Может быть, без "content_scripts"?

Ответы [ 2 ]

4 голосов
/ 24 апреля 2011
var unbind_event_listeners = function (node) {
    var parent = node.parentNode;
    if (parent) {
        parent.replaceChild(node.cloneNode(true), node);
    } else {
        var ex = new Error("Cannot remove event listeners from detached or document nodes");
        ex.code = DOMException[ex.name = "HIERARCHY_REQUEST_ERR"];
        throw ex;
    }
};

Просто позвоните unbind_event_listeners(a_node), чтобы отсоединить слушателей от узла.Это будет работать на каждом узле документа, кроме самого document.Что касается window, вам не повезло.unbind_event_listeners(document.documentElement) должен удалить большинство прослушивателей событий, прикрепленных к узлам в документе.

В случае a[rel] вы захотите сделать это:

var nodes = document.querySelectorAll("a[rel]"), i = nodes.length;
while (i--) {
    unbind_event_listeners(nodes.item(i));
}
0 голосов
/ 21 апреля 2011

Если это не обязательно должно быть красиво, и вы можете делать что-то вроде хака, это должно принудительно отменить привязку каждого прослушивателя кликов, привязанного к этому элементу:

var el = document.querySelector('a[rel]');
el.onclick = function() {};
el.addEventListener = function() {};

или для каждого элемента:

Array.prototype.slice.call(document.querySelectorAll('a[rel]')).forEach(function(el) {
  el.onclick = function() {};
  el.addEventListener = function() {};
});

РЕДАКТИРОВАТЬ: Возможно, вы могли бы сделать что-то еще более уродливым и запустить скрипт содержимого в "document_start" и сделать:

Element.prototype.addEventListener = (function() {
  var real = Element.prototype.addEventListener;
  return function(ev) {
    if (ev === 'click' && this.tagName === 'A' && this.hasAttribute('rel')) {
      console.log('try again, jquery!');
    } else {
      return real.apply(this, arguments);
    }
  };
})();
...