简体   繁体   中英

How to get object properties on element click?

I am building a weather app for practice. I get to that point that I have to make an autocomplete input field with data from JSON object. When someone makes an input, it displays the matched data, but on click I want to get two properties from the object. I need to get the longitude and latitude properties from JSON object to make an API request to return the object with the weather data. The content displays properly but I can't make that onClick event listener work. I tried very different things and failed, either was a scope problem or something else. It is one of my first projects and I am in a downfall right now. Please help me. :)

PS You can find it on this link: https://objective-edison-1d6da6.netlify.com/

// Testing
const search = document.querySelector('#search');
const matchList = document.querySelector('#match-list');
let states;

// Get states
const getStates = async () => {
  const res = await fetch('../data/bg.json');
  states = await res.json();
};

// Filter states
const searchStates = searchText => {
  // Get matches to current text input
  let matches = states.filter(state => {
    const regex = new RegExp(`^${searchText}`, 'gi');

    return state.city.match(regex);
  });

  // Clear when input or matches are empty
  if (searchText.length === 0) {
    matches = [];
    matchList.innerHTML = '';
  }

  outputHtml(matches);
};

// Show results in HTML
const outputHtml = matches => {
  if (matches.length > 0) {
    const html = matches
      .map(
        match => `<div class="card match card-body mb-1">
    <h4>${match.city} 
    <span class="text-primary">${match.country}</span></h4>
    <small>Lat: ${match.lat} / Long: ${match.lng}</small>
   </div>`
      )
      .join('');
    matchList.innerHTML = html;
    document.querySelector('.match').addEventListener('click', function() {});
    //Wconsole.log(matches);
    //let test = document.querySelectorAll('#match-list .card');
    //const values = matches.values(city);
  }
};

window.addEventListener('DOMContentLoaded', getStates);
search.addEventListener('input', () => searchStates(search.value));

If I understand correctly, you're trying to access the lat and lng values of the clicked match, if that is the case, here is one way of doing it:

const outputHtml = matches => {
  if (matches.length > 0) {
    const html = matches
      .map(
        match => `<div class="card match card-body mb-1" data-lat="`${match.lat}" data-lng="`${match.lng}">
    <h4>${match.city} 
    <span class="text-primary">${match.country}</span></h4>
    <small>Lat: ${match.lat} / Long: ${match.lng}</small>
   </div>`
      )
      .join('');
    matchList.innerHTML = html;
    document.querySelectorAll('.match').forEach(matchElm => {
      matchElm.addEventListener('click', function(event) {
         const { currentTarget } = event;
         const { lat, lng } = currentTarget.dataset;
      });
    });
  }
};

I've used the data-lat and data-lng attributes to store the required values in the element's dataset and I've used document.querySelectorAll('.match') to get all the elements that have the class match not just the first one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM