Изменение атрибута src изображения с помощью jQuery не всегда применяется в Chrome/Opera

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

$('#magviewplus').attr('src', '/photos/original-snippet.php?id=<?php echo $nID?>&x='+left+'&y='+top).load(function() {
    window.clearInterval(maginterval);
    magtimer=3;
    maginterval=window.setInterval(magViewCountdown,1000);
    $('#clicktoenhance').html('Exiting in '+magtimer+'s...');
});

Почему-то с перерывами. Fiddler показывает, что фрагмент загружается всегда, но отображается только иногда. Даже когда он не отображается, код в событии load() работает нормально.

Таким образом, он думает, что он загружен, Fiddler показывает, что он загружен, но примерно в 50% случаев на самом деле он не отображается там, где должен.

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

Любые идеи?

изменить: это на самом деле ограничено Chrome и Opera, но отлично работает в Firefox/IE11.


person Codemonkey    schedule 08.04.2015    source источник
comment
что делает magViewCountdown?   -  person mplungjan    schedule 08.04.2015
comment
Ничего важного - просто обновляет текст clicktoenhance - показывает обратный отсчет, а затем скрывает окно, когда обратный отсчет закончился.   -  person Codemonkey    schedule 08.04.2015
comment
@Codemonkey Разве вы не используете плагины Adblock в Chrome и Firefox? Возможно, им не нравится .php в вашем образе src   -  person Kevin    schedule 05.05.2015
comment
@Codemonkey Что произойдет, если я перейду к '/photos/original-snippet.php?id=123 ..'?   -  person Kevin    schedule 05.05.2015
comment
Нет рекламного блока и т. д. И если вы перейдете по URL-адресу, вы увидите изображение, как если бы вы перешли к my-photo.jpg. Он подается с правильным типом пантомимы, если это то, что вам интересно.   -  person Codemonkey    schedule 05.05.2015
comment
Можете ли вы воспроизвести эту проблему на скрипке? Вероятно, вы обнаружите проблему, пытаясь создать скрипку...   -  person Denys Séguret    schedule 05.05.2015
comment
@Codemonkey Ответ на этот вопрос дан, но не к моему удовлетворению, поэтому из любопытства, не могли бы вы попробовать это в своем коде и сказать мне, имеет ли это какой-либо эффект? Просто измените $('#magviewplus').attr на $('#magviewplus').unbind("load").attr. Спасибо.   -  person Drakes    schedule 06.05.2015


Ответы (6)


Похоже, ваша проблема хорошо задокументирована, как видно из следующих сообщений:

  1. обратный вызов jquery при загрузке изображения при изменении источника

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

  3. обратный вызов jQuery при загрузке изображения (даже если изображение кэшируется)

Я бы посоветовал вам загрузить новое изображение в память, а затем, когда срабатывает событие загрузки этого нового изображения, изменить src фактического изображения и сделать все, что нужно сделать. Исходное изображение остается нетронутым, и любые другие события (кроме загрузки), прикрепленные к нему, должны оставаться нетронутыми:

$(new Image()).attr('src', '/photos/original-snippet.php?id=<?php echo $nID?>&x=' + left + '&y=' + top).load(function() {
    $('#magviewplus').attr('src', this.src);
    window.clearInterval(maginterval);
    magtimer = 3;
    maginterval = window.setInterval(magViewCountdown,1000);
    $('#clicktoenhance').html('Exiting in ' + magtimer + 's...');
});

ДЕМО

person PeterKA    schedule 05.05.2015
comment
Я по-прежнему утверждаю, что мой вопрос не о событии загрузки как таковом.... Но загрузка src в память, а затем назначение (через событие загрузки...) изображению, похоже, исправило вещи, я думаю . Я проверю в течение дня и посмотрю, постоянно ли это исправлено, прежде чем принять. - person Codemonkey; 06.05.2015
comment
Сообщите мне о своих выводах, как только завершите тестирование. И, если вы выясните, что, по вашему мнению, может быть причиной проблемы, не стесняйтесь поделиться; если вы можете предоставить демонстрацию, это будет гигантским шагом к поиску основной причины. - person PeterKA; 06.05.2015
comment
Мне пришлось настроить кэширование, чтобы избежать двойной загрузки изображения (что, очевидно, замедлило его) с использованием вашего кода, но теперь, когда я это сделал, все кажется довольно хорошим. Боюсь, у меня нет ни времени, ни желания разбирать его на демо... :( - person Codemonkey; 06.05.2015

отредактировано, чтобы показать, что это не работает...

Сначала казалось, что прагматичным «решением» было удалить и снова добавить изображение:

<div id="magviewholder"><img id="magviewplus" src="pixel.gif" alt=""></div>

Вот так:

$('#magviewholder').children("img").remove()
$('#magviewholder').append('<img>');

$('#magviewholder>img').attr('onerror','imgError(this)').attr('id','magviewplus').attr('src', '/photos/original-snippet.php?id=<?php echo $nID?>&x='+left+'&y='+top).load(function() {
     window.clearInterval(maginterval);
     magtimer=3;
     maginterval=window.setInterval(magViewCountdown,1000);
     $('#clicktoenhance').html('Exiting in '+magtimer+'s...');
 });

Сначала это работало во всех браузерах, но теперь, кажется, так же прерывисто...

person Codemonkey    schedule 28.04.2015
comment
можете ли вы предоставить шаги, которые приводят к отображению изображения? например... User clicks on image.. user taken to page X... page loads... on page load the image src is replaced... on some other function x happens... и зачем использовать нагрузку? может быть, предоставить демонстрацию того, что вы делаете? - person Cayce K; 05.05.2015


Используйте .load() для загрузки изображения:

$('#magviewplus').load('/photos/original-snippet.php?id=<?php echo $nID?>&x='+left+'&y='+top, function() {
    window.clearInterval(maginterval);
    magtimer=3;
    maginterval=window.setInterval(magViewCountdown,1000);
    $('#clicktoenhance').html('Exiting in '+magtimer+'s...');
});
person Brijesh Bhatt    schedule 08.04.2015
comment
Я попробовал это, и, похоже, он вообще не работает, и, глядя на документы jquery, которые, похоже, предназначены для фрагментов HTML, так что в этом сценарии это не сработает. - person Codemonkey; 08.04.2015

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

$('#loadbtn').click(function(){
  $('#msg').html("loading...");
  $('#myimg').attr("src", "http://cache1.asset-cache.net/xt/165920320.jpg?v=1&g=fs1%7C0%7CISI%7C20%7C320&s=1" + 
    "&rnd=" + Math.random());
});

$('#myimg').load(function(){
  $('#msg').html("loaded");
});
#loadbtn {
  margin: 16px;
}
#msg {
  margin: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id='myimg' src='http://cache1.asset-cache.net/xt/165920320.jpg?v=1&g=fs1%7C0%7CISI%7C20%7C320&s=1' />
<div>
  <input type=button id='loadbtn' value='reload' />
</div>
<div id='msg'>loading...</div>

person Alexander Dayan    schedule 05.05.2015
comment
Я четко указал в вопросе, что вижу, как ресурс загружается в Fiddler. Следовательно, это не проблема кэширования. И большинство запросов уже новые/уникальные. - person Codemonkey; 06.05.2015

Попробуйте поместить свойство "name" в тег с тем же значением, что и свойство "id".

<id="magviewplus" name="magviewplus".../>

таким образом, jquery даже в chrome определяет атрибут и правильно изменяет его, в более старых версиях jquery я игнорирую, если это работает, надеюсь, что это поможет

person Marco Antonio Chan Cruz    schedule 19.11.2015