如何从 iframe 源获取 jstree 实例?

问题描述

我使用 jstree 在单独的 iframe 中准备了 2 个树视图。右树视图应该控制左树视图。当用户单击右侧树视图中的列表之一时,将在左侧树视图中打开并选择相应的项目文件夹。我可以在单页中使用 div 来实现它。我使用右侧 jstree div var instance = $('#left').jstree(true); 中的左侧树视图实例控制左侧树视图。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<!doctype html>
<html>

<head>
  
  <script src="jquery/jquery-2.2.3.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.11/jstree.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.11/themes/default/style.min.css" />

  <Meta charset="UTF-8">
    <title>jstree basic demos</title>
    <style>
    html { margin:0; padding:0; font-size:62.5%; }
    body { max-width:800px; min-width:300px; margin:0 auto; padding:20px 10px; font-size:14px; font-size:1.4em; }
    h1 { font-size:1.8em; }
    .demo { overflow:auto; border:1px solid silver; min-height:100px; }
        
        .flex-container {
            display: flex;
        }
        .flex-child {
            flex: 1;
            border: 1px solid black;
        }  
        .flex-child:first-child {
            margin-right: 20px;
        } 
    </style>
</head>

<body>
  <h1>Tree Menu</h1>
<!--    <button id="evts_button">select node with id 1</button> <em>either click the button or a node in the tree</em>-->
        <div class="flex-container">

            <div class="flex-child magenta">
                <div id="left" class="demo">
                </div>
            </div>

            <div class="flex-child green">
                <div id="List">
                </div>
            </div>
  
        </div>
  <script>
    $('#left')
        .jstree({
            'core' : {
                'multiple' : false,'data' : [
                                            {
                                                "text":"A","id":"A","children":[
                                                    {"text":"Australia","id":"Aus"},{"text":"America","id":"Ame"}
                                                ]                                             
                                            },{
                                                "text":"B","id":"B","children":[
                                                    {"text":"Beirut","id":"Bei"},{"text":"Brunei","id":"Bru"}
                                                ]
                                            }
                                        ]
            }
        });
    $('#List')
                .on("changed.jstree",function(e,data){
                    if(data.selected.length)
                    {
                        $("#left").jstree("close_all");
                        //console.log(data.selected);
                        selected_node=data.selected[0];//list-j2_1
                        console.log(selected_node);
                        var tm_id = selected_node.replace("j2_","");//tree
                        var instance = $('#left').jstree(true);
                        instance.deselect_all();
                        instance.select_node(tm_id);
                        $("#left").jstree("open_all",tm_id);
                    }
                })
                .jstree({
                    'core':{
                        'multiple':false,'data':[{"text":"Australia","id":"Ame"},{"text":"Beirut","id":"Bru"}]
                    }
                })
        </script>
</body>

</html>

在使用 iframe 时,我无法获取左侧树视图的实例。我想在 index-10_2.html(右 iframe 源)中获得左树视图实例来选择和打开相应的节点。我使用 left=$("#1").contents(); 获取 iframe 内容,使用 var instance=left.find('#left'); 获取实例,使用 instance.select_node(tm_id); 选择节点。但是,显示错误 instance.select_node is not a function

<!DOCTYPE html>
<html>
    <head>
        <Meta charset="utf-8">
        <Meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <Meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
        <iframe src="index-10_1.html" id="1"></iframe>
        <iframe src="index-10_2.html" id="2"></iframe>
    </body>
</html>

index-10_1.html

    <!DOCTYPE html>
<html>
    <head>
        <Meta charset="utf-8">
        <Meta http-equiv="X-UA-Compatible" content="IE=edge,shrink-to-fit=no">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
            <div class="content demo" id="left"></div>
            <script>
                $('#left')
        .jstree({
            'core' : {
                'multiple' : false,"id":"Bru"}
                                                ]
                                            }
                                        ]
            }
        });
            </script>
    </body>
</html>

index-10_2.html

    <!DOCTYPE html>
