Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Замена .animate() (https://javascript.ru/forum/misc/18769-zamena-animate.html)

(Sandr) 14.07.2011 19:10

Замена .animate()
 
Всем привет. Подскажите, как сделать подобие .animate(); только на чистом js?
А именно, меня интересует плавное скрытие и показ элемента: $(id).animate({height: 'show'}, 200);

Подскажите, как такое сделать, а то даж не знаю с чего начать:(

Sweet 14.07.2011 19:23

Лучше всего начать с поиска!

(Sandr) 14.07.2011 19:48

Sweet,
Я так понимаю, нужно просто плавно изменять высоту/ширину элемента и всё? Если да, то подскажи, как получить доступ к высоте и ширине элемента?

(Sandr) 14.07.2011 20:08

Сам нашёл)

(Sandr) 14.07.2011 20:33

Посмотрите этот код пжл, скажите, что в нём не так?

<script>
function myf(div)
{
	var elem = document.getElementById(div);
	var show = document.getElementById('di');
	show.innerHTML = elem.offsetHeight;
	setTimeout(function() {
	elem.style.height = (elem.offsetHeight - 15) + 'px';
	
	
	show.innerHTML = elem.offsetHeight;
	if(elem.offsetHeight > 0)
	{
		myf(div);
	}
	},50);
}
</script>
<a href="javascript:void(0)" onclick="myf('dii')">Запуск</a>
<div id="di"></div><hr>
<div id="dii" style="background-color: blue">
 111111111111111111111111111111111111111111111111111111111111111111<br>
 1111111 1111111111111111111 11111111111111111 111111111 11111111111111<br>
 1111111111111111111 111111111111111111111 11111111111111111111111111<br>
 111111111111111111111111111111111111111111111111111111111111 111111<br>
 11111111111111111111111111111111111111111111111111 11 11111111111111<br>
 </div>

(Sandr) 14.07.2011 21:26

Блин, код сдесь не запускается почему-то но в браузере работает. Но не совсем так, как нужно.. сама высота дива уменьшается, это можно посмотреть по уменьшению столбика с синим цветом, но вот единички не исчезают.

trikadin 14.07.2011 21:56

Поставьте overflow: hidden, и будет вам счастье.

(Sandr) 14.07.2011 22:22

Спасибо)

(Sandr) 15.07.2011 19:47

Возник ещё один вопрос. Если длина дива не уменьшается, а увеличивается, то нужно прописать в условии, чтобы код корректно исполнялся?
function myf(div)
{
    var elem = document.getElementById(div);
    var show = document.getElementById('di');
    show.innerHTML = elem.offsetHeight;
    setTimeout(function() {
    elem.style.height = (elem.offsetHeight + 1) + 'px';
     
     
    show.innerHTML = elem.offsetHeight;
    if(elem.offsetHeight > 0) // что здесь прописать?
    {
        myf(div);
    }
    },50);
}


Конечно можно прописать что-то в роде if(elem.offsetHeight < x)
Где x - длина дива в "развёрнутом" состоянии. Но вот как тогда узнать эту длину?

monolithed 22.07.2011 17:36

Для понимания, как-то так (стоит отметить, что это не правильные подходы):
<script type="text/javascript">
//show
window.onload = function() {
    var i = 0;
    (function(){
        if(++i <= 100) {
           document.getElementsByTagName('div')[0].style.height = i+'px';
           setTimeout(arguments.callee, 10);
        }
        else {
            alert('finished');
        }
    })();
};
</script>

<style type="text/css">
div {
    background: blue;
    position: absolute;
    width: 100px;
}
</style>

<div></div>


<script type="text/javascript">
//toggle
window.onload = function() {
    var elem = document.getElementById('div'), i = 0, j = 0, s = 100;   
    document.getElementById('a').onclick = function() {
        if(++i <= s) {
            elem.style.height = i +'px';
            j = i;
            if(j >= s) return false;
        }
        else {
            elem.style.height = --j +'px';
            if(j <= 0) {
                i = 0;
                return false;
            }
        }
        window.setTimeout(arguments.callee, 1);
        return false;
    };
};
</script>

<a href="#" id="a">click<a/>
<div id="div" style="background: #0095FF; overflow: hidden; width: 200px; height: 0px;"></div>


как правильно, написано тут

(Sandr) 22.07.2011 18:16

monolithed,
извиняюсь, видимо, я не совсем правильно озвучил проблему..
Так будет вернее: "Как можно раскрыть див, если в стиле не указана его ширина и высота?"

Т.е. если взять ваш первый пример, то в стиле будет не так


div {
background: blue;
position: absolute;
width: 100px;
height: 100px;
}



а так


div {
background: blue;
position: absolute;
}

monolithed 22.07.2011 19:10

Цитата:

Сообщение от (Sandr)
Так будет вернее: "Как можно раскрыть див, если в стиле не указана его ширина и высота?"

