下拉菜单点击事件在HTML和JS代码中未触发。

huangapple go评论65阅读模式
英文:

Dropdown click event not firing in HTML and JS code

问题

Dropdown Click Event Not Being Triggered

我尝试在DOM加载后加载监听器,对于我添加的每个选项,都似乎不起作用。这有点复杂,因为我有图像,所以我不是使用常规的HTML下拉菜单,而且我也是以编程方式添加选项。
或者有时,它会提交数字0(我不知道为什么)
这里是可以看到它工作的CodePen链接

这里是原始的JavaScript代码:

const wcaIdInput = document.getElementById('wcaIdInput');
const wcaIdList = document.getElementById('wcaIdList');
const dropdownList = document.getElementById('dropdown-list');

wcaIdInput.addEventListener('input', () => {
  const inputValue = encodeURIComponent(wcaIdInput.value.toLowerCase());

  dropdownList.addEventListener('click', (event) => {
    const clickedElement = event.target;
    console.log(clickedElement); 
  });

  fetch(`https://www.worldcubeassociation.org/api/v0/search/users?q=${inputValue}&persons_table=true`)
    .then(response => response.json())
    .then(data => {
      let top3 = [];
      for (let i = 0; i < 3 && i < data.result.length; i++) {
        top3.push({
          name: data.result[i].name,
          id: data.result[i].id,
          avatarUrl: data.result[i].avatar.url
        });
      }
      populateOptions(top3);
    })
    .catch(error => {
      console.error(error);
    });
});

document.addEventListener('click', (event) => {
  const clickedElement = event.target;
  if (dropdownList.contains(clickedElement)) {
    console.log(clickedElement);
  }
});

function populateOptions(options) {
  dropdownList.innerHTML = '';

  if (options.length > 1) {
    options.reverse().forEach(option => {
      const optionElement = document.createElement('li');
      optionElement.value = option.id;
      optionElement.innerHTML = `
        <img src="${option.avatarUrl}" alt="Avatar" width="40" height="40">
        <span class="bigger-text">${option.name}</span>
        <span class="smaller-text">${option.id}</span>
      `;
      optionElement.addEventListener('click', () => {
        console.log('yo what?');
        console.log('Clicked option:', optionElement); // 新的控制台日志
        wcaIdInput.value = optionElement.value;
        hideDropdown();
        submitWcaId();
      });
      dropdownList.appendChild(optionElement);
    });

    dropdownList.style.display = 'block';
    dropdownList.style.top = `${wcaIdInput.offsetTop + wcaIdInput.offsetHeight}px`;
    dropdownList.style.left = `${wcaIdInput.offsetLeft}px`;
  } else if (options.length === 1) {
    const optionElement = document.createElement('li');
    optionElement.value = options[0].id;
    optionElement.innerHTML = `
      <img src="${options[0].avatarUrl}" alt="Avatar" width="40" height="40">
      <span class="bigger-text">${options[0].name}</span>
    `;
    console.log(optionElement);
    optionElement.addEventListener('click', () => {
      console.log("click moment!");
      console.log('Clicked option:', optionElement); // 新的控制台日志
      wcaIdInput.value = optionElement.value;
      hideDropdown();
      submitWcaId();
    });
    dropdownList.appendChild(optionElement);

    // 显示和定位下拉列表
    dropdownList.style.display = 'block';
    dropdownList.style.top = `${wcaIdInput.offsetTop + wcaIdInput.offsetHeight}px`;
    dropdownList.style.left = `${wcaIdInput.offsetLeft}px`;
  } else {
    hideDropdown();
  }
}

function hideDropdown() {
  dropdownList.style.display = 'none';
}

wcaIdInput.addEventListener('focus', () => {
  if (wcaIdInput.value.trim() !== '') {
    dropdownList.style.display = 'block';
  }
});

wcaIdInput.addEventListener('blur', () => {
  hideDropdown();
});

以及HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  ...
</head>
<body>
  <div class="container">
    <div class="dropdown">
      <input type="text" id="wcaIdInput" name="wcaIdInput" placeholder="WCA ID" autocomplete="off" autofocus>
      <ul id="dropdown-list"></ul>
    </div>
    <button id="submitBtn">Submit</button>
  </div>
  <div id="loading" style="display: none;">
    <div class="loader"></div>
  </div>
  <div id="error" class="error"></div>
  <div id="tableContainer"></div>
  <script src="js/upcoming.js"></script>
</body>
</html>
英文:

Dropdown Click Event Not Being Triggered

I tried loading the listener after the DOM is loaded, for each option I added, neither seemed to work. It's a bit more complicated since I have images, so I'm not using the regular html dropdown and I'm also adding the options programmatically.
Or sometimes, it'll submit the number 0 (I have no clue why)
here's the codepen to see it working

and here's the raw js:

