在React Portal中执行Jquery

问题描述

我正在开发使用React Portal的React应用程序。我已经能够使用给定的数据在新窗口中加载门户(门户代表表中的数据。)。现在,我想在Portal中的该表上添加Jquery DataTable库,但是我无法这样做。我以为我的Jquery库和DataTable启动函数在门户中不起作用。

注意:我试图添加一个简单的onClick,但是我无法运行它。

请参阅以下代码段供您参考。

在父组件中向门户网站加载“ Restaurants”组件

<RankingWindowPortal>
    <Restaurants
        restaurants={this.props.restaurants}
        selected={this.state.selected}
        formValues={this.state.formTags}
    />
</RankingWindowPortal>

RankingWindowPortal组件

class RankingWindowPortal extends React.PureComponent {
    constructor(props) {
        super(props);
        // STEP 1: create a container <div>
        this.containerEl = document.createElement('div');
        this.externalWindow = null;
    }

    copyStyles(sourceDoc,targetDoc) {
        Array.from(sourceDoc.styleSheets).forEach(styleSheet => {
            if (styleSheet.cssRules) { // for <style> elements
                const newStyleEl = sourceDoc.createElement('style');

                Array.from(styleSheet.cssRules).forEach(cssRule => {
                    // write the text of each rule into the body of the style element
                    newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.csstext));
                });

                targetDoc.head.appendChild(newStyleEl);
            } else if (styleSheet.href) { // for <link> elements loading CSS from a URL
                const newLinkEl = sourceDoc.createElement('link');

                newLinkEl.rel = 'stylesheet';
                newLinkEl.href = styleSheet.href;
                targetDoc.head.appendChild(newLinkEl);
            }
        });
    }

    render() {
        // STEP 2: append props.children to the container <div> that isn't mounted anywhere yet
        return ReactDOM.createPortal(this.props.children,this.containerEl);
    }

    componentDidMount() {
        // STEP 3: open a new browser window and store a reference to it
        // this.externalWindow = window.open('','','width=1920,height=1080');
        this.externalWindow = window.open('','width=1700,height=900,left=300,bottom=300');
        this.copyStyles(document,this.externalWindow.document);

        // STEP 4: append the container <div> (that has props.children appended to it) to the body of the new window
        this.externalWindow.document.body.appendChild(this.containerEl);

    }

    componentwillUnmount() {
        // STEP 5: This will fire when this.state.showWindowPortal in the parent component becomes false
        // So we tidy up by closing the window
        this.externalWindow.close();
    }
}

export default RankingWindowPortal

餐厅组件

import React,{ Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import "../styles/restaurants.css"
import logo from "../resources/summit.png"
import RankingFooter from "./rankingfooter";
import $ from 'jquery/dist/jquery';

import "datatables.net-dt/js/dataTables.dataTables"
import "datatables.net-dt/css/jquery.dataTables.min.css"

$( function() {
    $( "#sort-table" ).DataTable();
} );

export default class Restaurants extends Component {
    constructor(props) {
        super(props);
    }


    render() {
        return (
            <div className="row">
                <div className="rankingPageHeader">
                    <div className="headerlogo">
                        <img src={logo} width="218" height="43"  alt=""/>
                    </div>
                    <div className="headerTitle">
                        
                    </div>

                </div>

                <div className="col-12 mx-auto">

                    <div className="card">
                        <div className="card-body">
                            <table className="table table-bordered sort-table table-condensed" id="sort-table">
                                <thead className="bg-success">
                                <tr>

                                    {this.props.formValues.map((formItem,index) => {
                                        return formItem.tag === 'glrank'  && formItem.value?
                                            <th className="text-center tableHeaderStyle">Rank</th> :
                                            formItem.tag === 'name'  && formItem.value?
                                                <th className="text-center tableHeaderStyle">Restaurant</th> :
                                                formItem.tag === 'slice'  && formItem.value?
                                                    <th className="text-center tableHeaderStyle">Goal</th>:
                                                    formItem.tag == 'hourDaily'  && formItem.value?
                                                        <th className="text-center tableHeaderStyle">Hour IP</th>:
                                                        formItem.tag == 'hourAv'  && formItem.value?
                                                            <th className="text-center tableHeaderStyle">Hour Avrg</th> :
                                                            formItem.tag == 'hourAch'  && formItem.value?
                                                                <th className="text-center tableHeaderStyle">Hour %</th> :
                                                                formItem.tag == 'hourCss'  && formItem.value?
                                                                    <th className="text-center tableHeaderStyle">Cars Hour - Today</th>:
                                                                    formItem.tag == 'dailyCss'  && formItem.value?
                                                                        <th className="text-center tableHeaderStyle">Day IP</th>:
                                                                        formItem.tag == 'dailyAv'  && formItem.value?
                                                                            <th className="text-center tableHeaderStyle">Day Avrg</th>:
                                                                            formItem.tag == 'highlight'  && formItem.value?
                                                                                <th className="text-center tableHeaderStyle">Day</th> :
                                                                                null

                                    })}
                                </tr>

                                </thead>
                                <tbody>{this.renderItems()}</tbody>

                            </table>
                        </div>
                    </div>
                </div>
                <RankingFooter/>
            </div>

        );
    }
}

预先感谢您:)

解决方法

我认为您应该尝试将jQuery脚本附加到创建的window元素上,这样它们就可以在门户网站的DOM中使用。

例如,您可以在componentDidMount()中进行操作:

let s = document.createElement("script");
s.type = "text/javascript";
s.src = "<your-js-paths>";
this.externalWindow.document.head.append(s);

除此之外,您可以添加一个事件监听器,例如

this.externalWindow.addEventListener('load',() => {
    // Code you'd like to run
});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...