ну так уберите высоту, она нужна лишь для того чтобы гарантировать максимально возможное ее значение (только в этом случае нужно еще добавлять overflow:hidden;, т.к. тайминг во всех бразурах разный). Что касается ширины, то вы ее тоже можете убрать, если это целесообразно.

prowoke 22.07.2011 20:03

document.getElementById('a').onclick = function() {

        if(++i <= s) {

            elem.style.height = i +'px';

            j = i;

            if(j >= s) return false;

        }

        else {

            elem.style.height = --j +'px';

            if(j <= 0) {

                i = 0;

                return false;

            }

        }

        window.setTimeout(arguments.callee, 1);

        return false;

    };

Сори, конечно, что влезу не в тему, но создавать новый топик с куском кода из этой темы, немного глупо. Так вот вот этот момент:

window.setTimeout(arguments.callee, 1);


Это рекурсия?

(Sandr) 22.07.2011 20:47

monolithed,
я не про это. В вашем примере див раскрывается на 100px, а что если реальная высота дива не 100, 123пикселя? Тогда он раскроется не полностью.

monolithed 22.07.2011 21:03

Цитата:

Сообщение от prowoke
Это рекурсия?

arguments.callee в данном случае содержит ссылку на анонимный контекст исполнения и в каком-то смылсе, явлеется рекурсивным вызовом.
Цитата:

Сообщение от (Sandr)
я не про это. В вашем примере див раскрывается на 100px, а что если реальная высота дива не 100, 123пикселя?

что значит реальая высота? подставте значение какое вам нужно

(Sandr) 22.07.2011 22:32

monolithed,
это высота дива)
Мне не нужно задавать на сколько должен раскрыться див, мне нужно, чтоб он просто раскрывался и всё. Как в jQuery.

monolithed 22.07.2011 23:34

Цитата:

Сообщение от (Sandr)
Мне не нужно задавать на сколько должен раскрыться див, мне нужно, чтоб он просто раскрывался и всё. Как в jQuery.

для этого случая предусмотрено несколько вариантов:
1. если блок скрыт, но у него заданы некие значения в css (height+padding-top/bottom) или они заранее известны, то нужно брать их.

2. получить неизвестные значения, можно путем задания абсолютного позиционирования элементу и взятия у него свойста offsetHeight. Если элемент скрыт неполностью или есть какие-то еще причины по которым нельзя задать исходному элементу абсолютное значение, то в этом случае сперва делается клонирование объекта с помощью метода cloneNode().

<style type="text/css">
#wrap {display: none;}
#wrap div {height: 50px;}
</style>

<div id="wrap">
     <div></div>
     <div></div>
</div>

<script type="text/javascript">
var div = document.getElementById('wrap');
// временно меняем css-значения
div.style.cssText = 'display: block; position: fixed; visibility: hidden; overflow: hidden';

//получаем значение высоты
var height = div.offsetHeight;

//восстанавливаем значения
div.style.cssText = 'display: ; position: ; visibility: ; overflow: ';

alert([height, div.offsetHeight]);
</script>


PS: конкретно этот вариант, на кроссбраузерность не проверял.

float 23.07.2011 02:55

сам кстати недавно пробивал по этой теме, тк для меня актуально тоже.
пишу фрэймворк под проект... и анимации фэйдинга уже не хватает.

1-е что я сделал покопался в jquery. там вспомогательные функции работают все через анимэйт, а саму эту функцию, разобрать я не смог. куча ветвлений/непонятные названия переменных...

Траблы которые встретил:
1. это метод вызова. для анимации вроде как больше подходит сетИнтервал, однако есть модная функция requestAnimationFrame, которая по синтаксису походит на seтTimeout, анимация на которой в свою очередь(если браузер старый) происходит с рывками.
также с сетИнтервалом есть фишка, в которой я пока не сильно разобрался (видимых проблем не вызывает).
дело в том, что после очисткиИнтервала, функция вызывается ещё некоторое время...
2. разные типы переменных в стилях, напр: флот если это непрозрачность, инт если там ширина в пикселах и проч.
3. некроссбраузерность некоторых стилей... то есть в фрэймворке это уже решено, но в функцию надо встраивать непонятные ветвления и тп...
4. не важно на сетИнтервале или Таймауте реализована анимация, в разных браузерах она длиться разное время и точка. В ДжейЗапросе это видимо пофикшено, тк. в особо тормозных браузерах анимация почти без перехода... Что мне не особо нравится... Тк для моего проекта время выполнения анимации не особо важно(ну. в разумных приделах), а если ставишь анимацию, то её хочется видеть...

float 23.07.2011 08:07

Цитата:

дело в том, что после очисткиИнтервала, функция вызывается ещё некоторое время...
Хм... Видимо это скорее всего фишка ФФ... И Интервал тут не причём. Сейчас ничего лишнего не вызывается. Как часы.

Или я чёт накосячил, а потом несознательно поправил :no:

(Sandr) 23.07.2011 10:25

monolithed,
о! То, что нужно))

(Sandr) 23.07.2011 10:26

float,
:)


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