โหลดรูปภาพแบบอะซิงโครนัสด้วย jQuery


142

ฉันต้องการโหลดภาพภายนอกบนหน้าของฉันแบบอะซิงโครนัสโดยใช้ jQueryและฉันได้ลองทำสิ่งต่อไปนี้แล้ว:

$.ajax({ 
   url: "http://somedomain.com/image.jpg", 
   timeout:5000,
   success: function() {

   },
   error: function(r,x) {

   }
});

แต่มันกลับข้อผิดพลาดอยู่เสมอมันเป็นไปได้ไหมที่จะโหลดภาพเช่นนี้?

ฉันพยายามใช้.loadวิธีการและใช้งานได้ แต่ฉันไม่รู้ว่าจะกำหนดไทม์เอาต์ได้อย่างไรหากภาพไม่พร้อมใช้งาน (404) ฉันจะทำสิ่งนี้ได้อย่างไร


สิ่งนี้ใช้ได้กับฉัน: stackoverflow.com/questions/6150289/…
MrRhoads

คำตอบ:


199

ไม่จำเป็นต้องมีอาแจ็กซ์ คุณสามารถสร้างองค์ประกอบภาพใหม่ตั้งค่าแอตทริบิวต์ต้นฉบับและวางองค์ประกอบอื่นในเอกสารเมื่อโหลดเสร็จแล้ว:

var img = $("<img />").attr('src', 'http://somedomain.com/image.jpg')
    .on('load', function() {
        if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
            alert('broken image!');
        } else {
            $("#something").append(img);
        }
    });

20
จะทำอย่างไรกับ timeout และ 404
Arief

1
วิธีการตั้งค่าการหมดเวลากับสิ่งนี้? ฉันลองใช้วิธีนี้ แต่อย่างใดหน้ายังคงรอให้โหลดภาพ
Arief

7
หากคุณตรวจสอบไทม์ไลน์ของเบราว์เซอร์ของคุณเช่นไทม์ไลน์เครื่องมือ dev ของ Google Chrome คุณจะเห็นว่าการสร้างองค์ประกอบ DOM ใด ๆ (ไม่ว่าคุณจะแนบมันเข้ากับ DOM นั้นจะไม่เกี่ยวข้องหรือไม่ก็ตาม) จากนั้นการตั้งค่าแหล่งที่มานั้น รายการ - ดังนั้นหน้าจะไม่เสร็จ "โหลด" จนกว่าองค์ประกอบที่สร้างจะถูกโหลด วิธีการแก้ปัญหาของคุณเป็นจริงไม่ได้เป็นเหตุการณ์ asyncrhonous ในแง่ที่ว่า window.load () จะไม่ยิงจนกระทั่งภาพที่มีการโหลดอาจจะชะลอการบางอย่างpaintหรือlayoutการดำเนินงานและแน่นอนการล่าช้าใด ๆonloadอ้างอิงเหตุการณ์
Tom Auger

2
@TomAuger: แล้วเราจะทำให้มันไม่ตรงกันได้อย่างไร? ฉันเพิ่งทดสอบโค้ดด้วย load () และมันไม่ได้เป็นแบบอะซิงโครนัส
basZero

2
@gidzior ไม่ทำงานใน IE8 เพราะคุณไม่สามารถตั้งค่าแอตทริบิวต์ SRC ใน IE8 โดยใช้ jquery อ้างอิงที่นี่: stackoverflow.com/questions/12107487/…
Rich

78

หากคุณต้องการใช้ AJAX จริงๆ ...

ฉันได้พบกับเราโดยที่ตัวจัดการ onload ไม่ใช่ตัวเลือกที่ถูกต้อง ในกรณีของฉันเมื่อพิมพ์ผ่านจาวาสคริปต์ ดังนั้นจริงๆแล้วมีสองตัวเลือกในการใช้สไตล์ AJAX สำหรับสิ่งนี้:

โซลูชันที่ 1

