Реагируйте с imagesLoaded и разрешите значение для окончательного рендеринга.

У меня есть класс с именем PhotoTags, у которого есть функция getScalePercent(). В getScalePercent я делаю простой расчет ширины и высоты отображаемого изображения и возвращаю значение. В функции рендеринга PhotoTags я использую данные координат для наложения элементов на фотографию. Эта логика прекрасно работает, только если изображение загружено на 100%. Если я обновляю страницу достаточно раз, я вижу, что моя логика на самом деле правильно устанавливает координаты, но только после того, как изображение было либо кэшировано, либо загружено быстро. Поэтому я хочу использовать imagesLoaded для проверки загрузки изображения, чтобы эффективно использовать координаты.

Моя функция выглядит так:

getScalePercent(){
        var p =0;
        var targetWidth = $('.expanded-image').width();
        var targetHeight = $('.expanded-image').height();
        p = (targetWidth / 1920);
        return p;
}

И в моей функции рендеринга я пытаюсь использовать imagesLoaded, чтобы проверить, было ли загружено изображение перед использованием getScalePercent():

render(){
   var p = 0;

   $('.expanded-image').imagesLoaded().done( function() {
        p = this.getScalePercent();
   });

   console.log(p); //But value is still 0

   //I then want to use p later in the render function

Моя переменная p не обрабатывается в событии.done imagesLoaded. Я знаю, что это как-то связано с асинхронными вызовами, а что нет, и я пытался поместить imagesLoaded в getScalePercent(), но безрезультатно. Я также попытался сделать обратный вызов getScalePercent() и многих других вариантов, но все еще безрезультатно. По сути, я хочу запустить getScalePercent() внутри события.done() imagesLoaded. Затем я хочу иметь возможность использовать значение, которое getScalePercent() возвращает (когда изображение полностью загружено) внутри функции рендеринга PhotoTags. Буду признателен за любую оказанную помощь.

2 ответа

Решение

Не лучше ли добавить на изображение событие onLoad, например:

class Test extends Component {
    constructor (props){
        super(props);
        this.state = {
            imgLoaded:false
        }
    }
    handleImgLoaded (event){
        // Do stuff
        console.log(event.target);
        this.setState({
            imgLoaded:true
        });
    }
    render (){           
        <div className={'img-wrapper-class ' + (this.state.imgLoaded ? 'img-loaded' : 'img-loading')}>
            <img src={"somesrc.jpg"} onLoad={this.handleImgLoaded.bind(this)} />
        </div>
    }
}

Я уверен, что проблема в том, что элемент DOM .expanded-image фактически не загружается в DOM при первом рендере. Попробуйте переместить эту логику в componentDidMount и это должно работать нормально. Вы также хотите сохранить p в состоянии, чтобы вы могли ссылаться на него за пределами componentDidMountприсвойте ему начальное значение и немедленно измените компонент, если он изменится.

Другие вопросы по тегам