Отсутствие вашего HTML немного усложнило задачу, но я придумал некоторую разметку, которая работает со структурой вашего скрипта, а затем успешно изменил скрипт:
- L oop с использованием всех параметров ,
- Имитируйте связанный
link
щелчок для каждой опции и - Имитируйте
button
щелчок для каждой опции, чтобы загрузить связанный файл
Я столкнулся с той же проблемой, что и вы , и мне удалось избавиться от нее go, добавив прослушиватель настраиваемых событий в элемент dropdown
. По крайней мере, часть проблемы для меня заключалась в том, что программное изменение свойства selectedIndex
элемента select
не запускает прослушиватели событий , как это происходит при вызове метода .click
для определенных элементов. Чтобы гарантировать, что функция download
вызывается для каждой опции, в приведенном ниже коде используется настраиваемое событие (называемое programmatic-selection
), которое запускается вручную в функции chooseOpt
.
Другое на заметку:
Каждый link
имеет атрибут data-file
, в котором хранится путь к связанному файлу . Это значение при необходимости копируется в глобальную переменную filepath
, чтобы button
мог видеть, какой файл загружать.
Каждый link
будет нажат, если он класс, соответствующий текущему текстовому содержимому option
. (Ваш код выбирает link
s на основе link.textContent === 'Filter'
, и это поведение сохраняется: любое link
, которое соответствует текущему option
, имеет свойство textContent
, установленное на «Фильтр», чтобы соответствовать вашему условию и тем самым вызвать имитацию щелчка.)
// Declares global variables
const
dropdown = document.getElementsByClassName('dropdown')[1],
links = Array.from(document.getElementsByClassName('btn')),
button = document.getElementsByClassName('download-link')[0];
let filepath = '';
// Adds event listeners
dropdown.addEventListener('programmatic-selection', handleProgrammaticSelection);
document.addEventListener('click', handleLinkClick);
button.addEventListener('click', handleButtonClick);
// Main
chooseAll();
// Loops through options, selecting each one
function chooseAll(){
let i = -1;
while(++i < dropdown.length){
chooseOpt(i);
}
}
// Triggers custom event listener and the appropriate link
function chooseOpt(x){
dropdown.selectedIndex = x;
// The `change` event won't fire if we select an option
// programmatically, so we fire a custom event instead
dropdown.dispatchEvent(new CustomEvent('programmatic-selection'));
links.forEach((link) => {
if(link.textContent === 'Filter'){
// Simulates click on certain links, triggering listener
link.click();
}
});
}
// Listener for custom event -- sets link text
function handleProgrammaticSelection(event){
const dropdown = event.target;
links.forEach((link) => {
// `chooseOpt` relies on `textContent` property of `link` elements,
// so we set this before deciding which link to click
link.textContent = link.classList.contains(dropdown.value)
? 'Filter'
: 'Nope';
});
}
// (Listeners can automatically access their triggering events)
function handleLinkClick(event){
// An event has a `target` property
const clickedThing = event.target;
// Ignores irrelevant clicks
if(!clickedThing.classList.contains('btn')){ return; }
// Sets global `filepath` to match 'file' data-attribute of target
filepath = clickedThing.dataset.file;
// Calls `download`, which simulates button click
download();
}
// Called by above listener
function download(){
// Simulates click on `button`, triggering listener
button.click();
}
// Called by listener on `button`
function handleButtonClick(event){
// Accesses global `filepath` to pick file
console.log(`downloading ${filepath}...`);
}
<select class="dropdown">
<option>A</option>
<option>B</option>
</select><br/>
<select class="dropdown">
<option>AA</option>
<option>BB</option>
<option>CC</option>
</select><br/><br/>
<button data-file='some-file' class='btn AA'>Nope</button><br/>
<button data-file='some-other-file' class='btn BB'>Nope</button><br/>
<button data-file='another-file' class='btn CC'>Nope</button><br/><br/>
<button class='download-link'>Download</button>