2017-02-04 4 views
2
  • Типичное решение проблемы не работает в React из-за его динамически генерируемую структуру компонентов и события модели, в отличии от традиционных статического HTML:

сценарий:Настройка высоты IFrame для scrollHeight в ReactJS

<script> 
    function resizeIframe(obj) { 
    obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px'; 
    } 
</script> 

HTML:

<iframe src="..." frameborder="0" scrolling="no" onload="resizeIframe(this)" /> 
  • Существует НПЙ пакет react-iframe, но выглядит незаконченным (принимает только реквизит url, width, height):

    https://www.npmjs.com/package/react-iframe

  • Вероятная часть раствора, чтобы прослушать load событие iframe, но таким образом, который совместим с React.

Есть ли способ в React, чтобы установить высоту в iframe на высоту его прокручивать содержимое?

мой код:

import React, { Component } from 'react' 
import ReactDOM from 'react-dom' 
import Iframe from 'react-iframe' 

export default class FullheightIframe extends Component { 

    componentDidMount() { 
     console.log("IFRAME DID MOUNT"); 
    } 

    renderReactFrame() { 
     return (
      <Iframe url="http://www.example.com" width="100%" height="100%" onLoad={()=>{console.log("IFRAME ON LOAD")}}></Iframe> 
     ); 
    } 

    renderHTMLFrame() { 
     return (
      <iframe 
       onLoad={(loadEvent)=>{ 
        // NOT WORKING var frameBody = ReactDOM.findDOMNode(this).contentDocument.body; // contentDocument undefined 
        // NOT WORKING obj.nativeEvent.contentWindow.document.body.scrollHeight // contentWindow undefined 
       }} 
       ref="iframe" 
       src="http://www.example.com" 
       width="100%" 
       height="100%" 
       scrolling="no" 
       frameBorder="0" 
      /> 
     ); 
    } 

    render() { 
     return (
      <div style={{maxWidth:640, width:'100%', height:'100%', overflow:'auto'}}> 
       {this.renderHTMLFrame()} 
      </div> 
     ); 
    } 
} 

ответ

1

То, что вы хотите сделать, это в вашем componentDidMount, запустите скрипт, чтобы установить высоту. [При загрузке внешнего контента, вы можете добавить прослушиватель событий на IFrame, чтобы подождать, пока не будет загружен внешнее содержимое.]

componentDidMount() { 
     const obj = ReactDOM.findDOMNode(this); 
     obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px'; 
    } 

Существует еще один, более «reacty» способ сделать это - где ты будет хранить высоту в состоянии.

componentDidMount() { 
     const obj = ReactDOM.findDOMNode(this); 
     this.setState("iFrameHeight", obj.contentWindow.document.body.scrollHeight + 'px'); 
    } 

, а затем в рендеринге:

render() { 
    return (
     <div style={{maxWidth:640, width:'100%', height:this.state.iFrameHeight, overflow:'auto'}}> 
      {this.renderHTMLFrame()} 
     </div> 
    ); 
} 
+0

Это решение должно работать, но это не делает (не находя 'obj'):' неперехваченным TypeError: не удается прочитать свойство 'документ' в undefined' –

+0

Update: Это было исправлено с использованием 'iframe' в качестве корневого элемента в методе возврата компонента. Теперь проблема заключается в том, что высота устанавливается на '8px'. Вероятно, потому что iframe еще не полностью загружен. –

+0

Невозможно прочитать документ свойства undefined - это означает, что contentWindow не найден - это значит, что iFrame не загружается. Это означает, что вам нужно добавить прослушиватель событий в iFrame - iframe.addEventListener ('load', function() {... –

2

Вот ответ, но первые две важные вещи.

  • Iframe должен быть корневым компонентом в render() методе
  • Высота должна быть захваченными из onLoad события (как только IFrame, если полностью загружены)

Вот полный код:

import React, { Component, PropTypes } from 'react' 
import ReactDOM from 'react-dom' 

export default class FullheightIframe extends Component { 

    constructor() { 
     super(); 
     this.state = { 
      iFrameHeight: '0px' 
     } 
    } 

    render() { 
     return (
      <iframe 
       style={{maxWidth:640, width:'100%', height:this.state.iFrameHeight, overflow:'visible'}} 
       onLoad={() => { 
        const obj = ReactDOM.findDOMNode(this); 
        this.setState({ 
         "iFrameHeight": obj.contentWindow.document.body.scrollHeight + 'px' 
        }); 
       }} 
       ref="iframe" 
       src="http://www.example.com" 
       width="100%" 
       height={this.state.iFrameHeight} 
       scrolling="no" 
       frameBorder="0" 
      /> 
     ); 
    } 
} 
+1

Это не работает в перекрестном происхождении. Кто-нибудь знает, как это сделать в кросс-начале? – cabaji99

+0

@ cabaji99 Большинство инструментов изменения размера, связанных с iframe, не будут работать с перекрестным началом. cross-origin, на третьей стороне страницы должен быть добавлен код, который разрешает и обрабатывает связь с родительской страницей. –

Смежные вопросы