Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Подгрузка контента в див и его ресайз (https://javascript.ru/forum/dom-window/23496-podgruzka-kontenta-v-div-i-ego-resajjz.html)

Gosha 25.11.2011 19:00

Подгрузка контента в див и его ресайз
 
Здравствуйте, товарищи. Я программист, но в жаваскриптах не силен. Задумал одну простенькую вещь. Логически понимаю, как это сделать, но реализовать программно не получается. Прошу вашей помощи.

По задумке, имеется на странице список ссылок. При нажтии на одну, под ней расскроется соответствующий блок с некоторым содержимым, который подгружается AJAXом из PHP скрипта. С этим проблем не возникло. Дальше я решил подключить функцию, которая развернет соответствующий див плавно. И это тоже сделал. Все работает, если картинки в нем закэшированы. А если нет, див открывается на высоту, равную надписи alt'а изображения, пока она еще не загружена. А когда полностью появляется, оказывается за рамками, разрушая всю верстку.

Дальше по задумке, нужно так же плавно сворачивать див, при нажатии на ссылку повторно. Но не удалять его содержимое, чтобы при уже следующем клике, див раскрылся без повторной подгрузки контента из PHP.

Вот имеется следующие блоки
<div class="topic_block">
<a href="#" onclick="topic('1', 'monkey'); return false;">Текст</a>
</div>
<div class="big_topic" id="monkey"></div>


<div class="topic_block">
<a href="#" onclick="topic('2', 'parrot'); return false;">Текст</a>
</div>
<div class="big_topic" id="parrot"></div>

...


<div class="topic_block">
<a href="#" onclick="topic('3', 'dog'); return false;">Текст</a>
</div>
<div class="big_topic" id="dog"></div>


И имеется такой жаваскрипт

function topic(a, b) {
//Тут блок должен свернуться, если он открыт
	if (($("#"+b).text() !== '') && ($("#"+b).css("height") !==0)) {
		$("#"+b).css("overflow", "hidden");
		$("#"+b).animate({height: 0}, 500);
		return;
	}
//Тут блок должен развернуться, если он закрыт, но в нем есть контент
	if (($("#"+b).text() !== '') && ($("#"+b).css("height") ==0)) {
		$("#"+b).css("overflow", "hidden");
		$("#"+b).animate({height: $("#"+b)[0].scrollHeight}, 500);
		return;
	}
//А тут выполняется код, если блок пустой и закрытый
	$("#"+b).css("height", "0px");
	$("#"+b).css("overflow", "auto");
	$("#"+b).html("Загрузка...");
	$.ajax({
		type: "POST",
		url: "doit.php",
		data: "id="+a, 
		success: function(msg){
			$("#"+b).html(msg);
			$("#"+b).animate({height: $("#"+b)[0].scrollHeight}, 500);
		}
	});
}


Проблема еще возникает, когда блок сворачивается. Сначала все нормально. Но как тлько анимация завершится, картинка тут же вылезает за края нулевопиксельного блока во всю высоту, опять же ломая верстку. Подскажите, пожалуйста, что подправить. И как можно оптимизировать мой чайниковый код. Который я писал, основываясь на знаниях ООП :help:

Андрей38 25.11.2011 19:11

...только анимация завершится,
По этому делу,только
$("#"+b).animate({height: $("#"+b)[0].scrollHeight}, 500,function(){
$('твоя картинка') .css({'height':0}) или hide()
})
потом вернуть на место ее начальный сиэсэс не забудь или show() ,если хайданутая

Gosha 25.11.2011 19:19

Спасибо. Это получается, что нужно еще картинкам id добавлять? А если там несколько картинок, и все в купе с текстом. В виде небольшой статьи?

Андрей38 25.11.2011 19:55

Цитата:

Сообщение от Gosha (Сообщение 139007)
Спасибо. Это получается, что нужно еще картинкам id добавлять? А если там несколько картинок, и все в купе с текстом. В виде небольшой статьи?

Так пусть себе скрываеться ВСЕ содержимое блока по окончании анимции картинки
А если речь об айди то просто хайдани всЕ в ПАРЕНТЕ картинки
$('Айди блока img').parent().hide()
да и вообще Просто $('Айди блока').children().hide()

И еще, если заметишь, что анимация как то странно себя ведет ,то вот -микстура
$("#"+b).stop().animate(

Gosha 25.11.2011 21:19

Спасибо, все начинает получаться. :)

Gosha 25.11.2011 23:52

Извините, еще один вопрос, можно ли как-то идентифицировать состояние дива (закрыт с неподгруженным контентом | открыт | закрыт с подгруженным контентом) кроме того способа, что испытал я (по высоте дива, и наличию хоть какой-то строки в нем)

Сейчас у меня получился такой код, и не получается расскрыть див с уже имеющимся контентом.

function topic(a, b) {
//Тут див закрывается, если он открыт
	if (($("#"+b).text() !== '') &&  $("#"+b).css("height") !== 0){
		$("#"+b).css("overflow", "hidden");
		$("#"+b).animate({height: 0}, 500,function(){
				$("#"+b).children().hide()
		})
		return;
	}

//Тут див должен открыться с уже имеющимся контентом
	if ($("#"+b).children().hide()){
		$("#"+b).css("height", "0px");
		$("#"+b).css("overflow", "auto");
		$("#"+b).animate({height: $("#"+b)[0].scrollHeight}, 500,function(){
				$("#"+b).children().show()
			})
		return;
	}

//Тут див открывается, подгружая контент
	$("#"+b).css("height", "0px");
	$("#"+b).css("overflow", "auto");
	$("#"+b).html("Загрузка...");
	$("#"+b).children().show();
	$.ajax({
		type: "POST",
		url: "doit.php",
		data: "id="+a, 
		success: function(msg){
			$("#"+b).html(msg);
			$("#"+b).animate({height: $("#"+b)[0].scrollHeight}, 500,function(){
				$("#"+b).children().show()
			})
		}
	});
}

Андрей38 26.11.2011 14:01

Цитата:

Сообщение от Gosha (Сообщение 139040)
Извините, еще один вопрос, можно ли как-то идентифицировать состояние дива (закрыт с неподгруженным контентом | открыт | закрыт с подгруженным контентом) кроме того способа, что испытал я (по высоте дива, и наличию хоть какой-то строки в нем)

Сейчас у меня получился такой код, и не получается расскрыть див с уже имеющимся контентом.

function topic(a, b) {
//Тут див закрывается, если он открыт
	if (($("#"+b).text() !== '') &&  $("#"+b).css("height") !== 0){
		$("#"+b).css("overflow", "hidden");
		$("#"+b).animate({height: 0}, 500,function(){
				$("#"+b).children().hide()
		})
		return;
	}

//Тут див должен открыться с уже имеющимся контентом
	if ($("#"+b).children().hide()){
		$("#"+b).css("height", "0px");
		$("#"+b).css("overflow", "auto");
		$("#"+b).animate({height: $("#"+b)[0].scrollHeight}, 500,function(){
				$("#"+b).children().show()
			})
		return;
	}

//Тут див открывается, подгружая контент
	$("#"+b).css("height", "0px");
	$("#"+b).css("overflow", "auto");
	$("#"+b).html("Загрузка...");
	$("#"+b).children().show();
	$.ajax({
		type: "POST",
		url: "doit.php",
		data: "id="+a, 
		success: function(msg){
			$("#"+b).html(msg);
			$("#"+b).animate({height: $("#"+b)[0].scrollHeight}, 500,function(){
				$("#"+b).children().show()
			})
		}
	});
}

if($(' блок *').length==0){
//...померять количество наявных елементов в блоке
}не подойдет?
или
if($(' блок ').find('*').length==0){...}
...тоже самое

if($(' блок ').find('*:visible').length==0){...}
.. померять количество visible елементов в блоке

Gosha 26.11.2011 15:34

Я попробовал сделать массив, в который записывается состояние для каждого блока

var ar = Array();

Где информация хранится так

'monkey' => '0';
'dog' => '1';

И когда кликаю на слой, читаю по его ключу значение, и если его не существует, то блок закрыт и контент в нем не подгружен. Все это дело подгружается, и создается элемент массива с ключем (id дива) и значением "1". Это значит, что блок расскрыт. При закрытии, значение меняется на "0" - закрыт.

В общем все держится на существовании элемента массива и его значениях. Не знаю, не расточительно ли...

Ваш способ испытал, но он почему-то показывает одинаковые значения количества hide объектов в открытом и закрытом состояниях. Сейчас попробую пофиксить

Андрей38 26.11.2011 22:15

$('#див').show(333)
я 2-й год юзаю только jQ для ДОм и многие понятия мне мало известны.маасив почти не использую так как мало знаком с ним
ВСЕ знает человек по логу KSA , Diablo и еще пару других гуру

Gosha 28.11.2011 00:04

На этом спасибо за помощь. Скрипт получился и работает нормально во всех браузерах :)

melky 28.11.2011 00:35

для начала было бы неплохо уменьшить свой код. его трудно читать

function topic(a, b) {
   
    var div = $("#" + b);
    
    //Тут див закрывается, если он открыт   
    if (div.text() && parseInt(div.css("height")) ) {
        return div.slideUp(500);
    }   

//Тут див должен открыться с уже имеющимся контентом
    if (div.children().hide().length) {
        return div.css({ "height":"0px", "overflow":"auto"}).
            animate({
                height: div[0].scrollHeight
            }, 500, function () {
                div.children().show()
            });
     }

    //Тут див открывается, подгружая контент
    div.css({ "height":"0px", "overflow":"auto"}).
        html("Загрузка...").
            children().
                show();
    $.ajax({
        type: "POST",
        url: "doit.php",
        data: "id=" + a,
        success: function (msg) {
            div.html(msg);
            div.animate({
                height: div[0].scrollHeight
            }, 500, function () {
                div.children().show()
            })
        }
    });
}


плюс пара неточностей.

$("#"+b).css("height")

вернет строку, а не число.
т.е. 54px, а не 54
...
$("#" + b).css("overflow", "hidden");
        $("#" + b).animate({
            height: 0
        }, 500, function () {
            $("#" + b).children().hide()
        })

это велосипед. см далее. этот код делает точно такие же действия
$("#"+b).slideUp(500);

.....
//Тут див должен открыться с уже имеющимся контентом
    if ($("#" + b).children().hide()) {

что вы хотели написать в условии ? просто, $(el).hide() возвращает jq-объект, а объекты при приведении к булевому типу дают true. если вы хотите проверить, есть ли потомки, можно было посмотреть свойство length объекта jq.
//Тут див должен открыться с уже имеющимся контентом
    if ($("#" + b).children().hide().length > 0) {

Gosha 05.12.2011 02:45

Спасибо. Ваш вариант сильно дергается. И неправильно функционирует, видать из-за отсутствия живого примера для фикса. Но код я все таки читабельнее сваял.

И вот еще что я нашел. Оказывается существует такая штука как data(), в которой можно хранить состояние, как в массивах ключ/значение для каждого объекта

Например так
$("#div")data("status", "open");
а вытащить так
alert ($("#div")data("status"));

Что я и применил.
Проблема теперь в том, что еще не успев загрузить картинки, в какой-то момент скрипт берет высоту недогруженного дива и анимирует до него. А когда картинки полностью загрузятся, резко растягивается, создавая впечатление дергания.

Есть ли способ как-то отследить полную загрузку контента в блоке?

melky 05.12.2011 12:48

$(window).load(function(){...........});


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