Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   Индикатор загрузки изображений (https://javascript.ru/forum/css-html/29896-indikator-zagruzki-izobrazhenijj.html)

Ingiborn 16.07.2012 04:41

Индикатор загрузки изображений
 
Здравствуйте..
Помогите разобраться, как реализовать, чтобы при загрузке сайта за место пустых блоков(пока не загрузилось изображения)показывался индикатор в формате gif(картинка)?
Буду очень благодарен..

devote 16.07.2012 05:24

<!DOCTYPE html>
<html>
	<head>
		<style>
			html, body {
				padding: 0;
				margin: 0;
			}
		</style>
		<script type="text/javascript">

function DOMReady( callback ) {

    if ( document.readyState === "complete" ) {
        return setTimeout( callback, 1 );
    }

    var loaded = function( doScroll ) {
        if ( document.removeEventListener ) {
            document.removeEventListener( 'DOMContentLoaded', loaded, false );
            window.removeEventListener( 'load', loaded, false );
            loaded = null;
            callback();
        } else if ( document.detachEvent ) {
            if ( document.readyState === "complete" || doScroll === null ) {
                document.detachEvent( 'onreadystatechange', loaded );
                window.detachEvent( 'onload', loaded );
                loaded = null;
                callback();
            }
        }
    }

    if ( document.addEventListener ) {
        document.addEventListener( "DOMContentLoaded", loaded, false );
        window.addEventListener( "load", loaded, false );
    } else if ( document.attachEvent ) {
        document.attachEvent( "onreadystatechange", loaded );
        window.attachEvent( "onload", loaded );
  
        var toplevel = false;
        try {
            toplevel = window.frameElement == null;
        } catch( _e_ ) {}
  
        if ( document.documentElement.doScroll && toplevel ) {
            var check = function() {
                if ( !loaded ) return;
                try {
                    document.documentElement.doScroll( "left" );
                } catch( _e_ ) {
                    setTimeout( check, 0 );
                    return;
                }
                loaded( null );
            }
            check();
        }
    }
}

DOMReady( function(){

	var imageScope = [],
		imgs = document.getElementsByTagName( 'img' ),
		bgdiv = document.createElement( 'DIV' ),
		div = document.createElement( 'DIV' );

	if ( imgs.length > 0 ) {

		bgdiv.style.cssText = "position: fixed; width: 100%; height: 100%; background-color: #000;"+
			"opacity: 0.3; filter: Alpha(opacity=30);";

		div.style.cssText = "position: fixed; padding: 20px; width: 100px; height: 20px; left: 50%; top: 50%;"+
			"margin: -30px 0 0 -70px; background-color: #fff; border: 1px solid #eaeaea; border-radius: 8px;"+
			"opacity: 0.7; filter: Alpha(opacity=70); box-shadow: 2px 2px 4px #000; font: 20px Arial; color: #f00;";

		div.innerHTML = 'Loading...';

		document.body.insertBefore( div, document.body.firstChild );
		document.body.insertBefore( bgdiv, document.body.firstChild );

		for( var i = 0; i < imgs.length; i++ ) {

			imageScope.push(1);

			var img = new Image();
			img.onload = img.onerror = function() {
				imageScope.pop();
				if ( imageScope.length == 0 ) {
					bgdiv.parentNode.removeChild( bgdiv );
					div.parentNode.removeChild( div );
				}
			}
		    img.src = imgs[ i ].src;
		}
	}

});

		</script>
	</head>
	<body>
		<img src="http://worldoftanks.ru/dcont/fb/media/batchat_ru_june_clear/1920x1200.jpg">
		<img id="img" src="http://wallpaper.goodfon.ru/image/302908-2880x1800.jpg"/>
	</body>
</html>

Aetae 16.07.2012 08:10

..а можно просто назначить в css
img{background:transparent url(loading.gif) 50% 50% no-repeat}
.)

Ingiborn 16.07.2012 11:58

а если у меня пнг изображения на прозрачном фоне?
css не подойдёт..
Спасибо devote, опробую, расскажу..

Deff 16.07.2012 12:05

Цитата:

Сообщение от Ingiborn
а если у меня пнг изображения на прозрачном фоне?
css не подойдёт..

Да наплевать - обрамляете в <span style="inline-block" - прописываете у span бекграунд(gif-картинкой) на время загрузки

Ingiborn 16.07.2012 12:12

Немножко неправильно..
Мне надо, чтобы такой индикатор был над каждым загружаемым изображением, а не один индикатор по центру с текстом Loading...:)

Deff 16.07.2012 12:32

Ingiborn,
:) Какие сложности одеть в span каждое ? Именно это и подразумевал

Ingiborn 16.07.2012 12:35

Непойму как=)

Deff 16.07.2012 13:34

http://javascript.ru/forum/css-html/...tml#post176659

Раед 16.07.2012 18:29

devote,
Смысл новый img создавать? Не проще на старый события повесить?

devote 16.07.2012 18:34

Цитата:

