Реагируйте с 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
присвойте ему начальное значение и немедленно измените компонент, если он изменится.