const wcaIdInput = document.getElementById(&#39;wcaIdInput&#39;);
const wcaIdList = document.getElementById(&#39;wcaIdList&#39;);
const dropdownList = document.getElementById(&#39;dropdown-list&#39;);

wcaIdInput.addEventListener(&#39;input&#39;, () =&gt; {
  const inputValue = encodeURIComponent(wcaIdInput.value.toLowerCase());

 dropdownList.addEventListener(&#39;click&#39;, (event) =&gt; {
  const clickedElement = event.target;
  console.log(clickedElement); 
});

fetch(`https://www.worldcubeassociation.org/api/v0/search/users?q=${inputValue}&amp;persons_table=true`)
    .then(response =&gt; response.json())
    .then(data =&gt; {
      let top3 = [];
      for (let i = 0; i &lt; 3 &amp;&amp; i &lt; data.result.length; i++) {
        top3.push({
          name: data.result[i].name,
          id: data.result[i].id,
          avatarUrl: data.result[i].avatar.url
        });
      }
      populateOptions(top3);
    })
    .catch(error =&gt; {
      console.error(error);
    });
});

// wcaIdList.addEventListener(&#39;change&#39;, (event) =&gt; {
//   wcaIdInput.value = event.target.value;
// });
document.addEventListener(&#39;click&#39;, (event) =&gt; {
  const clickedElement = event.target;
  if (dropdownList.contains(clickedElement)) {
    console.log(clickedElement);
  }
});

function populateOptions(options) {
  dropdownList.innerHTML = &#39;&#39;;

  if (options.length &gt; 1) {
    options.reverse().forEach(option =&gt; {
      const optionElement = document.createElement(&#39;li&#39;);
      optionElement.value = option.id;
      optionElement.innerHTML = `
        &lt;img src=&quot;${option.avatarUrl}&quot; alt=&quot;Avatar&quot; width=&quot;40&quot; height=&quot;40&quot;&gt;
        &lt;span class=&quot;bigger-text&quot;&gt;${option.name}&lt;/span&gt;
        &lt;span class=&quot;smaller-text&quot;&gt;${option.id}&lt;/span&gt;
      `;
      optionElement.addEventListener(&#39;click&#39;, () =&gt; {
        console.log(&#39;yo what?&#39;);
        console.log(&#39;Clicked option:&#39;, optionElement); // New console log
        wcaIdInput.value = optionElement.value;
        hideDropdown();
        submitWcaId();
      });
      dropdownList.appendChild(optionElement);
    });

    dropdownList.style.display = &#39;block&#39;;
    dropdownList.style.top = `${wcaIdInput.offsetTop + wcaIdInput.offsetHeight}px`;
    dropdownList.style.left = `${wcaIdInput.offsetLeft}px`;
  } else if (options.length === 1) {
    const optionElement = document.createElement(&#39;li&#39;);
    optionElement.value = options[0].id;
    optionElement.innerHTML = `
      &lt;img src=&quot;${options[0].avatarUrl}&quot; alt=&quot;Avatar&quot; width=&quot;40&quot; height=&quot;40&quot;&gt;
      &lt;span class=&quot;bigger-text&quot;&gt;${options[0].name}&lt;/span&gt;
    `;
    console.log(optionElement);
    optionElement.addEventListener(&#39;click&#39;, () =&gt; {
      console.log(&quot;click moment!&quot;);
      console.log(&#39;Clicked option:&#39;, optionElement); // New console log
      wcaIdInput.value = optionElement.value;
      hideDropdown();
      submitWcaId();
    });
    dropdownList.appendChild(optionElement);

    // Show and position the dropdown list
    dropdownList.style.display = &#39;block&#39;;
    dropdownList.style.top = `${wcaIdInput.offsetTop + wcaIdInput.offsetHeight}px`;
    dropdownList.style.left = `${wcaIdInput.offsetLeft}px`;
  } else {
    hideDropdown();
  }
}
function hideDropdown() {
  dropdownList.style.display = &#39;none&#39;;
}

wcaIdInput.addEventListener(&#39;focus&#39;, () =&gt; {
  if (wcaIdInput.value.trim() !== &#39;&#39;) {
    dropdownList.style.display = &#39;block&#39;;
  }
});

wcaIdInput.addEventListener(&#39;blur&#39;, () =&gt; {
  hideDropdown();
});

and html:

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  ...
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;container&quot;&gt;
    &lt;div class=&quot;dropdown&quot;&gt;
      &lt;input type=&quot;text&quot; id=&quot;wcaIdInput&quot; name=&quot;wcaIdInput&quot; placeholder=&quot;WCA ID&quot; autocomplete=&quot;off&quot; autofocus&gt;
      &lt;ul id=&quot;dropdown-list&quot;&gt;&lt;/ul&gt;
    &lt;/div&gt;
    &lt;button id=&quot;submitBtn&quot;&gt;Submit&lt;/button&gt;
  &lt;/div&gt;
  &lt;div id=&quot;loading&quot; style=&quot;display: none;&quot;&gt;
    &lt;div class=&quot;loader&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div id=&quot;error&quot; class=&quot;error&quot;&gt;&lt;/div&gt;
  &lt;div id=&quot;tableContainer&quot;&gt;&lt;/div&gt;
  &lt;script src=&quot;js/upcoming.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

答案1

得分: 0

以下是onBlur处理程序

wcaIdInput.addEventListener('blur', () => {
  hideDropdown();
});

触发并隐藏下拉菜单在点击项目之前发生。

因此,您的点击不会到达项目,因此不会执行点击回调。

将此处理程序注释掉可以解决问题。

您可能想要删除此处理程序或使用其他事件来隐藏下拉菜单。

英文:

The following onBlur handler

wcaIdInput.addEventListener(&#39;blur&#39;, () =&gt; {
hideDropdown();
});

fires and hides the dropdown before clicking on an item happens.

As a result, your click doesn't reach an item, and hence, click callback is not executed.

Commenting out this handler solves the problem.

You may want to remove this handler or use some other event to hide the dropdown.

huangapple
  • 本文由 发表于 2023年5月29日 07:27:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76353963.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定