ฉันต้องการทำ:
$("img").bind('load', function() {
// do stuff
});
แต่เหตุการณ์โหลดไม่เริ่มทำงานเมื่อโหลดภาพจากแคช jQuery docsแนะนำให้ใช้ปลั๊กอินเพื่อแก้ไขปัญหานี้ แต่มันไม่ทำงาน
ฉันต้องการทำ:
$("img").bind('load', function() {
// do stuff
});
แต่เหตุการณ์โหลดไม่เริ่มทำงานเมื่อโหลดภาพจากแคช jQuery docsแนะนำให้ใช้ปลั๊กอินเพื่อแก้ไขปัญหานี้ แต่มันไม่ทำงาน
คำตอบ:
หากsrc
ตั้งค่าไว้แล้วเหตุการณ์จะเริ่มทำงานในกรณีที่แคชก่อนที่คุณจะได้รับตัวจัดการเหตุการณ์ที่ถูกผูกไว้ ในการแก้ไขปัญหานี้คุณสามารถวนซ้ำการตรวจสอบและกระตุ้นให้เกิดเหตุการณ์ตาม.complete
เช่นนี้:
$("img").one("load", function() {
// do stuff
}).each(function() {
if(this.complete) {
$(this).load(); // For jQuery < 3.0
// $(this).trigger('load'); // For jQuery >= 3.0
}
});
บันทึกการเปลี่ยนแปลงจาก.bind()
เป็น.one()
เพื่อให้ตัวจัดการเหตุการณ์ไม่ทำงานสองครั้ง
setTimeout(function(){//do stuff},0)
ภายใน 'โหลด' ฟังก์ชั่น ... 0ให้ระบบเบราว์เซอร์ (DOM) เห็บพิเศษหนึ่งเพื่อให้แน่ใจว่าทุกอย่างมีการปรับปรุงอย่างถูกต้อง
.load()
ไม่ทริกเกอร์เหตุการณ์และมีอาร์กิวเมนต์ที่จำเป็น 1 ข้อให้ใช้.trigger("load")
แทน
ฉันขอแนะนำให้คุณโหลดมันใหม่ไปเป็นวัตถุอิมเมจที่ไม่ใช่ DOM ได้ไหม? หากแคชแล้วจะไม่ใช้เวลาเลยและ onload จะยังคงทำงานต่อไป หากไม่มีการแคชแคชจะทำการโหลด onload เมื่อโหลดอิมเมจซึ่งควรเป็นเวลาเดียวกันกับที่เวอร์ชัน DOM ของอิมเมจเสร็จสิ้นการโหลด
javascript:
$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.src = $('#img').attr('src') ;
tmpImg.onload = function() {
// Run onload code.
} ;
}) ;
อัปเดต (เพื่อจัดการภาพหลายภาพและมีไฟล์แนบ onload ที่สั่งซื้ออย่างถูกต้อง):
$(document).ready(function() {
var imageLoaded = function() {
// Run onload code.
}
$('#img').each(function() {
var tmpImg = new Image() ;
tmpImg.onload = imageLoaded ;
tmpImg.src = $(this).attr('src') ;
}) ;
}) ;
load
จัดการก่อนที่มันเพิ่มยังนี้จะไม่ทำงาน แต่สำหรับภาพหนึ่งตรวจการณ์การทำงานสำหรับหลาย ๆ :)
#img
เป็น ID ไม่ใช่ตัวเลือกองค์ประกอบ :) ใช้this.src
งานได้โดยไม่จำเป็นต้องใช้ jQuery โดยที่ไม่จำเป็น :) แต่การสร้างภาพอื่นดูเหมือนว่า overkill ในกรณี IMO
imageLoaded
ให้ใช้tmp.onload = imageLoaded.bind(this)
โซลูชันที่เรียบง่ายของฉันไม่จำเป็นต้องใช้ปลั๊กอินภายนอกและสำหรับกรณีทั่วไปควรจะเพียงพอ:
/**
* Trigger a callback when the selected images are loaded:
* @param {String} selector
* @param {Function} callback
*/
var onImgLoad = function(selector, callback){
$(selector).each(function(){
if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
callback.apply(this);
}
else {
$(this).on('load', function(){
callback.apply(this);
});
}
});
};
ใช้มันแบบนี้:
onImgLoad('img', function(){
// do stuff
});
ตัวอย่างเช่นในการโหลดภาพของคุณให้จางลงคุณสามารถทำได้:
$('img').hide();
onImgLoad('img', function(){
$(this).fadeIn(700);
});
หรือเป็นทางเลือกถ้าคุณชอบแนวทางคล้ายกับ jquery:
/**
* Trigger a callback when 'this' image is loaded:
* @param {Function} callback
*/
(function($){
$.fn.imgLoad = function(callback) {
return this.each(function() {
if (callback) {
if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
callback.apply(this);
}
else {
$(this).on('load', function(){
callback.apply(this);
});
}
}
});
};
})(jQuery);
และใช้วิธีนี้:
$('img').imgLoad(function(){
// do stuff
});
ตัวอย่างเช่น:
$('img').hide().imgLoad(function(){
$(this).fadeIn(700);
});
width
, max-height
และลาheight:auto
มักจะเป็นสิ่งจำเป็นในการตั้งค่าทั้งความกว้างและความสูงเพียงถ้าคุณจำเป็นต้องยืดภาพ; สำหรับโซลูชันที่มีประสิทธิภาพยิ่งขึ้นฉันจะใช้ปลั๊กอินเช่นImagesLoaded
คุณต้องทำกับ jQuery จริงๆเหรอ? คุณสามารถแนบonload
กิจกรรมโดยตรงกับภาพของคุณเช่นกัน
<img src="/path/to/image.jpg" onload="doStuff(this);" />
มันจะเริ่มทำงานทุกครั้งที่โหลดภาพจากแคชหรือไม่
onload
ตัวจัดการจะเริ่มทำงานเมื่อภาพถูกโหลดครั้งที่สองจากแคชหรือไม่
นอกจากนี้คุณยังสามารถใช้รหัสนี้พร้อมการสนับสนุนสำหรับข้อผิดพลาดในการโหลด:
$("img").on('load', function() {
// do stuff on success
})
.on('error', function() {
// do stuff on smth wrong (error 404, etc.)
})
.each(function() {
if(this.complete) {
$(this).load();
} else if(this.error) {
$(this).error();
}
});
load
ตัวจัดการก่อนแล้วจึงเรียกมันภายหลังในeach
ฟังก์ชั่น
ฉันเพิ่งพบปัญหานี้ด้วยตัวเองค้นหาทุกที่เพื่อหาทางออกที่ไม่เกี่ยวข้องกับการฆ่าแคชหรือดาวน์โหลดปลั๊กอิน
ฉันไม่เห็นกระทู้นี้ทันทีดังนั้นฉันจึงพบสิ่งอื่นแทนซึ่งเป็นการแก้ไขที่น่าสนใจและ (ฉันคิดว่า) ควรค่าแก่การโพสต์ที่นี่:
$('.image').load(function(){
// stuff
}).attr('src', 'new_src');
ที่จริงฉันได้ความคิดนี้จากความคิดเห็นที่นี่: http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/
ฉันไม่รู้ว่าทำไมมันใช้งานได้ แต่ฉันได้ทดสอบสิ่งนี้บน IE7 และที่ที่มันพังก่อนที่มันจะทำงาน
หวังว่าจะช่วย
คำตอบที่ยอมรับได้จริงอธิบายว่าทำไม:
หาก src ถูกตั้งค่าไว้เหตุการณ์จะเริ่มทำงานในแคชก่อนที่คุณจะได้รับตัวจัดการเหตุการณ์
$image.load(function(){ something(); }).attr('src', $image.attr('src'));
เพื่อตั้งค่าต้นฉบับดั้งเดิม
โดยใช้ jQuery เพื่อสร้างรูปภาพใหม่ด้วย src ของรูปภาพและกำหนดวิธีการโหลดโดยตรงกับวิธีนั้นโหลดวิธีจะถูกเรียกสำเร็จเมื่อ jQuery เสร็จสิ้นการสร้างภาพใหม่ สิ่งนี้ใช้ได้กับฉันใน IE 8, 9 และ 10
$('<img />', {
"src": $("#img").attr("src")
}).load(function(){
// Do something
});
วิธีการแก้ปัญหาที่ฉันพบhttps://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (รหัสนี้นำมาโดยตรงจากความคิดเห็น)
var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;
การดัดแปลงตัวอย่างของ GUS:
$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.onload = function() {
// Run onload code.
} ;
tmpImg.src = $('#img').attr('src');
})
ตั้งค่าซอร์สก่อนและหลัง onload
src
ก่อนที่จะติดตั้งเครื่องonload
จัดการหลังจากนั้นจะพอเพียง
เพียงเพิ่มอาร์กิวเมนต์ src อีกครั้งในบรรทัดแยกต่างหากหลังจากที่มีการกำหนด img oject สิ่งนี้จะหลอก IE ในการกระตุ้นเหตุการณ์เด็กหนุ่ม มันน่าเกลียด แต่ก็เป็นวิธีแก้ปัญหาที่ง่ายที่สุดที่ฉันเคยพบมา
jQuery('<img/>', {
src: url,
id: 'whatever'
})
.load(function() {
})
.appendTo('#someelement');
$('#whatever').attr('src', url); // trigger .load on IE
ฉันสามารถให้คำแนะนำเล็กน้อยแก่คุณได้หากคุณต้องการทำสิ่งนี้:
<div style="position:relative;width:100px;height:100px">
<img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/>
<img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/>
</div>
หากคุณทำเช่นนั้นเมื่อเบราว์เซอร์เก็บรูปภาพจะไม่มีปัญหา img แสดงขึ้นเสมอ แต่โหลด img ภายใต้ภาพจริง
ฉันมีปัญหากับ IE ที่ e.target.width นี้จะไม่ได้กำหนด เหตุการณ์โหลดจะเริ่มขึ้น แต่ฉันไม่สามารถรับขนาดของภาพใน IE (chrome + FF ทำงาน)
เปิดออกคุณต้องมองหาe.currentTarget.naturalWidth & e.currentTarget.naturalHeight
อีกครั้ง IE ทำสิ่งต่าง ๆ เป็นของตัวเอง (ซับซ้อนกว่า)
คุณสามารถแก้ปัญหาของคุณโดยใช้ปลั๊กอินJAILที่ช่วยให้คุณสามารถโหลดภาพที่ขี้เกียจ (ปรับปรุงประสิทธิภาพของหน้า) และผ่านการเรียกกลับเป็นพารามิเตอร์
$('img').asynchImageLoader({callback : function(){...}});
HTML ควรมีลักษณะดังนี้
<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />
หากคุณต้องการโซลูชัน CSS ที่บริสุทธิ์เคล็ดลับนี้ใช้ได้ดีมาก - ใช้วัตถุแปลง วิธีนี้ใช้ได้กับรูปภาพเมื่อแคชหรือไม่:
CSS:
.main_container{
position: relative;
width: 500px;
height: 300px;
background-color: #cccccc;
}
.center_horizontally{
position: absolute;
width: 100px;
height: 100px;
background-color: green;
left: 50%;
top: 0;
transform: translate(-50%,0);
}
.center_vertically{
position: absolute;
top: 50%;
left: 0;
width: 100px;
height: 100px;
background-color: blue;
transform: translate(0,-50%);
}
.center{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background-color: red;
transform: translate(-50%,-50%);
}
HTML:
<div class="main_container">
<div class="center_horizontally"></div>
<div class="center_vertically"></div>
<div class="center"></div>
</div>
</div