Изменение источника для изображения приводит к нулю его ширину / высоту при первом нажатии

#javascript #jquery #html #canvas #coffeescript

#javascript #jquery #HTML #холст #coffeescript

Вопрос:

Когда я выбираю изображение из множества вариантов, уже имеющихся на сервере, а затем нажимаю на холст, изображение будет отрисовано в том месте, на котором щелкну.

Проблема, с которой я сталкиваюсь, заключается в том, что при первом нажатии высота и ширина изображения равны нулю, и ничего не отображается. При втором нажатии это работает отлично, и это продолжает работать идеально, пока я не выберу другое изображение, а затем 1-й щелчок снова не сработает.

Я предполагаю, что, поскольку это происходит только при выборе нового источника для изображения, это как-то связано с тем, что изображение еще не было загружено, когда установлены ширина и высота.

Вот код:

где источником является пример строки: «sample/ball.png», «sample/dog.png»

Javascript:

   this.image_object = new Image();
  this.image_object.src = source;
  this.width = this.image_object.width;
  this.height = this.image_object.height;
  

Coffeescript:

 @image_object = new Image()
@image_object.src = source
@width = @image_object.width
@height = @image_object.height
  

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

Редактировать:

Я также хочу упомянуть, что ручная настройка ширины / высоты изображения «новое изображение (52,52)» по-прежнему занимает два клика, поскольку изображение не загружено.

Ответ №1:

Да, это потому, что изображение не было загружено в DOM при вызове атрибута .width. Все, что вы сделали, это установили источник. Вот почему это работает после нажатия кнопки. Вы должны загрузить изображение в DOM, прежде чем можно будет определить ширину.

Вы используете фреймворк?

Если нет, это, вероятно, поможет. http://www.webdeveloper.com/forum/showthread.php?t=108392

Комментарии:

1. Пример, на который вы ссылались, у меня не работает. Получаемое мной предупреждающее сообщение не определено с помощью undefined для width / height

Ответ №2:

Скорее всего, вы захотите загрузить все изображения сразу после загрузки страницы. Для этого я использую следующую функцию:

   loadImages = (fxDone) ->
    doneCount = 0 
    total = imageURLs.length
    for imageURL in imageURLs
      imageName = imageURL.slice(0, imageURL.lastIndexOf("."))
      images[imageName] = new Image()
      images[imageName].onload = ->
        doneCount  
        if doneCount == total
          fxDone()
      images[imageName].src = imageURL
  

Где-то за пределами этой функции imageURLs должен быть определен как список, ну, URL-адресов изображений. И images должно быть инициализировано как пустая карта. Я вызываю это в onload обработчике и передаю функцию fxDone для запуска процессов, зависящих от загружаемых изображений.

Другой вариант — загружать по щелчку, если изображение еще не загружено. Обратите внимание, что это будет немного медленнее реагировать на первый щелчок. Я бы сделал это следующим образом:

 if @images[source]?
  @width = @images[source].width
  @height = @images[source].height
else
  @images[source] = new Image()
  @images[source].onload = ->
    @width = @images[source].width
    @height = @images[source].height
  @images[source].src = source
  

Помимо этого, @images должно быть инициализировано пустой картой.

Ответ №3:

Поскольку у вас есть тег jQuery, я бы использовал jQuery для этого. Действительно, проблема в том, что ширина и высота неизвестны до тех пор, пока изображение не будет загружено. Сделайте это вместо:

 var container = this;
var theImg = $('<img/>')
    .appendTo($(container))
    .load(function() { 
        $(container).width(theImg.width()).height(theImg.height());
    })
    .attr('src', source);
  

Комментарии:

1. Ваше решение у меня не сработало. Все равно потребовалось два клика. Является ли @image_object «this» вашим примером?

2. Нет; в вашем примере кода вы устанавливаете this.width и this.height ; Я не знаю, что this есть в вашем примере кода, но мой this пытается быть таким.

3. Использование правильного this по-прежнему не решило проблему. У меня все еще есть ширина и высота 0.

4. Я упустил важную деталь; изображение, возможно, также потребуется включить в DOM, прежде чем оно получит ширину и высоту, как упоминал @polyhedron. Смотрите мой обновленный код, который также помещает вновь созданное img в контейнер.

5. Я ценю вашу помощь. К сожалению, ваше последнее решение также не работает.