jQuery $(document).off() not working in Chrome extension

坚强是说给别人听的谎言 提交于 2019-12-18 09:31:53

问题


I've created a Chrome Extension based on https://thoughtbot.com/blog/how-to-make-a-chrome-extension (look at the end for the completed files)

I've made two changes: I used jQuery 3.1.1 minimized instead of the older one given in the page above, and I changed content.js:

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if( request.message === "clicked_browser_action" ) {
            $(document).off("touchmove mousewheel mousemove scroll");
        }
    }
);

The $(document).off() command is not working when I click the extension's button with an appropriate test page opened. It doesn't give an error, it just doesn't do anything.

I've checked. If I type $(document).off("touchmove mousewheel mousemove scroll"); into the console on the page I want to affect, it works fine. If run in the extension it isn't.

I tried checking that document was correct in the extension, and document.domain gives the correct result when checked in a breakpoint in the extension (and in the console on the page).

I tried checking jQuery._data( jQuery(document)[0]).events["touchmove"] (and "mousewheel", "mousemove", "scroll") and it works in the console, but I get an error (Cannot read property 'touchmove' of undefined) if I breakpoint the extension. When I checked further, jQuery._data( jQuery(document)[0]) gives the following:

In console:

Object
    events: Object
    handle: function (e)
    __proto__: Object

In breakpoint:

Object
    __proto__: Object

I've tried a few other things (for example, that jQuery is accessible and working, and so on).


回答1:


You're attempting to execute $(document).off() in order to remove jQuery event handlers that were added by page scripts (scripts that already exist in the webpage; i.e. not your content script). jQuery stores which event handlers have been added in data structures internal to the jQuery instance being used. Your content script is in a different context/scope from that of page scripts. Thus, when you execute $(document).off() in the context of your content script, that jQuery instance isn't aware of any of the even handlers which have been added by the page scripts and can't remove them.

For your $(document).off() to be effective, it must be run in the page script context. The most common way to have code execute in the page script context is to create and insert a <script> element to the page's DOM.

You could change your code to:

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if( request.message === "clicked_browser_action" ) {
            let newScript = document.createElement('script');
            newScript.innerHTML='$(document).off("touchmove mousewheel mousemove scroll");';
            document.head.appendChild(newScript);
        }
    }
);

The added script gets run in the page context because it's now a <script> element in the DOM. The browser recognizes that a <script> element was added and evaluates it (executes the code contained) as soon as the script which inserted it is no longer processing. It does basically the same thing for any other element you add to the DOM. Because it is part of the page, the code inside the <script> gets run in the page script context/scope.

While the above works, particularly for such short code, my preferred method of creating <script> elements to execute code in the page context is to use a function I wrote called executeInPage(). You can find that function in my answer to "Calling webpage JavaScript methods from browser extension".



来源:https://stackoverflow.com/questions/40320529/jquery-document-off-not-working-in-chrome-extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!