2013-04-08 27 views
6

Tôi cho phép người dùng chèn một đối tượng, một hình ảnh, và sau đó tôi gọi một hàm trên đối tượng đó. Những gì có vẻ ngẫu nhiên với tôi, đôi khi nó hoạt động và đôi khi không, tôi đoán nó đã làm với DOM không được cập nhật chưa?Chèn đối tượng (jquery) chậm trễ?

//add a new image 
function add_image(img) { 

var objCount = count_objects() + 1; 
var objId = 'object_'+objCount; 

var myNewImg = jQuery('<div/>', { 
    id: objId, 
    class: 'object_image invisible', 
}).appendTo('#objectbox'); 

//sätt objektnamnet (användaren kan ändra senare) 
$('#'+objId).attr('namn', objId) 

//sätt låsta proportioner som standard 
$('#'+objId).addClass('lockedAspectRatio') 

//lägg till bilden i detta element 
var imgInner = jQuery('<img/>', { 
    id: objId, 
    class: 'object_image_inner', 
    src: img, 
}).appendTo('#'+objId); 



window.objectCounter++; 

prepare_editmode(); 

//reset the flag and the temporary image field now that image adding is complete 
$('#imageGhost').val(null); 

//fixa rätt storlek på bilden 
setTimeout(function(){ 
    restoreSize(myNewImg,imgInner); 
    $(myNewImg).removeClass('invisible'); 
}, 1500); 

} 

Vì nếu tôi tự kích hoạt chức năng cuối cùng bằng một nút sau một giây hoặc lâu hơn, nó luôn hoạt động.

function restoreSize(myImg,imgInside) { 

if (imgInside == null) { 
    console.log("nothing passed"); 
    var imgInside = $(myImg).find('img'); 
} 
else { 
    console.log("passed alright"); 
} 

//remove fixed dimensions on containing div 
$(myImg).css("height", 'auto'); 
$(myImg).css("width", 'auto'); 

//remove the 100% attribute on the image 
$(imgInside).css("width", 'auto'); 
$(imgInside).css("height", 'auto'); 

//get calculated dimensions of div once img original size determines it 
var newWidth = $(myImg).css("width"); 
var newHeight = $(myImg).css("height"); 

//...and set them firmly. 
$(myImg).css("width", newWidth); 
$(myImg).css("height", newHeight); 

//restore the height/width 100% property to image in case of new resize 
$(imgInside).css("width", '100%'); 
$(imgInside).css("height", '100%');  
} 

Tôi cố gắng timeout zero với kết quả tương tự - đôi khi hình ảnh đã được nạp và đôi khi không phải như vậy nó hoạt động một cách ngẫu nhiên, với những hình ảnh lớn hơn (dành thời gian lâu hơn để tải trong trình duyệt) nó dĩ nhiên không thường xuyên hơn. Ngay bây giờ tôi đã bỏ qua nó với một thời gian chờ giây nhưng đó không phải là không có giải pháp khá: -/Có lẽ tôi có thể đặt một vòng trên tìm ('img') mà giữ kiểm tra cho hình ảnh và chỉ tiến hành một lần tìm thấy? Nhưng điều đó có thể dính vào tôi trong một vấn đề vòng lặp vô hạn tại một số lần?

+2

Bạn có đang gọi 'restoreSize' ngay sau khi thêm phần tử (như trong mã của bạn) không? Hoặc là những người ở hai nơi riêng biệt? – Ian

+0

Tôi đã có một trải nghiệm tương tự. Bạn có đang thử nghiệm chống lại các trình duyệt cũ và nhận được một cú đánh hay bỏ lỡ? lớp là một từ dành riêng và nên được trong dấu ngoặc kép, nhưng tôi nghĩ rằng họ là một vấn đề lớn hơn ở đây ... – blackhawk

+0

Tôi nghĩ bạn cần đợi cho đến khi trình duyệt thêm phần tử trong DOMTree .. Bạn nên thử một setTimeout (fx, 0); – fernandosavio

Trả lời

2

điều này có thể phù hợp với bạn không?

 function add_image(img) { 
     var objCount = count_objects() + 1; 
     var objId = 'object_' + objCount; 

     var myNewImg = jQuery('<div/>', { 
      id: objId, 
      class: 'object_image invisible' 
     }).appendTo('#objectbox'); 

     $('#' + objId).attr('namn', objId) 

     $('#' + objId).addClass('lockedAspectRatio') 

     var imgInner = jQuery('<img/>', { 
      id: objId, 
      'class': 'object_image_inner', 
      src: img 
     }).load(function() { 
      imgInner.appendTo('#' + objId) 
      restoreSize(myNewImg, imgInner); 
      $(myNewImg).removeClass('invisible'); 
     }); 

     window.objectCounter++; 

     prepare_editmode(); 

     //reset the flag and the temporary image field now that image adding is complete 
     $('#imageGhost').val(null); 
    } 

và BTW bạn đã id trùng lặp cho myNewImgimgInner

+0

@Mattias Svensson bạn đã xem nó chưa? – Ejaz

+1

