【问题标题】:Execute Jquery in React Portals在 React 门户中执行 Jquery
【发布时间】:2020-08-17 08:23:58
【问题描述】:

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

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

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

在我的父组件中加载带有“餐厅”组件的门户

<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 reactjs datatables react-portal


    【解决方案1】:

    我认为您应该尝试将 jQuery 脚本附加到您创建的窗口元素中,这样它们就可以在门户的 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
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-18
      • 2012-04-04
      • 1970-01-01
      • 2014-02-06
      • 2013-05-19
      • 1970-01-01
      • 2019-12-13
      • 2011-06-29
      相关资源
      最近更新 更多