在 r2d3 (RMarkdown) 中使用多个 javascript 脚本时出现 document.body.onload 问题

问题描述 投票:0回答:1

我在 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。

javascript r r-markdown r2d3
1个回答
0
投票

如评论中所述,

document.body.onload
只能有一个值。如果您(或第三方供应商)尝试为该事件分配不同的处理程序,则前一个处理程序将被覆盖并且不会执行。只有最后分配的处理程序才会执行。要查看分配给 onload 事件的处理程序,只需将
document.body.onload
粘贴到控制台即可。

同样如前所述,如果您想向加载事件添加多个处理程序,那么您将需要添加如下内容:

window.addEventListener('load', my_function)

您可以添加尽可能多的负载

document.addEventListener()
,因为它不可靠每个问题

© www.soinside.com 2019 - 2024. All rights reserved.