Reputation: 853
http://info.academyart.edu/programs?&pmcode=PMDIR
On this page, when you choose any option from "Current level of education" select, an new select is shown below ("Program of interest").
I'm trying to change it's value via my chrome extension like this:
var evt = document.createEvent("HTMLEvents");
var program = document.getElementById('Program');
program.selectedIndex = 1;
evt.initEvent("change", true, true);
program.dispatchEvent(evt);
but it won't change. I tried also with this:
var program = document.getElementById('Program');
program.selectedIndex = 1;
but result is the same.
In my code I first select an value in "current level of education" selectbox, if that matters. So, I can change value in any other select on that page, but I can't change it on this one.
What could be the problem?
Upvotes: 0
Views: 1999
Reputation: 2188
Dispatching events is only useful when something listens to them. The element in question (#educationLevel
) listens to focus
, change
, and blur
events.
The easiest way to create events is with an Event
constructor.
function dispatch(el, evType) {
el.dispatchEvent(new Event(evType));
}
var level = document.getElementById('educationLevel');
dispatch(level, 'focus');
level.selectedIndex = 1;
dispatch(level, 'change');
dispatch(level, 'blur');
However, #Program
only listens to focus
and blur
so you don't need to dispatch the change
event.
The actual problem: #Program
is empty on load and only gets populated after change
on #educationLevel
fires. Thus you need to apply a mutation observer on it:
function initMO(root, callback) {
var MO = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MO(function(mutations) {
observer.disconnect();
mutations.forEach(function(mutation){
callback(mutation.target);
});
observe(); // comment this out to run only once
});
var opts = { childList: true, subtree: true };
var observe = function() {
observer.takeRecords();
observer.observe(root, opts);
};
observe();
}
full solution:
function dispatch(el, evType) {
el.dispatchEvent(new Event(evType));
}
function addMO(root, callback) {
var MO = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MO(function(mutations) {
observer.disconnect();
mutations.forEach(function(mutation){
callback(mutation.target);
});
observe(); // comment this out to run only once
});
var opts = { childList: true, subtree: true };
var observe = function() {
observer.takeRecords();
observer.observe(root, opts);
};
observe();
}
var level = document.getElementById('educationLevel');
dispatch(level, 'focus');
level.selectedIndex = 1;
dispatch(level, 'change');
dispatch(level, 'blur');
var program = document.getElementById('Program');
addMO(program, function() {
program.selectedIndex = 1;
});
Upvotes: 1
Reputation: 10897
When you load the page, your content script is injected and you can view from F12 tool, at that time #Program is hidden with only one option. So after the rest options showing, you content script will not be injected and executed again, that's the root cause.
You should try executing
program.selectedIndex = 1;
after the hidden options show, for example, you can declare a browserActionListener in your background script and do messaging communication when click that, then you can make sure above code be executed in an environment that the rest options can be accessed.
Upvotes: 0