ใช้ข้อมูลภาพ Base64 และบริการรูปภาพ REST หากคุณมีเว็บเซอร์วิซของคุณเองคุณสามารถเพิ่มสคริปต์ JSP / PHP REST ที่ให้ภาพในการเข้ารหัส Base64 ตอนนี้มีประโยชน์อย่างไร ฉันเจอไวยากรณ์ใหม่ที่ยอดเยี่ยมสำหรับการเข้ารหัสภาพ:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhE..."/>

ดังนั้นคุณสามารถโหลดข้อมูลภาพ Base64 โดยใช้ Ajax และเมื่อเสร็จแล้วคุณจะสร้างสตริงข้อมูล Base64 ลงในภาพ! สนุกดี :). ฉันแนะนำให้ใช้เว็บไซต์นี้http://www.freeformatter.com/base64-encoder.htmlสำหรับการเข้ารหัสภาพ

$.ajax({ 
    url : 'BASE64_IMAGE_REST_URL', 
    processData : false,
}).always(function(b64data){
    $("#IMAGE_ID").attr("src", "data:image/png;base64,"+b64data);
});

Solution2:

หลอกเบราว์เซอร์ให้ใช้แคช สิ่งนี้จะช่วยให้คุณ fadeIn () ดีเมื่อทรัพยากรอยู่ในแคชเบราว์เซอร์:

var url = 'IMAGE_URL';
$.ajax({ 
    url : url, 
    cache: true,
    processData : false,
}).always(function(){
    $("#IMAGE_ID").attr("src", url).fadeIn();
});   

อย่างไรก็ตามทั้งสองวิธีมีข้อเสีย: วิธีแรกใช้ได้กับเบราว์เซอร์สมัยใหม่เท่านั้น ส่วนที่สองมีข้อบกพร่องด้านประสิทธิภาพและขึ้นอยู่กับการสันนิษฐานว่าจะใช้แคชอย่างไร

ไชโย


1
หากสถานะปัจจุบันของการสนับสนุนเบราว์เซอร์เป็นที่ยอมรับของคุณ ( caniuse.com/#search=Blob ) คุณสามารถใช้Blobsแทนข้อมูล URI สิ่งนี้ 'รู้สึก' แฮ็คน้อยกว่าการใช้ URIs ที่เข้ารหัสด้วย data64 และยังสิ้นเปลืองหน่วยความจำน้อยกว่า (เนื่องจาก base64 ไม่ใช่รูปแบบที่มีประสิทธิภาพของหน่วยความจำ) แม้ว่าหลังอาจไม่ได้ใช้เวลาส่วนใหญ่ในโลกแห่งความเป็นจริง
Mark Amery

11

การใช้ jQuery คุณสามารถเปลี่ยนแอตทริบิวต์ "src" เป็น "data-src" ภาพจะไม่ถูกโหลด แต่ตำแหน่งจะถูกเก็บไว้ด้วยแท็ก ซึ่งฉันชอบ

<img class="loadlater" data-src="path/to/image.ext"/>

ชิ้นส่วนที่เรียบง่ายของ jQuery คัดลอก data-src ไปยัง src ซึ่งจะเริ่มโหลดรูปภาพเมื่อคุณต้องการ ในกรณีของฉันเมื่อหน้าโหลดเสร็จ

$(document).ready(function(){
    $(".loadlater").each(function(index, element){
        $(element).attr("src", $(element).attr("data-src"));
    });
});

ฉันเดิมพันรหัส jQuery อาจเป็นตัวย่อ แต่ก็เข้าใจได้ด้วยวิธีนี้


4
เคล็ดลับ: หากคุณกำลังใช้data-แท็กคุณสามารถเข้าถึงแท็กเหล่านี้ได้ง่ายกว่า$(element).data('src')แทนที่จะเป็น$(element).attr('data-src')
Maxim Kumpan

จริงวันนี้ฉันจะไม่ใช้ jQuery อีกต่อไป แต่นั่นเป็นคำถามของรสนิยมส่วนตัวและขึ้นอยู่กับขนาดของเว็บไซต์ที่คุณกำลังสร้าง แต่หัวข้อที่ร้อนแรงของเวลาคือ "ภาพโปรเกรสซีฟ" บางทีนั่นอาจเป็นสิ่งที่ต้องพิจารณา smashingmagazine.com/2018/02/…
htho

8
$(<img />).attr('src','http://somedomain.com/image.jpg');

ควรจะดีกว่าอาแจ็กซ์เพราะถ้าเป็นแกลเลอรี่และคุณวนลูปผ่านรายการภาพถ้าภาพอยู่ในแคชแล้วมันจะไม่ส่งคำขอไปยังเซิร์ฟเวอร์อีก มันจะร้องขอในกรณีของ jQuery / ajax และส่งคืน HTTP 304 (ไม่ได้แก้ไข) จากนั้นใช้อิมเมจดั้งเดิมจากแคชหากมีอยู่แล้ว วิธีการด้านบนลดการร้องขอที่ว่างเปล่าไปยังเซิร์ฟเวอร์หลังจากวนรอบแรกของรูปภาพในแกลเลอรี


4

คุณสามารถใช้วัตถุที่เลื่อนออกไปสำหรับการโหลด ASYNC

function load_img_async(source) {
    return $.Deferred (function (task) {
        var image = new Image();
        image.onload = function () {task.resolve(image);}
        image.onerror = function () {task.reject();}
        image.src=source;
    }).promise();
}

$.when(load_img_async(IMAGE_URL)).done(function (image) {
    $(#id).empty().append(image);
});

โปรดใส่ใจ: image.onload ต้องอยู่ก่อน image.src เพื่อป้องกันปัญหาเกี่ยวกับแคช


3

หากคุณต้องการตั้งค่าแหล่งที่มาของภาพคุณสามารถใช้สิ่งนี้

$("img").attr('src','http://somedomain.com/image.jpg');


2

AFAIK คุณจะต้องทำฟังก์ชั่น. load () ที่นี่ตามที่ระบุไว้ใน. jax () แต่คุณสามารถใช้ jQuery setTimeout เพื่อให้มันมีชีวิตอยู่ (ish)

<script>
 $(document).ready(function() {
 $.ajaxSetup({
    cache: false
});
 $("#placeholder").load("PATH TO IMAGE");
   var refreshId = setInterval(function() {
      $("#placeholder").load("PATH TO IMAGE");
   }, 500);
});
</script>

2
ขอโทษฉันเข้าใจผิดเล็กน้อย Q ของคุณฉันคิดว่าคุณกำลังโหลดภาพที่กำลังเปลี่ยนแปลงหรือบางสิ่งบางอย่าง (ดังนั้น ajax bit)
benhowdle89

2

ใช้. load เพื่อโหลดรูปภาพของคุณ เพื่อทดสอบว่าคุณได้รับข้อผิดพลาด (สมมุติว่า 404) คุณสามารถทำสิ่งต่อไปนี้:

$("#img_id").error(function(){
  //$(this).hide();
  //alert("img not loaded");
  //some action you whant here
});

ระวัง - .error () เหตุการณ์จะไม่ทริกเกอร์เมื่อแอตทริบิวต์ src ว่างเปล่าสำหรับภาพ


0

$ (ฟังก์ชั่น () {

    if ($('#hdnFromGLMS')[0].value == 'MB9262') {
        $('.clr').append('<img src="~/Images/CDAB_london.jpg">');
    }
    else
    {
        $('.clr').css("display", "none");
        $('#imgIreland').css("display", "block");
        $('.clrIrland').append('<img src="~/Images/Ireland-v1.jpg">');
    }
});

มันทำงานได้อย่างสมบูรณ์แบบในขณะที่โหลดโฮมเพจเราสามารถตั้งค่าภาพต่าง ๆ - จาก Polaris
MadhaviLatha Bathini

ความยุ่งเหยิงมากเกินไปไม่เกี่ยวข้องกับการตอบคำถาม
Maxim Kumpan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.