I am writing a Chrome extension which needs to be able to trigger keydown events at the document level of the target page. The target page has an event listener which uses javascript like:
document.addEventListener("keydown", function (event) {…});
My manifest.json is as follows:
{
"manifest_version": 2,
"name": "Title",
"version": "1.0",
"description": "Testing",
"icons": {
"default_icon": "icon.png"
},
"browser_action": {
"default_title": "Title"
},
"author": "James McLaughlin",
"background": {
"scripts": ["jquery.js", "event.js"],
"persistent": false
},
"permissions": ["<all_urls>"]
}
And my event.js:
function injectedMethod (tab, method, callback) {
chrome.tabs.executeScript(tab.id, {file: 'jquery.js'}, function() {});
chrome.tabs.executeScript(tab.id, {file: 'inject.js'}, function() {
chrome.tabs.sendMessage(tab.id, {method: method}, callback);
});
}
function run (tab) {
injectedMethod(tab, 'run', function (response) {
return true;
});
}
chrome.browserAction.onClicked.addListener(run);
And my inject.js (I used one of the methods of JS injection available here because it seemed applicable:
var injected = injected || (function(){
var methods = {};
methods.run = function () {
injectScript(function () {
var e = jQuery.Event("keydown");
e.which = 40;
$(document).trigger(e);
});
}
function injectScript(func) {
var actualCode = '(' + func + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.body||document.documentElement).appendChild(script);
//script.parentNode.removeChild(script);
}
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
$('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>').appendTo('head');
var data = {};
if (methods.hasOwnProperty(request.method))
data = methods[request.method]();
sendResponse({data:data});
return true;
});
return true;
})();
However, when I push the chrome extension, the target page does not respond to the keydown event. This got me thinking that perhaps a jQuery-generated event cannot trigger a pure JS listener. To test this theory, I put the following in an HTML file and ran it:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<script>
//listener one
document.addEventListener("keydown", function (event) {
alert(event.which);
});
//listener two
$(document).on('keydown', function (event) {
alert(event.which);
});
$(document).ready(function(e) {
var e = jQuery.Event("keydown");
e.which = 40;
$(document).trigger(e);
});
</script>
</body>
</html>
When I ran the above html file, only the jQuery event listener was fired. When I commented out the jQuery listener, nothing happened. Furthermore, when I commented out the JS listener and uncommented the JS listener, the jQuery event listener fired without problem.
Since the jQuery keydown did not appear to fire the pure JS listener in either case, I tried to trigger the keydown with pure JS:
var pressEvent = document.createEvent ('KeyboardEvent');
pressEvent.initKeyEvent ('keydown', true, true, window, true, false, false, false, 65, 0);
document.dispatchEvent (pressEvent);
However, that generates an "undefined is not a function" on the "initKeyEvent".
I also tried the suggestion available here, here (but that one did not specify a which or keyCode, here (but again no keyCode or which),
How can I trigger a pure JS keydown listener from a Chrome extension?
Thank you
See Question&Answers more detail:
os