Jquery: захват ширины изображения после добавления изображения - PullRequest
1 голос
/ 30 ноября 2009

Возможно, простое решение, но я застрял, и уже поздно ...:)

$j('#thisImage').html('<img src="image.jpg" id="box" />');
var imgWidth = $j('#box').width();

Когда я делаю console.log(imgWidth), он возвращается 0 ...

Я почти уверен, что это потому, что .html(...) не полностью завершен до того, как вызов width(...) сработает. Я протестировал его с кэшированными изображениями, и он отлично работает и дает мне правильную ширину изображения ... но те, которые не кэшированы, возвращают 0.

Так что я ищу хорошее решение, которое ждет завершения вызова .html(...), прежде чем перейти к моему .width(...) вызову

Любая помощь очень ценится. Thx!


ОБНОВЛЕНИЕ 1

Используя ответ CMS ниже ... (и это может помочь всем понять мою дилемму)

Если я сделаю это:

var imgWidth = 0;

$j('<img src="image.jpg" id="box" />').appendTo("#thisImage").load(function() {
    imgWidth = $j('#box').width();

    //my first log
    console.log("Width 1: " + imgWidth);                
});             

//my second log
console.log("Width 2: " + imgWidth);

if (imgWidth > 100) {
    //do something
}

Затем //my second log возвращается до //my first log, так как .load еще не закончил ...

таким образом, мое if утверждение всегда false, так как imgWidth всегда 0 ...

до тех пор, пока .load не завершится ... но тогда будет слишком поздно ...


ОБНОВЛЕНИЕ 2: СМОТРЕТЬ, ЧТО Я ВИДЮ

Используя модификацию ответа Райана ...

Перейдите на jsbin.com -> Включить "jquery" из выпадающего меню -> Заменить w / ниже на вкладке Javascript и затем нажмите Вкладка «Вывод»

function loadImg(url, func) {
    var img = new Image();
    img.onload = func;
    img.src = url;
    return img;
}

$(document).ready(function() {
    var myWidth = 0;

    var myImg = loadImg("http://sstatic.net/so/img/logo.png", function() {
                    myWidth = $(this).width();
                    $('#hello').append("Show Me First: " + myWidth + "<br />");
                });


    $(myImg).appendTo("body");

    if(myWidth > 0) {
        $('#hello').append("Success!");    
    } else {
        $('#hello').append("Show Me Second: " + myWidth + " <- BOO! Out of Order! <br />");
    }

});

Ответы [ 2 ]

2 голосов
/ 30 ноября 2009

Попробуйте что-то вроде кода ниже:

function loadImg(url, func) {
    var img = new Image();
    img.onload = func;
    img.src = url;
    return img;
}

var myImg = loadImg("lulz.jpg", function() {
    console.log($j(this).width());
});

$j(myImg).appendTo("#thisImage");

Это в значительной степени делает следующее:

  • Устанавливает изображение для загрузки в фоновом режиме, передавая его в браузер
  • Позволяет jQuery создать и создать элемент DOM, добавить его и т. Д.
  • Наша пользовательская функция loadImg принимает функцию обратного вызова, которая срабатывает, когда изображение готово

Конечно, само собой разумеется, что вы хотите сделать это после того, как DOM будет готов, так что document.ready - ваш друг и весь этот джаз. Повеселись. ; D

Редактировать в ответ на правки ОП:

Ваш код выглядит следующим образом:

function loadImg(url, func) {
    var img = new Image();
    img.onload = func;
    img.src = url;
    return img;
}

$(document).ready(function() {
    var myWidth = 0;

    var myImg = loadImg("http://sstatic.net/so/img/logo.png", function() {
                    myWidth = $(this).width();
                    $('#hello').append("Show Me First: " + myWidth + "<br />");
                });


    $(myImg).appendTo("body");

    // This section is problematic...
    if(myWidth > 0) {
        $('#hello').append("Success!");    
    } else {
        $('#hello').append("Show Me Second: " + myWidth + " <- BOO! Out of Order! <br />");
    }
});

Я прокомментировал проблемный раздел; загрузка изображения - асинхронная вещь. К тому времени, когда этот блок будет нажат, нет никакой гарантии, что ваше изображение будет готово. Возможно, я должен был указать это в своем предыдущем ответе, но в этом случае лучше сделать все ваши манипуляции с DOM в функции обратного вызова изображения, поэтому оно срабатывает, когда изображение действительно готово.

Прокомментировал это, а не набрал другой абзац, но что-то вроде ...

// Move this outside the $(document).ready, for scoping reasons...
var myWidth = 0;

function loadImg(url, func) {
    var img = new Image();
    img.onload = function() { func(img); };
    img.src = url;
    return img;
}

$(document).ready(function() {
    loadImg("http://sstatic.net/so/img/logo.png", function(img) {
        var myImg = $(img);

        // Since you can't get the width until the image is appended, get around it
        // by throwing it in hidden; get the width, then unhide it and do what you want.
        myImg.css({
            "position": "absolute",
            "visibility": "hidden"
        }).appendTo("body");

        myWidth = myImg.width();

        myImg.css({
            "position": "normal",
            "visibility": "visible"
        });

        if(myWidth > 0) {
            $('#hello').append("Success!");    
        } else {
            $('#hello').append("Show Me Second: " + myWidth + " <- BOO! Out of Order! <br />");
        }
    });
});
1 голос
/ 30 ноября 2009

Вы можете создать элемент изображения с помощью функции jQuery , использовать appendTo , чтобы вставить его в элемент #thisImage, привязав событие load к изображение:

$j('<img src="image.jpg" id="box" />').appendTo('#thisImage').load(function() {
  console.log($j(this).width()); // image loaded, show width
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...