Создание & lt; script & gt; теги работают с реакцией [дубликат]

Да, они будут, см. 10.4.5.1 Инициализация статического поля :

Инициализаторы статической переменной поля класса соответствуют последовательности назначений, которые выполняются в текстовом порядке, в котором они отображаются в объявлении класса. Если в классе существует статический конструктор (раздел 10.11), выполнение инициализаторов статического поля происходит непосредственно перед выполнением этого статического конструктора. В противном случае инициализаторы статического поля выполняются в зависящее от реализации время до первого использования статического поля этого класса.

blockquote>

. Говоря, я думаю, что было бы лучше сделать инициализация внутри инициализатора статического типа (статический конструктор).

11
задан meteors 25 February 2016 в 00:16
поделиться

3 ответа

Вот немного грязного способа сделать это. Немного объясняю, что происходит здесь, вы извлекаете содержимое скрипта через регулярное выражение и только визуализируете html, используя реакцию, а затем после того, как компонент монтируется содержимое в теге скрипта запускается в глобальной области.

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

var extractscript=/<script>(.+)<\/script>/gi.exec(x);
x=x.replace(extractscript[0],"");

var Hello = React.createClass({
  displayName: 'Hello',
  componentDidMount: function() {
    // this runs the contents in script tag on a window/global scope
    window.eval(extractscript[1]);

  },
  render: function() {
    return (<div dangerouslySetInnerHTML={{__html: x}} />);
  }
});

ReactDOM.render(
  React.createElement(Hello),
  document.getElementById('container')
);
10
ответ дан Dasith Kuruppu 19 August 2018 в 02:16
поделиться
  • 1
    благодаря этому решена проблема. – meteors 25 February 2016 в 10:33
  • 2
    Что делать, если есть несколько тегов скриптов? – Elton Jain 1 August 2017 в 12:05
  • 3
    для тега многострочного скрипта выражение reg может не работать, попробуйте var extractscript = / & lt; script & gt; [\ s \ S] * & lt; \ / script & gt; /gi.exec (x); – super1ha1 14 August 2017 в 02:06

Я не думаю, что вам нужно использовать конкатенацию (+) здесь.

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

Я думаю, что вы можете просто сделать:

var x = '<html><script>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</script><body><p onClick="pClicked()">Hello</p></body></html>';

Поскольку он передан dangerouslySetInnerHTML.

Но вернемся к проблеме. Вам не нужно использовать регулярное выражение для доступа к содержимому тега скрипта. Если вы добавите атрибут id, например <script id="myId">...</script>, вы можете легко получить доступ к элементу.

Давайте посмотрим пример такой реализации.

const x = `
  <html>
    <script id="myScript">
      alert("this.is.sparta");
      function pClicked() {console.log("p is clicked");}
    </script>
    <body>
      <p onClick="pClicked()">Hello</p>
    </body>
  </html>
`;

const Hello = React.createClass({

  displayName: 'Hello',

  componentDidMount() {
    const script = document.getElementById('myScript').innerHTML;
    window.eval(script);
  }

  render() {
    return <div dangerouslySetInnerHTML={{__html: x}} />;
  }

});

Если у вас несколько скрипты, вы можете добавить атрибут данных [data-my-script], например, и затем получить к нему доступ с помощью jQuery:

const x = `
  <html>
    <script data-my-script="">
      alert("this.is.sparta");
      function pClicked() {console.log("p is clicked");}
    </script>
    <script data-my-script="">
      alert("another script");
    </script>
    <body>
      <p onClick="pClicked()">Hello</p>
    </body>
  </html>
`;

const Hello = React.createClass({

  constructor(props) {
    super(props);

    this.helloElement = null;
  }

  displayName: 'Hello',

  componentDidMount() {
    $(this.helloElement).find('[data-my-script]').each(function forEachScript() {
      const script = $(this).text();
      window.eval(script);
    });
  }

  render() {
    return (
      <div
        ref={helloElement => (this.helloElement = helloElement)} 
        dangerouslySetInnerHTML={{__html: x}} 
      />
    );
  }

});

В любом случае всегда полезно избегать использования eval, поэтому другой вариант получите текст и добавьте новый тег скрипта с содержимым скрипта оригинала вместо вызова eval. Этот ответ предлагает такой подход

3
ответ дан emil.c 19 August 2018 в 02:16
поделиться

небольшое расширение для ответа Дасита для будущих просмотров ...

У меня была очень похожая проблема, но в моем случае я получил HTML с серверной части, и это заняло некоторое время (часть отчетов решение, где бэкэнд будет отображать отчет в html)

, поэтому то, что я сделал, было очень похоже только на то, что я обработал скрипт, запущенный в функции componentWillMount ():

import React from 'react';
import jsreport from 'jsreport-browser-client-dist'
import logo from './logo.svg';
import './App.css';

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            report: "",
            reportScript: ""
        }
    }

    componentWillMount() {
        jsreport.serverUrl = 'http://localhost:5488';
        let reportRequest = {template: {shortid: 'HJH11D83ce'}}
        // let temp = "this is temp"
        jsreport.renderAsync(reportRequest)
            .then(res => {
                let htmlResponse = res.toString()
                let extractedScript = /<script>[\s\S]*<\/script>/g.exec(htmlResponse)[0];
                // console.log('html is: ',htmlResponse)
                // console.log('script is: ',extractedScript)
                this.setState({report: htmlResponse})
                this.setState({reportScript: extractedScript})
            })
    }

    render() {
        let report = this.state.report
        return (
            <div className="App">
                <div className="App-header">
                    <img src={logo} className="App-logo" alt="logo"/>
                    <h2>Welcome to React</h2>
                </div>
                <div id="reportPlaceholder">
                    <div dangerouslySetInnerHTML={{__html: report}}/>

                </div>
            </div>
        );
    }

    componentDidUpdate() {
        // this runs the contents in script tag on a window/global scope
        let scriptToRun = this.state.reportScript
        if (scriptToRun !== undefined) {
            //remove <script> and </script> tags since eval expects only code without html tags
            let scriptLines = scriptToRun.split("\n")
            scriptLines.pop()
            scriptLines.shift()
            let cleanScript = scriptLines.join("\n")
            console.log('running script ',cleanScript)
            window.eval(cleanScript)
        }

    }
}

export default App;

надеюсь, что это полезно ...

1
ответ дан Tal Joffe 19 August 2018 в 02:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: