Промяната на 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
Нищо релевантно - просто актуализира текста за щракване за подобряване - показва обратно броене и след това скрива полето, когато обратното броене приключи.   -  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. Сервира се с правилния тип mime, ако това се чудите.   -  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 при зареждане на изображение при промяна на src

  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... също защо да използвам load? може би да предоставите демонстрация на това, което правите? - 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