首页 > 解决方案 > 从下拉列表中选择值,过滤结果并循环下载文件

问题描述

我的目标是将javascript函数置于循环中:

  1. 从下拉列表中选择选项
  2. 点击“过滤”按钮
  3. 下载选定的文件

当我在两个功能中使用它时,它可以完美运行: - 没有循环,手动运行(索引从 0 到 x)

function chooseOpt(x){
document.getElementsByClassName('span4 m-wrap dropdown combobox')[1].selectedIndex = x;
const links = Array.from(document.getElementsByClassName('btn green'));
links.forEach((link) => {
  if (link.textContent === 'Filter') {
    link.click();
  }
})
}
    
function Dowload(){
var button = document.getElementsByClassName('btn icn-only black tooltips download_link')[0];
button.click();
}

但是我怎样才能进入循环?我已经从这两个函数中创建了一个函数,但不起作用:

function chooseOpt(){
    for (x = 0; x<3;x++){
    document.getElementsByClassName('span4 m-wrap dropdown combobox')[1].selectedIndex = x;
    const links = Array.from(document.getElementsByClassName('btn green'));
    var button  = document.getElementsByClassName('btn icn-only black tooltips download_link')[0];
    links.forEach((link) => {
      if (link.textContent === 'Filter') {
        link.click();
      }
    }
    )
      button.click();
    }
}

chooseOpt();

你能给我提示吗,链接?谢谢

标签: javascripthtml

解决方案


看不到您的 HTML 有点挑战性,但我设计了一些适用于您的脚本结构的标记,然后成功地修改了脚本:

  • 循环遍历所有选项,
  • 模拟link每个选项的关联点击,以及
  • 模拟button每个选项的单击以下载关联文件

我遇到了同样的问题,我可以通过在dropdown元素上添加一个自定义事件侦听器来解决它。对我来说,至少部分问题是以编程方式更改元素的selectedIndex属性select.click不会像在某些元素上调用方法那样触发事件侦听器。为了确保download为每个选项调用该函数,下面的代码使用了一个自定义事件(称为programmatic-selection),该事件在chooseOpt函数中手动触发。

其他需要注意的事项:

  • 每个link都有一个data-file存储相关文件路径的属性。需要时将此值复制到全局filepath变量中,以便button查看要下载的文件。

  • 如果每个link都具有与当前option文本内容匹配的类,则每个都将被单击。(您的代码link基于 s 选择 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>


推荐阅读