Сообщение от Раед
Смысл новый img создавать? Не проще на старый события повесить?

ну а ты попробуй, если изображение маленькое, то оно загрузится мгновенно, и событие сработает до того как мы на него что-то повесим, а значит наше событие может не сработать. И это может привести к бесконечному показу loading...

Раед 16.07.2012 19:04

Цитата:

Сообщение от devote
если изображение маленькое, то оно загрузится мгновенно, и событие сработает до того как мы на него что-то повесим, а значит наше событие может не сработать.

img.complete

devote 16.07.2012 19:16

Цитата:

Сообщение от Раед
img.complete

а если сурс ошибочный? ведь img.complete так и останется со значением false, если ошибочный адрес ввести.. Поэтому событие onerror тоже нужно отлавливать, что бы убрать надпись

devote 16.07.2012 19:19

Раед,
вот пример:
<!DOCTYPE html>
<html>
	<head>
		<style>
			html, body {
				padding: 0;
				margin: 0;
			}
		</style>
		<script type="text/javascript">

function DOMReady( callback ) {

    if ( document.readyState === "complete" ) {
        return setTimeout( callback, 1 );
    }

    var loaded = function( doScroll ) {
        if ( document.removeEventListener ) {
            document.removeEventListener( 'DOMContentLoaded', loaded, false );
            window.removeEventListener( 'load', loaded, false );
            loaded = null;
            callback();
        } else if ( document.detachEvent ) {
            if ( document.readyState === "complete" || doScroll === null ) {
                document.detachEvent( 'onreadystatechange', loaded );
                window.detachEvent( 'onload', loaded );
                loaded = null;
                callback();
            }
        }
    }

    if ( document.addEventListener ) {
        document.addEventListener( "DOMContentLoaded", loaded, false );
        window.addEventListener( "load", loaded, false );
    } else if ( document.attachEvent ) {
        document.attachEvent( "onreadystatechange", loaded );
        window.attachEvent( "onload", loaded );
  
        var toplevel = false;
        try {
            toplevel = window.frameElement == null;
        } catch( _e_ ) {}
  
        if ( document.documentElement.doScroll && toplevel ) {
            var check = function() {
                if ( !loaded ) return;
                try {
                    document.documentElement.doScroll( "left" );
                } catch( _e_ ) {
                    setTimeout( check, 0 );
                    return;
                }
                loaded( null );
            }
            check();
        }
    }
}

DOMReady( function(){

	var imageScope = [],
		imgs = document.getElementsByTagName( 'img' ),
		bgdiv = document.createElement( 'DIV' ),
		div = document.createElement( 'DIV' );

	if ( imgs.length > 0 ) {

		bgdiv.style.cssText = "position: fixed; width: 100%; height: 100%; background-color: #000;"+
			"opacity: 0.3; filter: Alpha(opacity=30);";

		div.style.cssText = "position: fixed; padding: 20px; width: 100px; height: 20px; left: 50%; top: 50%;"+
			"margin: -30px 0 0 -70px; background-color: #fff; border: 1px solid #eaeaea; border-radius: 8px;"+
			"opacity: 0.7; filter: Alpha(opacity=70); box-shadow: 2px 2px 4px #000; font: 20px Arial; color: #f00;";

		div.innerHTML = 'Loading...';

		document.body.insertBefore( div, document.body.firstChild );
		document.body.insertBefore( bgdiv, document.body.firstChild );

		for( var i = 0; i < imgs.length; i++ ) {
			if ( !imgs[i].complete ) {

				imageScope.push(1);

				imgs[i].onload = imgs[i].onerror = function() {
					imageScope.pop();
					if ( imageScope.length == 0 ) {
						bgdiv.parentNode.removeChild( bgdiv );
						div.parentNode.removeChild( div );
					}
				}
			}
		}
	}

});

		</script>
	</head>
	<body>
		<img src="роывп рыпва">
		<img id="img" src="http://wallpaper.goodfon.ru/image/302908-2880x1800.jpg"/>
	</body>
</html>

devote 16.07.2012 19:20

Раед,
тут одна картинка имеет ошибочный адрес, и из-за этого надпись "Loading..." никогда не исчезнет. Поэтому использование img.complete тут не катит

devote 16.07.2012 19:23

хм.. хотя иногда исчезает.. видимо onerror все же успевает отработать... но не всегда.

devote 16.07.2012 19:29

В ИЕ8 вообще всегда висит надпись "Loading..."

Раед 16.07.2012 19:52

Цитата:

Сообщение от devote
тут одна картинка имеет ошибочный адрес, и из-за этого надпись "Loading..." никогда не исчезнет

У меня всегда исчезает (FF13)

P.S. А что это за новая мода, вместо инкремент-декремент массивы юзать?

devote 16.07.2012 20:12

Цитата:

Сообщение от Раед
У меня всегда исчезает (FF13)

ну мы же пишем не под один FF

Цитата:

Сообщение от Раед
P.S. А что это за новая мода, вместо инкремент-декремент массивы юзать?

