Упорядочить элементы HTML на странице в алфавитном порядке по идентификатору

0

У меня есть сценарий, который ajaxes в списке изображений, то функция успеха вызова ajax открывает изображения в виде холстов, чтобы пользователь мог нарисовать наложения сверху.

В основном у меня есть for (key in data.imgs) { OpenImg(data.img[key]); } for (key in data.imgs) { OpenImg(data.img[key]); } вызов этого. Мне нужна высота и ширина в функции OpenImg, чтобы я мог указать размер холста.

Проблема в том, что я получаю изображения не в порядке. Моя функция img.onload необходима для задержки определения высоты/ширины, пока изображение не будет загружено.

Я выяснил, что мне нужно дождаться загрузки изображений, но также необходимо загрузить их подряд. Я могу переключить назначение идентификатора canvas из счетчика в подстроку URL-адреса, которая содержит номер страницы.

Проблема в том, что даже после переименования идентификатора canvas они не изменят порядок на экране. Есть ли хороший способ их сортировки? Могу ли я просто не присоединяться к странице, а затем использовать JQuery.each(), чтобы поместить их, но как сделать.each() запущен по id?

TL; DR: могу ли я сделать эту асинхронную функцию синхронной, не будучи фактически синхронной?

function OpenImg(url) {
    var img=new Image();
    img.src=url;
    img.onload=function() {
        $('<div/>',{'id':'_wrap_pg'+canvasCount,'class':'wrapPage','Width':img.width,'Height':img.height,'data-w':img.width,'data-h':img.height,'data-url':url}).appendTo('#filebox');
        $('<canvas/>',{'id':'pg'+canvasCount,'Width':img.width,'Height':img.height,'data-w':img.width,'data-h':img.height,'data-url':url}).appendTo('#_wrap_pg'+canvasCount);
        var el=document.getElementById('pg'+canvasCount);
        if (typeof(G_vmlCanvasManager)!='undefined') G_vmlCanvasManager.initElement(el);

        var date=new Date().getTime();  // use timestamp to force image not to cache
        $('#pg'+canvasCount).css({'background-image':'url('+url+'?t='+date+')',
            'filter':      "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"', sizingMethod='scale')",
            '-ms-filter':  "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"', sizingMethod='scale')"});

        InitDraw(canvasCount);  // function to attach events to newly created canvas
        if (canvasCount==1) {
            // if page 1 set zoom value to scale canvas/image to fit height
            $('#zoom').val(Math.floor(100/(img.height/$('#filebox').height()))-1);
        }
        zoom();  // my custom zoom function
        canvasCount++;
    }
}
Теги:
order

2 ответа

1
Лучший ответ

Создайте и добавьте холст на страницу как часть функции OpenImg, а не как часть функции onload. Вы можете сделать то же самое для <div>. Нарисуйте небольшую иконку "загрузка" или текст, так что некоторая обратная связь для пользователя. Это гарантирует, что элементы находятся в том порядке, в котором они должны быть, независимо от порядка загрузки.

  • 0
    У меня уже есть загрузка обратной связи, не для каждого изображения, а только для всей страницы (начинается до исходного AJAX и заканчивается после загрузки всех изображений). Это в локальной сети, поэтому это не займет много времени. Я собирался спросить, как я получаю высоту / ширину до загрузки изображения, но потом понял, что могу сначала разместить элементы и изменить их размер внутри нагрузки. Теперь я чувствую себя глупо, спрашивая LOL.
  • 0
    Имейте в виду, что размеры изображения являются одним из первых данных на изображении. Я внедряю на своем сайте автоматический sizer, который опрашивает с помощью setTimeout до тех пор, пока размеры не станут ненулевыми, вместо того, чтобы использовать onload , потому что таким образом он может правильно определить размер как можно скорее, а затем загрузить оставшуюся часть изображения.
0

Прежде всего, я бы превратил ваш объект в массив:

var arr = [];
for (key in data.imgs) { arr.push(data.img[key]); }

Тогда я бы назвал ваш метод:

OpenImg(arr, 0);

И ваш метод будет:

function OpenImg(arr, index) {
    var img=new Image();
    img.src=arr[index];
    img.onload=function() {
        $('<div/>',{'id':'_wrap_pg'+index,'class':'wrapPage','Width':img.width,'Height':img.height,'data-w':img.width,'data-h':img.height,'data-url':url}).appendTo('#filebox');
        $('<canvas/>',{'id':'pg'+index,'Width':img.width,'Height':img.height,'data-w':img.width,'data-h':img.height,'data-url':url}).appendTo('#_wrap_pg'+index);
        var el=document.getElementById('pg'+index);
        if (typeof(G_vmlCanvasManager)!='undefined') G_vmlCanvasManager.initElement(el);

        var date=new Date().getTime();  // use timestamp to force image not to cache
        $('#pg'+index).css({'background-image':'url('+url+'?t='+date+')',
            'filter':      "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"', sizingMethod='scale')",
            '-ms-filter':  "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"', sizingMethod='scale')"});

        InitDraw(index);  // function to attach events to newly created canvas
        if (index==1) {
            // if page 1 set zoom value to scale canvas/image to fit height
            $('#zoom').val(Math.floor(100/(img.height/$('#filebox').height()))-1);
        }
        zoom();  // my custom zoom function
        if (index < arr.length - 1)
            OpenImg(arr, ++index);
    }
}

Я изменил весь ваш код "canvasCount" на индекс массива, и он будет вызывать только следующую функцию OpenImg, когда последний закончен.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню