【问题标题】:Why is the first click not firing?为什么第一次点击没有触发?
【发布时间】:2019-07-27 16:08:48
【问题描述】:

第一次点击没有触发,我不知道为什么。

所有后续点击都可以正常工作。如果我重新加载页面,同样的问题:第一次点击:没有任何反应。

我已经尝试访问其他 html 元素作为 queryselector 中的测试,但这并没有什么不同。

这是代码(我正在尝试在 vanilla JS 中执行此操作):

const cities = [];
fetch(endpoint)
  .then(blob => blob.json())
  .then(data =>cities.push(...data));

function findMatches(wordToMatch, cities) {
  return cities.filter(place => {
    const regex = new RegExp(wordToMatch, 'gi'); 
    return place.city.match(regex) || place.state.match(regex) 
  });
}

function displayMatches() {
  const matchArray = findMatches(this.value, cities);

  const html = matchArray.map(place => {
  const regex = new RegExp(this.value, 'gi');
  const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
  const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);

    return `
      <li>
        <span class="name">${cityName}, ${stateName}</span>
        <span class="population">${numberWithCommas(place.population)}      </span>
      </li>
    `;

  }).join(''); 
  suggestions.innerHTML = html; 

   // this only works on the second click:
  const searchResult = document.querySelectorAll('li'); 
  searchResult.forEach(el => {
    el.addEventListener('click', function(){
      console.log('hi'); 

  })})


const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');

searchInput.addEventListener('change', displayMatches); // change only fires once user navigates away from input field!
searchInput.addEventListener('keyup', displayMatches);

}


【问题讨论】:

  • 第二次点击什么?请注意,在执行 displayMatches 之前不要安装点击监听器
  • 我想要监听器的html元素是在displayMatches中生成的。这就是为什么我将它包含在这个函数的底部。是不是找错地方了?
  • 不,应该没问题。我的意思是,如果suggestions 在页面加载时确实有任何内容,则不会附加任何点击监听器,因为它不是由displayMatches 生成的。
  • 所以你是说在调试代码的时候,el.addEventListener被执行了,但是之后点击列表项时,控制台没有出现日志?
  • 如果我控制台日志el(或其他任何事情),在第一次点击期间没有任何反应。但是,会记录第二次点击。

标签: javascript


【解决方案1】:

已编辑:问题来自具有焦点的搜索输入,因此单击建议将 blur 输入,然后由于某种原因忽略列表项上的单击事件(请参阅相关讨论 here)。在您的情况下,使用 mousedown 而不是 click 似乎可以解决问题,请参阅下面更新的 sn-p。

const cities = [];

// fetch(endpoint)
// 	.then(blob => blob.json())
// 	.then(data =>cities.push(...data));

// mocking fetch here
_fetch = () => {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve([
				{city: 'Los Angeles', state: 'CA', population: '4M'},
				{city: 'New York City', state: 'NY', population: '8.4M'},
				{city: 'Atlanta', state: 'GA', population: '0.5M'},
			]);
		}, 1000);
	});
};

_fetch()
	.then(data => cities.push(...data));

function findMatches(wordToMatch, cities) {
	return cities.filter(place => {
		const regex = new RegExp(wordToMatch, 'gi'); 
		return place.city.match(regex) || place.state.match(regex);
	});
}

function displayMatches() {
	const matchArray = findMatches(this.value, cities);
	
	const html = matchArray.map(place => {
		const regex = new RegExp(this.value, 'gi');
		const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
		const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
		
		return `
			<li>
				<span class="name">${cityName}, ${stateName}</span>
				<span class="population">${place.population}</span>
			</li>
		`;
		
	}).join('');
	
	suggestions.innerHTML = html; 
	
	// this only works on the second click:
	const searchResult = document.querySelectorAll('li'); 
	searchResult.forEach(el => {
		el.addEventListener('mousedown', e => {
			console.log(`Say hi to ${e.currentTarget.innerText}`);
		});
	});
}

const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
// change only fires once user navigates away from input field!
searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);
<input type="text" class="search" />
<ul class="suggestions">

</ul>

【讨论】:

  • 谢谢,我刚刚尝试过,但它仍然无法与我的代码一起使用。这是否与 fetch API 有关,因为问题仅在页面重新加载时出现?当我运行您的代码 sn-p 时,一切正常!
  • @ClaudSliv 可以在添加搜索输入时重现它,问题似乎是模糊和点击事件之间的冲突,请参阅上面更新的 sn-p 以获得解决方案!
  • 感激不尽!使用 mousedown(虽然不理想)解决了这个问题。
  • 是的,我知道 =/,不是最优的,但我自己找不到更好的解决方案,上面链接的 SO 帖子有不同的方法,但都有缺点或过于复杂,所以我就去了对于此处的“简单”修复,但如果您遇到键盘等问题,您可能需要寻找更好的解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2012-09-22
  • 2015-03-04
相关资源
最近更新 更多