Да собственно без разницы. Можно что угодно юзать. Этож лишь пример. Сам не знаю с чего я о массивах подумал когда писал.. :)

Ingiborn 16.07.2012 20:42

Так как лучше делать?=)

Ingiborn 17.07.2012 00:18

Ребят помогите, очень надо..

Deff 17.07.2012 00:29

Ingiborn,
Выложите HTML код двух -трёх картинок и минимального окружения - интересует первый один -два блока в который они вложены

Ingiborn 17.07.2012 03:38

допустим слайдшоу.
<div id=""slider">
<img src="1">
<img src="2">
<img src="3">
</div>

Deff 17.07.2012 13:52

<style>
#slider img{
 visibility:hidden;
 background-color:#000;
 background-image:url(http://uploads.ru/i/0/S/c/0ScZL.gif);
 background-position:center center;
 background-repeat:no-repeat;
}
</style>
<script type="text/javascript">
function LoImg(a) {
 a.visibility='visible';
 a.backgroundСolor='transparent';
 a.backgroundImage='none';
}
</script>

<div id="slider">
<img src="1" onload="LoImg(this)">
<img src="2" onload="LoImg(this)">
<img src="3" onload="LoImg(this)">
</div>

Deff 17.07.2012 14:05

jQuery

<style>
#slider img{
 visibility:hidden;
display:inline-block;
background-color:#000;
background-image:url(http://uploads.ru/i/0/S/c/0ScZL.gif);
background-position:center center;
background-repeat:no-repeat;
}
</style>

<div id="slider" >
<img src="1" >
<img src="2" >
<img src="3" >
</div>

<script type="text/javascript">
$("#slider img").load(function() {
  $(this).css({ 
		'visibility':'visible',
		'background-color':'transparent',
		'background-image':'none'
		
	     });
});
</script>

Ingiborn 17.07.2012 15:45

А для общем функции #slider img заменить на img?

Deff 17.07.2012 16:42

Ingiborn,
Ну наверно можно - если для всех изо -а не ток для слайдера - чревато тем - что, к примеру смайлик отсутствует - будет крутиться загрузка( в слайдере то обычно проверяете наличие

Aetae 17.07.2012 17:58

А если подойти с другой стороны: на что человеку смотреть приятнее во времф загрузки большой картинки: на крутящуюся х*ню, или на саму загружающущюся картинку?)

Раед 17.07.2012 18:57

Цитата:

Сообщение от Aetae
А если подойти с другой стороны: на что человеку смотреть приятнее во времф загрузки большой картинки: на крутящуюся х*ню, или на саму загружающущюся картинку?)

И как вы предлагаете такое реализовать? Для каждой картинки сжатый вариант делать?

Aetae 17.07.2012 19:07

Цитата:

Сообщение от Раед (Сообщение 189540)
И как вы предлагаете такое реализовать? Для каждой картинки сжатый вариант делать?

Я имел ввиду - никак не риализовать.

Кстати, для того, о чём подуали вы, давно есть progressive jpeg.

Ingiborn 18.07.2012 11:22

Спасибо Deff. Очень помог твой способ!

Ingiborn 26.07.2012 21:22

Пример ро jquery не работает, можно как то поправить?

Ingiborn 26.07.2012 22:06

всё именно также, всё равно не рабоает

Ingiborn 26.07.2012 22:09

оу, там дополнительная библиотека

Deff 26.07.2012 22:20

Ingiborn,
Вариант кривой по-ходу - поскольку изо уже может быть в кеше - jQuery не успевает отследит load (нужно извращацо через делегирование

Ingiborn 26.07.2012 22:39

то есть, не работает этот вариант?
я всё подключил как в примере, всё равно не работает..

Ingiborn 26.07.2012 22:40

и кеш чистил, всё равно не работает..

Deff 26.07.2012 22:42

Цитата:

Сообщение от Ingiborn
я всё подключил как в примере, всё равно не работает..

Неть - Срабатывает ток один раз... Подумаю

Ingiborn 27.07.2012 16:48

для jpg где нет прозрачного фона задал бэкграунд, для png решения так и не нашёл..

Deff 27.07.2012 19:24

Ingiborn,
Пробуйте так:
<style>
span.wrap{
  display:inline-block;
  background-color:#000;
  background-image:url(http://uploads.ru/i/0/S/c/0ScZL.gif);
  background-position:center center;
  background-repeat:no-repeat;
}

#slider img{
  visibility:hidden;
}

</style>
<script type="text/javascript">
function LoImg(a) {
 a.visibility='visible';
 a.parentNode.backgroundСolor='transparent';
 a.parentNode.backgroundImage='none';
}
</script>

<div id="slider">
<span class=wrap><img src="1" onload="LoImg(this)"><span>
<span class=wrap><img src="2" onload="LoImg(this)"><span>
<span class=wrap><img src="3" onload="LoImg(this)"><span>
</div>


Часовой пояс GMT +3, время: 02:38.