Cảm ơn tất cả những người đã đóng góp cho tiền thưởng này. Tôi đã chọn câu trả lời này vì nó dựa trên mã của tôi, và chỉ ra các bản sao của tôi. Nhưng bất kỳ một trong những câu trả lời của bạn có thể đã làm được các trick. Cảm ơn rất nhiều! –

0

Bạn đã thử sử dụng tham chiếu bạn đã có chưa?

var obj = jQuery('<div/>', { 
    id: objId, 
    class: 'object_image', 
}).appendTo('#objectbox'); 

restoreSize(obj); 

Có lẽ nó hoạt động

EDIT: Bạn có thể đặt một thời gian chờ từ 0 đến thêm chức năng của bạn sau khi trình duyệt làm ...

var obj = jQuery('<div/>', { 
     id: objId, 
     class: 'object_image', 
    }).appendTo('#objectbox'); 

    setTimeout(function(){ restoreSize(obj) }, 0); 
+0

Tôi cập nhật theo đề xuất sử dụng tham chiếu thay vì cố gắng phương thức find(), cùng một kết quả. –

1

Thay vì truy vấn ngay sau khi DOM phụ thêm, chỉ lưu trữ tham chiếu đến phần tử, sau đó tham chiếu đến phần tử đó. Giống như:

var div = jQuery("<div/>", { 
    id: objId, 
    "class": "object_image" 
}).appendTo("#objectbox"); 
restoreSize(div); 

Ngoài ra, tôi có thể đã tuyên thệ nhậm chức bạn không thể đặt chìa khóa của một đối tượng như class vì nó là một dạng dự trữ, mà không có dấu ngoặc kép ... để sử dụng "class": "object_image". Ngoài ra, bạn có thêm dấu phẩy sau giá trị class ... đó là lỗi cú pháp, ít nhất là trong IE.

+0

cùng một vấn đề xin lỗi –

+0

@MattiasSvensson Vâng chính xác những gì xảy ra trong 'restoreSize'? – Ian

+0

Mã được thêm vào câu hỏi gốc –

0

Bạn không thể truy cập những hình ảnh chiều rộng và chiều cao cho đến sau khi những hình ảnh tải. Thats lý do tại sao setTimeout làm việc cho bạn đôi khi. Sử dụng chức năng gọi lại image.load() để kích hoạt mã bạn yêu cầu chạy sau khi hình ảnh đã được tải.

var imgInner = jQuery('<img/>', {   
     src: img 
    }).load(function() { 
     jQuery(this).appendTo('#' + objId) 
     restoreSize(myNewImg, this);   
     //and so on 
    }); 
+1

Brendon, tôi nghĩ bạn có thể cần 'jQuery (this) .appendTo' thay vì' this.appendTo'. –

+0

Có, đúng, chỉnh sửa trong trường hợp –

1

u có thể sử dụng load function của jquery.Dưới đây là một ví dụ với mã của bạn:

http://jsfiddle.net/UhUb7/

var images = [ 
    "http://upload.wikimedia.org/wikipedia/commons/4/4b/Apple_pie.jpg" 
      ] 

$(document).ready(function(){ 
    addImage(images[0]); 
}); 

function addImage(url){ 
    var holder = $('<div class="object_image invisible">'); 
    var image = $('<img src="'+url+'" />'); 
    holder.append(image); 
    $("#objectbox").append(holder); 

    image.load(function(){ 
     holder.show('slow'); 

     // alert(image.css("width")); 
    }); 
} 
0

Bạn có thể làm điều đó mà không jquery, chỉ cần sử dụng các quan sát viên ES5 đột biến và một sự kiện tải

(function (global) { 
    "use strict"; 

    if (!("MutationObserver" in global)) { 
     global.MutationObserver = global.WebKitMutationObserver || global.MozMutationObserver; 
    } 

    function loadImage(e) { 
     var img = e.target, 
      width = img.clientWidth, 
      height = img.clientHeight; 

     img.removeEventListener('load', loadImage, false); 
     alert("Image loaded: width: " + width + " height: " + height); 
    } 

    var observer = new MutationObserver(function (mutations) { 
     mutations.forEach(function (mutation) { 
      switch (mutation.type) { 
      case 'childList': 
       Array.prototype.forEach.call(mutation.target.children, function (child) { 
        if (child.id === "smiley") { 
         child.addEventListener('load', loadImage, false); 
        } 
       }); 

       break; 
      default: 
      } 
     }); 
    }); 

    var container = document.getElementById("container"); 

    observer.observe(container, { 
     childList: true, 
     characterData: true, 
     subtree: true 
    }); 

    container.innerHTML = "<img id='smiley' src='http://1.bp.blogspot.com/-b1Z0R5ExM9s/TdWbeGQ-wdI/AAAAAAAAAPI/Ft52XTSxs0s/s1600/blue+sky+wallpaper+%25289%2529.jpg'/>"; 
}(window)); 

Một ví dụ sống là trên jsfiddle

Bạn có thể đọc thêm về MutationObserver tại mdn

Các vấn đề liên quan