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 }
问题截图:
原因分析
- 地图
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
相关产品推荐
相关产品推荐

