How to retrieve the element where a contextmenu has been executed

17,380

You can inject content script with contextmenu event listener and store element that was clicked:

manifest.json

"content_scripts": [{
  "matches": ["<all_urls>"],
  "js": ["content.js"],
  "all_frames": true,
  "match_about_blank": true
}]

content script.js

//content script
var clickedEl = null;

document.addEventListener("contextmenu", function(event){
    clickedEl = event.target;
}, true);

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if(request == "getClickedEl") {
        sendResponse({value: clickedEl.value});
    }
});

background.js

//background
function mycallback(info, tab) {
    chrome.tabs.sendMessage(tab.id, "getClickedEl", {frameId: info.frameId}, data => {
        elt.value = data.value;
    });
}
Share:
17,380

Related videos on Youtube

Laurent
Author by

Laurent

I run some businesses: https://contentshowcase.app https://medicalid.app https://noticeable.io

Updated on June 04, 2022

Comments

  • Laurent
    Laurent almost 2 years

    I am trying to write a google chrome extension where I use a contextmenu. This contextmenu is available on editable elements only (input texts for example). When the contextmenu is clicked and executed I would like to retrieve in the callback function the element (the input text) on which the contextmenu has been executed in order to update the value associated to this input text.

    Here is the skeleton of my extension:

    function mycallback(info, tab) {
      // missing part that refers to the question:
      // how to retrieve elt which is assumed to be 
      // the element on which the contextMenu has been executed ?
      elt.value = "my new value"
    }
    
    var id = chrome.contextMenus.create({
            "title": "Click me",
            "contexts": ["editable"],
            "onclick": mycallback
        });
    

    The parameters associated to the mycallback function contain no useful information to retrieve the right clicked element. It seems this is a known issue (http://code.google.com/p/chromium/issues/detail?id=39507) but there is no progress since several months. Does someone knows a workaround: without jquery and/or with jquery?

    • c69
      c69 over 12 years
    • Laurent
      Laurent over 12 years
      Thanks for pointing this link to me but I have already seen this issue. I have tried the solution from comment #7 and by using document.activeElement I retrieve an HTMLBodyElement not the input text element on which the contextmenu has been executed. Also, the solution proposed by comment #14 with jquery does not work: I get a null value.
    • c69
      c69 over 12 years
      is your content script sending messages to background script ? is background listening ?
  • Laurent
    Laurent over 12 years
    Thanks a lot. The solution was to use a content script to retrieve and to alter the content of a field contained in the current tab. Indeed, the background script is isolated and has not access to the content of the current webpage. Then, from the content script it is possible to use document.activeElement
  • juanignaciosl
    juanignaciosl over 9 years
    onRequest and sendRequest are now deprecated. It should be onMessage and sendMessage.
  • rvighne
    rvighne almost 8 years
    Or even better, the contextmenu event. In which case you won't have to check event.button == 2
  • Derek 朕會功夫
    Derek 朕會功夫 almost 8 years
    If you only need focusable elements such as inputs, you can instead use document.activeElement.
  • thdoan
    thdoan about 7 years
    Keep in mind that the chrome.contextMenus.onClicked handler will always execute first, so you can run into situations where the user right-clicks before the page is finished loading (hence before mousedown handler is registered), so when they select from the context menu it will fail.
  • Aero Wang
    Aero Wang about 4 years
    I got Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
  • user776686
    user776686 over 3 years
    @AeroWang "Receiving end does not exist" usually happens in either case: (1) you forgot to reload the content page after reloading the extension (2) you are on a page that is not white listed for content_scripts in the manifest.