не было сделано никаких попыток быть кросс-браузер здесь ... Но есть только один браузер, я могу думать, что может дать вам неприятности :)
Demo
Код
var product = document.getElementById('product');
var power = document.getElementById('power');
var allOpts = power.getElementsByTagName('option');
var opts = {
empty: allOpts[0]
};
// This builds three additional lists of options for each type of product
// It relies on having a single attribute - if more are added, this logic
// would need to be adjusted.
for(var i = 1; i < allOpts.length; ++i) {
var name = allOpts[i].attributes[0].value;
opts[name] = opts[name] || [];
opts[name].push(allOpts[i]);
}
// Each time product is changed, just loop through based on the selected ID
// and add those options to the power select list (removing all children first)
product.addEventListener('change', function(evt) {
var val = evt.target.value;
power.innerHTML = '';
power.appendChild(opts.empty);
for(var i = 0; i < opts[val].length; ++i) {
power.appendChild(opts[val][i]);
}
});
Здесь представляет собой версию с использованием документа. Фрагмент:
Demo
DocumentFragment версия
var product = document.getElementById('product');
var power = document.getElementById('power');
var allOpts = power.getElementsByTagName('option');
var opts = {
empty: allOpts[0]
};
// Appending to the doc fragment removes it from the live nodelist
while(allOpts.length > 1) {
var name = allOpts[1].attributes[0].value;
opts[name] = opts[name] || document.createDocumentFragment();
opts[name].appendChild(allOpts[1]);
}
product.addEventListener('change', function(evt) {
var val = evt.target.value;
power.innerHTML = '';
power.appendChild(opts.empty);
power.appendChild(opts[val].cloneNode(true));
});
Update
С помощью всего лишь немного больше работы, это может быть сделано более общий характер - скажем, когда новые требования приходят в комментариях к первоначальному ответу :)
Дополнительные требования
Примечание. Я добавил пустой элемент элемента, чтобы упростить решение. Код может быть адаптирован для обработки его отсутствия, но это будет оставлено в качестве упражнения для читателя.
<select name="continent" id="continent">'
<option value="IMAGES/maps/europe_gray.png" id="EU">Europe</option>
<option value="IMAGES/maps/europe_gray.png" id="AS">Asia</option>
</select>
<select name="country" id="country">
<option></option>
<option name="EU" id="ALB" value="IMAGES/flags/al.png">Albania, Republic of</option>
<option name="AS" id="RUS" value="IMAGES/flags/ru.png">Russia</option>
</select>
С ниже изменений, логический контроллер теперь более общий характер в том, что он может адаптироваться к разметке, приняв дополнительную информацию, которая говорит ему, где найти его ключи и выбрать элементы.
Generic Controller Example
/* params {
* master: id of the master select element
* subord: id of the subordinate select element
* mKey: name of the attribute holding the key in master that will be used to filter subordinate options
* sKey: name of the attribute in subordinate that will be used to match against mKey
*/
function selectController(params) {
var master = document.getElementById(params.master);
var subord = document.getElementById(params.subord);
var allOpts = subord.getElementsByTagName('option');
var opts = {
empty: allOpts[0]
};
// Appending to the doc fragment removes it from the live nodelist
while (allOpts.length > 1) {
var name = allOpts[1].getAttribute(params.sKey);
opts[name] = opts[name] || document.createDocumentFragment();
opts[name].appendChild(allOpts[1]);
}
master.addEventListener('change', function (evt) {
var sel = master.options[master.selectedIndex];
var mKey = sel.getAttribute(params.mKey);
subord.innerHTML = '';
subord.appendChild(opts.empty);
subord.appendChild(opts[mKey].cloneNode(true));
});
}
selectController({
master: 'product',
subord: 'power',
mKey: 'id',
sKey: 'name'
});
selectController({
master: 'continent',
subord: 'country',
mKey: 'id',
sKey: 'name'
});
Просто регенерировать список со значениями, вам нужно, когда 'изменения product'. – Bart