我在 RMarkdown 文档中有两个独立的 r2d3 块,我将其渲染为 HTML。
考虑到 r2d3 的工作方式,每个 r2d3 调用只能有 1 个脚本和 1 个数据源。 (即每个脚本彼此完全独立,并使用单独的数据源等)。
该块生成一个地图,带有下拉菜单:
{r out.width='100%', fig.height=6, echo=FALSE, message=FALSE, warning=FALSE}
library(r2d3)
r2d3(data = dataset_1,
# this is the script for the first map.
script = "X:/dataset_1_script.js",
d3_version = "4",
options(r2d3.shadow = FALSE),
container="div",
elementId = "map_1")
此块生成另一个带有下拉菜单的地图(注意脚本和数据源不同):
{r out.width='100%', fig.height=6, echo=FALSE, message=FALSE, warning=FALSE}
library(r2d3)
r2d3(data = dataset_2,
# this is the script for the second map.
script = "X:/dataset_2_script.js",
d3_version = "4",
options(r2d3.shadow = FALSE),
container="div",
elementId = "map_2")
这里是
dataset_1_script.js
中的一些基本内容。 该脚本在 DOM 中动态创建一个下拉元素:
document.body.onload = addElement_Tract;
function insertAfter_Tract(newNode, existingNode) {
existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);
}
function addElement_Tract() {
// create a sidebar_tract to hold legend and dropdown
const sidebar_tract = document.createElement("div");
sidebar_tract.className = "sidebar_tract";
sidebar_tract.id = "sidebar_tract";
//Create array of options to be added
var display_array_tract = ["2023", "2022","2021","2020","2019", "2018"];
var val_array_tract = [2023, 2022, 2021, 2020, 2019, 2018];
//Create and append select list
var selectList_tract = document.createElement("select");
selectList_tract.id = "mySelect_tract";
selectList_tract.className = "mySelect_tract";
//Create and append the options
for (var i = 0; i < display_array_tract.length; i++) {
var option_tract = document.createElement("option");
option_tract.value = Number(val_array_tract[i]);
console.log(option_tract.value);
option_tract.text = display_array_tract[i];
selectList_tract.appendChild(option_tract);
}
// add the newly created element and its content into the DOM
// Get a reference to the parent node
const parentDiv_tract = document.getElementById("map_choropleth_state_tract").parentNode;
const mapDiv_tract = document.getElementById("map_choropleth_state_tract");
insertAfter_Tract(sidebar_tract, mapDiv_tract)
sidebar_tract.appendChild(selectList_tract);
}
虽然这在
dataset_1_script.js
中有效,但在 dataset_2_script.js
的第二个块中不起作用。在 dataset_2_script.js
中,下拉列表不会在 DOM 中呈现。 该问题是由于两个脚本都调用 addElement
上的 document.body.onload
函数所致。并且,鉴于 document.body.onload
只能调用一次,因此下拉元素在第一个块(第一个脚本)中成功创建是有意义的,但在第二个块(第二个脚本)中则没有成功创建。
所以我的问题是:r2d3 有没有办法解决这个问题? 我确实认为我需要
body.onload
将下拉列表渲染到 DOM。
如评论中所述,
document.body.onload
只能有一个值。如果您(或第三方供应商)尝试为该事件分配不同的处理程序,则前一个处理程序将被覆盖并且不会执行。只有最后分配的处理程序才会执行。要查看分配给 onload 事件的处理程序,只需将 document.body.onload
粘贴到控制台即可。
同样如前所述,如果您想向加载事件添加多个处理程序,那么您将需要添加如下内容:
window.addEventListener('load', my_function)
您可以添加尽可能多的负载
document.addEventListener()
,因为它不可靠每个问题。