使用JavaScript数组填充HTML <select>遇null错误,求解决办法
Move your option-filling code inside the update method, right after you set the innerHTML for this._div. This way, the <select> is already in the DOM when you try to access it. We'll also use querySelector on the control's own div instead of the global document for better reliability:
var police_api_dates = ["&date=2017-03"]; var info = L.control(); info.onAdd = function (mymap) { this._div = L.DomUtil.create('div', 'info'); this.update(); return this._div; }; info.update = function (properties) { // First render the HTML including the select box this._div.innerHTML = '<select id="parent"></select><h4>Highlighted Postcode</h4>' + (properties ? '<b> Postcode: ' + properties.Name : 'Hover over a state'); // Now the select exists—grab it from the control's div and populate options var parent = this._div.querySelector("#parent"); for (var pos = 0; pos < police_api_dates.length; pos++) { var child = document.createElement("option"); child.textContent = police_api_dates[pos]; child.value = pos; parent.appendChild(child); } }; info.addTo(mymap);
Solution 2: Build the Control with DOM API Instead of innerHTML
For more control over your elements (and to avoid innerHTML timing issues entirely), use Leaflet's L.DomUtil.create to build each part of the control explicitly. This way you can populate the select box as you create it:
var police_api_dates = ["&date=2017-03"]; var info = L.control(); info.onAdd = function (mymap) { this._div = L.DomUtil.create('div', 'info'); // Create the select element and add it to the control div var select = L.DomUtil.create('select', '', this._div); select.id = "parent"; // Populate the select with options right away for (var pos = 0; pos < police_api_dates.length; pos++) { var option = L.DomUtil.create('option', '', select); option.textContent = police_api_dates[pos]; option.value = pos; } // Add the heading var heading = L.DomUtil.create('h4', '', this._div); heading.textContent = "Highlighted Postcode"; // Create a dedicated div for dynamic content to update later this.contentDiv = L.DomUtil.create('div', '', this._div); this.update(); return this._div; }; info.update = function (properties) { // Only update the dynamic content, no need to rebuild the select this.contentDiv.innerHTML = properties ? '<b> Postcode: ' + properties.Name : 'Hover over a state'; }; info.addTo(mymap);
Key Takeaway
The main rule here is: Never try to manipulate a DOM element until it's been added to the DOM tree. Either populate elements immediately after creating them via innerHTML, or build your UI piece-by-piece with DOM creation methods to avoid timing mismatches.
内容的提问来源于stack exchange,提问作者Adam