<html>
    <head>
         <Meta charset="utf-8">
        <Meta http-equiv="X-UA-Compatible" content="IE=edge,shrink-to-fit=no">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
        <div class="content" id="right"></div>
        <script>
            $('#right')
                    .on("changed.jstree",data){
                        if(data.selected.length)
                        {
                            $("#left").jstree("close_all");
                            console.log(data.selected);
                            selected_node=data.selected[0];//list-j2_1
                            console.log(selected_node);
                            var tm_id = selected_node.replace("j2_","");//tree
                            left=$("#1").contents().find('#left');
                            instance=left.jstree(true);
                            instance.select_node(tm_id);
                            $("#left").jstree("open_all",tm_id);
                        }
                    })
                    .jstree({
                        'core':{
                            'multiple':false,"id":"Bru"}]
                        }
                    })
        </script>
    </body>
</html>

解决方法

我曾使用 document.getElementById('1').contentWindow.jQuery('#left').jstree(true); 从 id='1' 的 iframe 中获取实例。为了在单击任何菜单时收听正确的 iframe(id='2'),我使用了 document.getElementById('2').contentWindow.jQuery('#right').on("changed.jstree",function(e,data){})。我在这个函数中得到了左 iframe 的实例。通过使用这个实例,我取消了上一个选择,选择了当前选择,并打开了所选菜单的子项。

index-12.html

    <!DOCTYPE html>
     <!--
       To change this license header,choose License Headers in Project Properties.
       To change this template file,choose Tools | Templates and open the template 
       in the editor.
    -->
    <html>
    <head>       
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
        <iframe src="index-12_1.html" id="1"></iframe>
        <iframe src="index-12_2.html" id="2"></iframe>
        <script>
            sec_frm =document.getElementById('2');//second frame
            sec_frm.addEventListener("load",function(){//wait for second frame to load
             
 fst_frm_jstinst=document.getElementById('1').contentWindow.jQuery('#left').jstree(true);//first frame jstree instance
              
document.getElementById('2').contentWindow.jQuery('#right').on("changed.jstree",data){
                  if(data.selected.length){
                      //close all menu in first frame
                      document.getElementById('1').contentWindow.jQuery('#left').jstree("close_all");
                      //get selected menu id from second frame
                      selected_node=data.selected[0];
                      //deselect any selected menu on first frame
                      fst_frm_jstinst.deselect_all();
                      //select node(country)
                      fst_frm_jstinst.select_node(selected_node);
                      document.getElementById('1').contentWindow.jQuery('#left').jstree("open_all",selected_node);
                      //console.log(selected_node);
                  }
              })

            })
        </script>
    </body>
</html>

index-12_1

    <!DOCTYPE html>
<!--
To change this license header,choose License Headers in Project Properties.
To change this template file,choose Tools | Templates
and open the template in the editor.
-->
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree 4a77e59/dist/themes/default/style.min.css"/>
    </head>
    <body>
        <div class="content demo" id="left"></div>
        <script>
            $('#left')
        .jstree({
            'core' : {
                'multiple' : false,'data' : [
                                            {
                                                "text":"A","id":"A","children":[
                                                    {"text":"Australia","id":"Aus"},{"text":"America","id":"Ame"}
                                                ]                                             
                                            },{
                                                "text":"B","id":"B","children":[
                                                    {"text":"Beirut","id":"Bei"},{"text":"Brunei","id":"Bru"}
                                                ]
                                            }
                                        ]
            }
        });
        </script>
    </body>
</html>

index-12_2.html

<!DOCTYPE html>
<!--
To change this license header,choose Tools | Templates
and open the template in the editor.
-->
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
         <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
        <div class="content" id="right"></div>
        <script>
            $('#right')
                    .jstree({
                                'core':{
                                    'multiple':false,'data':[{"text":"Australia","id":"Ame"},{"text":"Beirut","id":"Bru"}]
                                }
                            })
        </script>
    </body>
</html>