Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Добавление картинки в onload ивенте, в Opera.


Автор: Gogaaa 19.4.2009, 13:47
Всем привет!

Есть задача: нужно показать картинки, сжав\растянув их до нужных размеров, не зная начальных размеров. Сделал скрипт, который корректно работает в IE и Firefox, но в Oper-е он отказывается работать правильно, причём с какой то мистической странностью.

Собственно вот код:

Код


//////////////////////////////////
// CResizedImage

    function CSize(nWidth, nHeight)
    {
        this.nWidth = nWidth;
        this.nHeight = nHeight;
    }
    function CalculateResizedImageSize(nCurrentWidth, nCurrentHeight, nSupposedWidth, nSupposedHeight)
    {
        var fAspect = nCurrentWidth / nCurrentHeight;
        var nNewWidth = nCurrentWidth, nNewHeight = nCurrentHeight;
        if (nNewHeight != nSupposedHeight)
        {
            nNewHeight = nSupposedHeight;
            nNewWidth = fAspect * nNewHeight;
        }
        if (nNewWidth > nSupposedWidth)
        {
            nNewWidth = nSupposedWidth;
            nNewHeight = nNewWidth / fAspect;
        }
        return new CSize(nNewWidth, nNewHeight);
    }
    function CResizedImage_onload()
    {
        alert('CResizedImage_onload: this.width ' + this.width + ', this.height ' + this.height);
        var Size = CalculateResizedImageSize(this.width, this.height, this.nSupposedWidth, this.nSupposedHeight);
        this.width = Size.nWidth;
        this.height = Size.nHeight;
        if (this.OnLoadRootElement)
        {
            //alert('this.OnLoadRootElement');
            this.OnLoadRootElement.appendChild(this);
        }
        if (this.OnLoadedFunction)
            this.OnLoadedFunction();
    }
    function CResizedImage(HiddenImagesElement, RootElement, nSupposedWidth, nSupposedHeight, sImagePath, OnLoadedFunction)
    {
        this.ImageElement = document.createElement('img');
        this.ImageElement.ResizedImageOwner = this;
        this.ImageElement.OnLoadedFunction = OnLoadedFunction;
        if (HiddenImagesElement)
        {
            HiddenImagesElement.appendChild(this.ImageElement);
            this.ImageElement.OnLoadRootElement = RootElement;
        }
        else
        {
            RootElement.appendChild(this.ImageElement);
        }            
        this.ImageElement.nSupposedWidth = nSupposedWidth;
        this.ImageElement.nSupposedHeight = nSupposedHeight;
        this.ImageElement.onload = CResizedImage_onload;
        this.ImageElement.setAttribute('src', sImagePath);
        // TODO: Temporary 
        this.ImageElement.setAttribute('border', 1);
    }



Пример использования класса:

Код

var g_HiddenImagesElement = document.getElementById('hiddenimages');

function Foo()
{
    var ResizedImage = new CResizedImage(g_HiddenImagesElement, AElement, 45, 65, sThumbnailPath, null);
}


, где hiddenimages -

Код

<div id="hiddenimages" style="visibility:hidden"></div>




Как я уже написал, код работает в IE и Лисице нормально, а вот в Опере ведёт себя очень странно. Если раскомментить //alert('this.OnLoadRootElement');, в функции CResizedImage_onload, то картинки начинают отображаться. Пробовал перенести appendChild в отдельную функцию и вызывать её через некоторое время (setTimeout) - не помогло. Событие CResizedImage_onload вызывается корректно; this.width и this.height имеют корректные значения. 

Есть у кого нибудь идеи, как это заставить работать?

Заранее спасибо!


Автор: Gogaaa 21.4.2009, 22:36
Топик можно закрывать, разобрался.

По каким то причинам Опера не может прямо в событие сделать appendImage. Воспользовался setTimeout и всё заработало. Прошлый раз не получилось, так как не правильно использовал setTimeout. Пришлось мудрить такую конструкцию:

Код

    function CResizedImage(HiddenImagesElement, RootElement, nSupposedWidth, nSupposedHeight, sImagePath, OnLoadedFunction)
    {
        this.AppendImageToRootElement = 
            function()
            {
                var thisPointer = this;
                if (thisPointer.OnLoadRootElement) 
                    setTimeout(
                        function()
                        {
                            thisPointer.CResizedImage_AppendImage()
                        }, 
                        10);
            }
        this.CResizedImage_AppendImage = 
            function()
            {
                this.OnLoadRootElement.appendChild(this.ImageElement);
            }
        ...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)