You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript动态添加的Dropdown在DOM中重复,页面Resize时持续新增

问题:Dropdown组件重复渲染,页面Resize时持续新增

我通过JavaScript向页面动态添加Dropdown组件,用于切换地图显示属性,选择在地图加载完成后添加该元素。当前遇到的问题是:Dropdown在页面中被重复渲染,且每次调整页面尺寸(Resize)时都会新增更多的Dropdown组件。

代码嵌入r2d3框架(R中的d3.js库),相关伪代码如下:

//set default property for map so it knows which field to use for the map fill color  
var dropdown_val = 'ODpc'

//function that initially draws the map   
function loadMap(dropdown_val) {
  map2.on('load', function () {
    // Add source and layers, etc...

    // Create and inside the load function instead.
    addElement();
  });
}

loadMap(dropdown_val)

//this will be used to add sidebar to the page
function insertAfter(newNode, existingNode) {
  existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);
}

function addElement() {

   // create a sidebar to hold dropdown
   const sidebar = document.createElement("div");
   sidebar.className = "sidebar";
   sidebar.id = "sidebar";


  //For the dropdown: Create array of options to be added
  var array = ["2014-2022", "2022","2021","2020","2019", "2018", "2017", "2016", "2015", "2014"];
  var val_array = ["ODpc", "ODpc2022","ODpc2021","ODpc2020","ODpc2019", "ODpc2018", "ODpc2017", "ODpc2016", "ODpc2015", "ODpc2014"];

  //Create and append select list
  var selectList = document.createElement("select");
  selectList.id = "mySelect";
  selectList.className = "mySelect";


  //Create and append the options
  for (var i = 0; i < array.length; i++) {
    var option = document.createElement("option");
    option.value = val_array[i];
    option.text = array[i];
    selectList.appendChild(option);
  }

  //make legend etc.. etc...

  // Connect the event listener
  selectList.addEventListener('change', onChange);

  // add the newly created element and its content into the DOM
  // Get a reference to the parent node
  const parentDiv = document.getElementById("map_choropleth_state").parentNode;

  const mapDiv = document.getElementById("map_choropleth_state");

  //add the sidebar, which will hold the dropdown
  insertAfter(sidebar, mapDiv);

  //add the dropdown
  sidebar.appendChild(selectList);

 };

function onChange(event) {
  const dropdown_val = event.target.value;
  // Update the layers depending on the value
}

问题截图:Dropdown重复渲染截图

原因分析
  • 地图load事件重复触发:在r2d3框架中,页面Resize时通常会重新触发地图的渲染逻辑,导致map2.on('load', ...)事件被多次绑定并执行,每次执行都会调用addElement()创建新的Dropdown和sidebar。
  • 无创建前的存在性检查:addElement()函数每次执行都会直接创建新的sidebar和Dropdown元素,没有先检查页面中是否已经存在ID为sidebar或mySelect的元素,导致重复添加。
  • 旧元素未清理:每次新增组件时,之前创建的sidebar和Dropdown没有被移除,会在页面中不断累积,出现重复渲染的现象。
解决建议
  • 添加存在性检查:在addElement()开头先判断页面中是否已有目标元素,若存在则直接返回,不重复创建:

    function addElement() {
      // 先检查是否已存在sidebar
      if (document.getElementById("sidebar")) {
        return;
      }
      // 后续创建逻辑不变
      ...
    }
    
  • 避免重复绑定load事件:将map2.on('load', ...)改为仅绑定一次,或者在Resize时只更新地图尺寸,不重新触发完整的loadMap逻辑(比如分离地图尺寸调整和图层/UI加载的逻辑)。

  • 清理旧元素:如果必须重新创建组件,在addElement()开头先移除已存在的sidebar和Dropdown:

    function addElement() {
      const oldSidebar = document.getElementById("sidebar");
      if (oldSidebar) {
        oldSidebar.remove();
      }
      // 后续创建逻辑不变
      ...
    }
    

内容的提问来源于stack exchange,提问作者DiamondJoe12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:34:55