0

I'm trying to use Javascript to add event listeners to several links that are created via Javascript. I thought that I am probably calling it before it is created but looked at some other examples (such as add event listener on elements created dynamically and Google Map Event Listener does not seem to work) on here and thought that if those work I should probably be fine as well. If anyone could point out where I'm going wrong it would be greatly appreciated.

*It seems like it would be way easier for everyone to just put the whole snippet in.

Also as of right now I'm getting "P1 [object HTMLParagraphElement]" for when I console.log("P1 " + precinct1

JS Snippet:

    function initialize() {

  var myOptions = {
    zoom: 10,
    center: new google.maps.LatLng(123, 123),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }

/*
Creating Map - Do not create with Fusion Tables directly so that you have control
of how the polygons are drawn.
*/
map = new google.maps.Map(document.getElementById('map-canvas'), myOptions);

  //Initialize JSONP request

  var script = document.createElement('script');
  var url = ['https://www.googleapis.com/fusiontables/v1/query?'];
  url.push('sql=');
  var query = 'SELECT COMMISH, geometry, Website FROM ' + tableId;
  var encodedQuery = encodeURIComponent(query);
  url.push(encodedQuery);
  url.push('&callback=drawMap');
  url.push('&key=' + key);
  script.src = url.join('');
  var body = document.getElementsByTagName('body')[0];
  body.appendChild(script);
}

  function createPolygon(precinct, url, comPrecinct){
    google.maps.event.addListener(precinct, 'mouseover', function() {
      this.setOptions(
        {
          fillOpacity: 0.5,
          strokeOpacity: 1,
        }
      );

    });

    google.maps.event.addListener(precinct, 'mouseout', function() {
      this.setOptions(
        {
          fillOpacity: 0.3,
          strokeOpacity: 0,
        }
      );
    });

    google.maps.event.addListener(precinct, 'click', function(){
      window.location = url;
    });

  }

  function drawMap(data) {
        var rows = data['rows'];
        console.log(rows);
        /*Create Legend*/
        var legend = document.createElement('div');
        legend.id = 'legend';
        var content = [];
        content.push('<a href="#"><p class="precinct" id="precinct1"></div>Precinct 1</p></a>');
        content.push('<a href="#"><p class="precinct" id="precinct2"></div>Precinct 2</p></a>');
        content.push('<a href="#"><p class="precinct" id="precinct3"></div>Precinct 3</p></a>');
        content.push('<a href="#"><p class="precinct" id="precinct4"></div>Precinct 4</p></a>');

       legend.innerHTML = content.join('');
       legend.index = 1;
       map.controls[google.maps.ControlPosition.RIGHT_TOP].push(legend);

        for (var i in rows) {
            var comPrecinct = rows[i][0];
            var url = rows[i][2];
            var newCoordinates = [];
            var geometries = rows[i][1]['geometries'];

            if (geometries) {
              for (var j in geometries) {
                newCoordinates.push(constructNewCoordinates(geometries[j]));
              }
            } else {
              newCoordinates = constructNewCoordinates(rows[i][1]['geometry']);
            }

            /*
              Colors are out of order because precincts are out of order
              in KML files. Adjust CSS as necessary.
            */
            var precinct = new google.maps.Polygon({
              paths: newCoordinates,
              strokeColor: colors[i],
              strokeOpacity: 0,
              strokeWeight: 1,
              fillColor: colors[i],
              fillOpacity: 0.3,
            });


            createPolygon(precinct, url, comPrecinct);

            precinct.setMap(map);

        }

      console.log('P1 ' + precinct1);
      google.maps.event.addListener(legend, 'hover', function(e){
          if(e.target.id === 'precinct1'){
            console.log("P1 - aawwwww yis");
          }
        });

  }

  function constructNewCoordinates(polygon){
    var newCoordinates = [];
    var coordinates = polygon['coordinates'][0];
    for (var i in coordinates){
      newCoordinates.push(new google.maps.LatLng(coordinates[i][1], coordinates[i][0]));
    }
    return newCoordinates;
  }

google.maps.event.addDomListener(window, 'load', initialize);

P].push(legend);
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
mario
  • 1,503
  • 4
  • 22
  • 42

2 Answers2

1

I don't know much about google maps api, but the code seems a bit weird to me. You add plain HTML text as strings into an array which aren't placed in the dom/your div. Even the document.getElementById('precinct1'); should not work.

You have to append your links into the dom/your div first, after that register the event handler for each item:

legend.innerHTML += content.join('');

var links = legend.getElementsByTagName('p'); // these are your items with the id you want to bind

for(var i = 0; i < links.length; i++) {
    google.maps.event.addListener(links[i], 'hover', function(){
        console.log("Aww yis");
    });
}

If i'm wrong: Feel free to blame me.

Tyr
  • 2,810
  • 1
  • 12
  • 21
  • Quick clarification - did you mean to use foreach or for? Because foreach just gives me an error. Thanks though! – mario Jan 12 '15 at 20:51
  • Getting an "Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'." message. Could you explain where "content" came from? – mario Jan 12 '15 at 21:08
  • 1
    content is defined in your drawMap function -> `var content = [];`. For your error: We have to set it into a separate container. HTML strings aren't dom elements in the current state. See my edit above. – Tyr Jan 12 '15 at 21:12
  • Lol still no console.log firing from mouseover but now I have everything showing up double in my legend. Thanks though! – mario Jan 12 '15 at 21:20
  • 1
    This comes from here: `legend.innerHTML = content.join('');`. Remove this and it's fine or remove the first for loop where the strings get concatinated. See the edit. – Tyr Jan 12 '15 at 21:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/68682/discussion-between-tyr-and-gv0000). – Tyr Jan 12 '15 at 21:24
  • Thanks! That fixed the double legend but still a no go for adding a hover event. – mario Jan 12 '15 at 21:24
1

The problem is that (as you point it out) you are using it before it is created. Options:

  1. Create it (and actually add it to the document), then cache it, then call it.
  2. Do not cache it (advise against this)
  3. Delegate from the container they are added in (preferred)

I have not used the Google Maps API, but something like this might work (assuming it captures the same mouse event:

google.maps.event.addListener(precinctContainer, 'hover', function(e){
    if(e.target.id === 'precinct1'){
        console.log("Aww yis");
    }
});

Where precinctContainer is the container you put all those <a> tags in the content array.

PlantTheIdea
  • 16,061
  • 5
  • 35
  • 40