Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Раздвигающиеся меню как у Apple. 
V
    Опции темы
Elfet
  Дата 25.1.2008, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Вот тут http://www.apple.com/ru/support/ - есть классное меню "решения", при наведении мышкой меню раздвигается.  Как сделать такое же меню? 


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 25.1.2008, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Посмотреть как сделано...
Поискать в гугле по словам  prototype, scriptaculous, accordion, menu


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
Дата 25.1.2008, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Пробовал я уже разобраться как это у них устроено - бесполезно smile


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 25.1.2008, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Тогда попробуй вот здесь. Это почти оно-же, только на jQuery

Это сообщение отредактировал(а) ksnk - 25.1.2008, 18:59


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Sardar
Дата 25.1.2008, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Можно создать общий div (position:relative; overflow: hidden), он будет координатным якорем и заодно clip эффект реализует. Внутрь кладём div'ы на абсолютных позициях, будут менюшками, выставляем им правильный z-index: <num>, что бы друг на дружке были. Двигаем любой анимацией, тем же script.aculo.us.

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


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Elfet
Дата 25.1.2008, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



А как сделать что бы они вверх отползали? Там они не просто вниз уходят, но ещё и вверх.


--------------------
PM MAIL WWW Skype   Вверх
Sardar
Дата 25.1.2008, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



А чем отличается движение в верх от того же вниз? вместо style.top -= delta пишем style.top += delta или я не понял вопроса?


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Elfet
Дата 26.1.2008, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Там они в одном случае опускается див, а в другом случае поднимаеться. Так вот как определить какой поднимается, а какой опускается?


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 26.1.2008, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Цитата(Elfet @  25.1.2008,  18:40 Найти цитируемый пост)
Как сделать такое же меню? 

Весь это тред имеет смысл, если вопрос вучит не как сделать, а как сделать ВСЕ САМОМУ... Я прав? ;-)


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
Дата 26.1.2008, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



ksnk, да если есть уже готовое такое меню, я бы им воспользовался. Но похоже его нету, и придеться самому делать smile

Я всё примерно представляю как это делается, немного помучившись можно сделать такое же меню, но это будет очень громоздко и не "масштабируемо" smile



--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 26.1.2008, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Цитата(Elfet @  26.1.2008,  18:04 Найти цитируемый пост)
есть уже готовое такое меню


Не громоздко (во всяком случае - с твоей стороны ;) ) и масштабируемо можно написать, воспользовавшись готовыми accordion'ами от jQuery или scriptaculos. по моей ссылке вверху можно посмотреть демку... Второй пример сверху...

Самому писать с нуля - придется "помучится", хотя результат будет значительно меньше по объему... 


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
  Дата 27.1.2008, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Не люблю я всякие jQuery smile

Добавлено через 1 минуту и 34 секунды
Какой вобще принцип действия у такого меню? 


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 27.1.2008, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Ну что-ж... принципы...
В HTML разметке вставляем чего-то наподобии такого.
Код

<div>
    <ul id="navigation">
        <li>
            <a class="head" href="?p=1.1.1">Guitar</a>
            <ul>
                <li><a href="?p=1.1.1.1">Electric</a></li>
                <li><a href="?p=1.1.1.2">Acoustic</a></li>
                <li><a href="?p=1.1.1.3">Amps</a></li>
                <li><a href="?p=1.1.1.4.1">Effects A</a></li>
                <li><a href="?p=1.1.1.4.2">Effects B</a></li>
                <li><a href="?p=1.1.1.4.3">Effects C</a></li>
                <li><a href="?p=1.1.1.4.4">Effects D</a></li>
                <li><a href="?p=1.1.1.5">Accessories</a></li>
            </ul> 
        </li>
        <li>
            <a class="head" href="?p=1.1.2">Bass</a>
            <ul>
                <li><a href="?p=1.1.2.1">Electric</a></li>
                <li><a href="?p=1.1.2.2">Acoustic</a></li>
                <li><a href="?p=1.1.2.3">Amps</a></li>
                <li><a href="?p=1.1.2.4">Effects</a></li>
                <li><a href="?p=1.1.2.5">Accessories</a></li>
            </ul> 
        </li>
        <li>
            <a class="head" href="?p=1.1.3">Drums</a>
            <ul>
                <li><a href="?p=1.1.3.2">Acoustic Drums</a></li>
                <li><a href="?p=1.1.3.3">Electronic Drums</a></li>
                <li><a href="?p=1.1.3.4">Cymbals</a></li>
                <li><a href="?p=1.1.3.5">Hardware</a></li>
                <li><a href="?p=1.1.3.6">Accessories</a></li>
            </ul> 
        </li>
    </ul>
</div>
 Вариантов оформления меню в HTML может быть дофига, но определенность какая-то должна быть... 
И пытаемся сделать так, чтобы ul#navigation оказался нашим меню, все #navigation li a.head - заголовками разделов этого меню, а все #navigation ul li - строчками нашего меню.
Сначала неплохо бы скроить css так, чтобы все заголовки меню показывались, а строчки - нет. Так можно немного сэкономить на кодинге smile Хотя, достаточно здраво будет скрывать строки меню уже JavaScript'ом, чтобы юзеры с отключенным JS все-таки до него могли добраться.
После чего на все a.head нужно навесить какой-то обработчик каких-то событий. 
В нашем случае - событие mouseover .
По этому событию необходимо найти  "нижележащий" UL и в зависимости от того, скрыт он или нет закрыть "раскрытое" сейчас меню и показать это.  Показывать или скрывать нужно медленно и печально, для чего нужно пользоваться специальным методом, принципы которого пытался показать Sardar, несколькими сообщениями выше.
Итого 
  • необходим какой-то eventmanager, который позволяет относительно безболезненно ставить обработчики событий на элемент
  • функция animation, которая элемент либо медленно раздвигает до его натуральных размеров, либо сдвигает до нуля. Она тоже, вроде в форуме мелькала
  • необходим способ "пробега" по DOM'у с поиском характерных элементов, что тоже где-то тут неоднократно мелькал...




--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
Дата 27.1.2008, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Ок, спасибо. буду делать smile
Если бы дал ссылки на лучшие примеры eventmanager'а и "способа "пробега" по DOM'у с поиском характерных элементов" было бы очень классно!  smile 


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 28.1.2008, 02:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



smile Ну, так и знал, что все придется делать самому smile Попытался наискать собственных писем с нужными кусочками кода и подумал, что сделать проще, чем найти и объяснить что как и куда... 
CSS тут совсем уж минимально обработан напильником после утаскивания из примера, да HTML разметка несколько оличается от той, что выше...
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Simple menu</title>

<style>

ul.Menu { margin: 0; padding: 0; list-style-type: none; }
ul.Menu li { margin: 0; margin-bottom: 2px; padding: 0;}
ul.Menu li a.head { display: block; padding-left: 5px; margin-right: 3px; 
    height: 28px; background: white; color: #000; text-decoration: none; line-height: 28px; }

ul.Menu div{ overflow:hidden;} /* контейнер оказался необходим :-( */

ul.Menu ul{ display: block; margin-left: 30px; padding: 0; list-style-type: none; }
</style>

<script type="text/javascript">

// бег по DOM'у
function scanDomTree(e,callback,lvl){
    var o= e,
        stack=[null]
    do {
        if(!o) {
            o=stack.pop(); continue  // go up
        }
        if(callback.call(this,o))
            return o;
        if (o.firstChild) {
            stack.push(o.nextSibling);
            o=o.firstChild; // go deep
        } else
            o=o.nextSibling
    } while(stack.length)
    return null;
}

// переменная для проверки - делаем или нет какую анимацию...
var animation_going=0;
// медленно и печально... в течении секунды...
function animate(e,_from,_to,callback){
    animation_going++;
    var i = 20, // <<< вот тут - частота смены кадров.
        disp=(_from-_to)/i,interval=
    setInterval(function(){
        try{
            e.style.height=(_from-=disp)+'px';
        } catch(ee){;}
        if(!i--) {
            animation_going--;
            clearInterval(interval);
            callback()
        }
    },1000/i) // <<< вот тут она - секунда
}

// вот это - event handler
// хранилище событий для последующей чистки. Чистка нужна для IE :-(
var handlers=[]
// установка события
function add_event(a,e,o){
    if (a.addEventListener)
        a.addEventListener(e,o,false)
    else if (a.attachEvent) {
        try {
            a.attachEvent( e='on'+e, o);
        } catch (aEx) {}
    }
    handlers.push({a:a,e:e,o:o});
}
function clear_event(a,e,o) {
    if (a.removeEventListener) {
        a.removeEventListener(e, o, false);
    } else {
        try {
            a.detachEvent( /*'on'   */ e, o);
        } catch (aEx) {}
    }
}
// это то, ради чего огород с event manager'ом городили - чистка хвостов...
add_event(window,'unload',function(){
    for(var i in handlers){
        var h=handlers[i];
        clear_event(h.a,h.e,h.o);
    }
})

// а тут, собствено, жужжим ....
add_event(window,'load',function(){
    scanDomTree(document,function(e){
        // для всех элементов с классом Menu
        if(e && e.className && e.className=='Menu' ){
            var header=null;
            var menu={}; // элемент для хранения кое-какой информации
            scanDomTree(e,function(ee){
                if (ee.className && ee.className=='head') {
                    // нашли заголовок
                    header=ee; // сохраним его для истории
                } else if ( (e!=ee) && ee.tagName && ee.tagName.toUpperCase()=='DIV'){
                    // нашли UL 
                    add_event(header,'mouseover',(function(el){
                        // магия... немного дикая, но симпатичная
                        return function (){
                            if(animation_going) return;
                            // поехали
                            if(el.style.display=='none'){
                                // скрываем открытое
                                if (menu.current) {
                                    var he=menu.current;
                                    animate(he,he.getElementsByTagName("ul")[0].offsetHeight,0,
                                        function(){he.style.display='none';
                                    })
                                }
                                el.style.height='0px';
                                el.style.display='';
                                animate(el,0,el.getElementsByTagName("ul")[0].offsetHeight,function(){
                                    el.style.height='auto';
                                    menu.current=el
                                })
                            }
                        }
                    })(ee))
                    // скрываем пока ...
                    ee.style.display='none';
                }
            })
        }
    })

})
</script>
</head><body>
<div>
    <ul class='Menu'>
        <li>
            <a class="head" href="?p=1.1.1">Guitar</a>
            <div>
            <ul>
                <li><a href="?p=1.1.1.1">Electric</a></li>
                <li><a href="?p=1.1.1.2">Acoustic</a></li>
                <li><a href="?p=1.1.1.3">Amps</a></li>
                <li><a href="?p=1.1.1.4.1">Effects A</a></li>
                <li><a href="?p=1.1.1.4.2">Effects B</a></li>
                <li><a href="?p=1.1.1.4.3">Effects C</a></li>
                <li><a href="?p=1.1.1.4.4">Effects D</a></li>
                <li><a href="?p=1.1.1.5">Accessories</a></li>
            </ul>
            </div>
        </li>
        <li>
            <a class="head" href="?p=1.1.2">Bass</a>
            <div>
            <ul>
                <li><a href="?p=1.1.2.1">Electric</a></li>
                <li><a href="?p=1.1.2.2">Acoustic</a></li>
                <li><a href="?p=1.1.2.3">Amps</a></li>
                <li><a href="?p=1.1.2.4">Effects</a></li>
                <li><a href="?p=1.1.2.5">Accessories</a></li>
            </ul> 
            </div>
        </li>
        <li>
            <a class="head" href="?p=1.1.3">Drums</a>
            <div>
            <ul>
                <li><a href="?p=1.1.3.2">Acoustic Drums</a></li>
                <li><a href="?p=1.1.3.3">Electronic Drums</a></li>
                <li><a href="?p=1.1.3.4">Cymbals</a></li>
                <li><a href="?p=1.1.3.5">Hardware</a></li>
                <li><a href="?p=1.1.3.6">Accessories</a></li>
            </ul> 
            </div>
        </li>
    </ul>
</div>
</body>
</html>

То, что тут называется event  manager'ом и animation выглядит уж слишком упрощенно, но, однако свою функцию исполняет...

Это сообщение отредактировал(а) ksnk - 28.1.2008, 03:03


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
Дата 28.1.2008, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



 smile Супер! Всё классно!  smile 

Мне интересно вот что можно ли как-нибудь сделать задержку скажем в 1сек перед раскрытием пункта меню?


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 28.1.2008, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Цитата(Elfet @  28.1.2008,  15:20 Найти цитируемый пост)
Мне интересно вот что можно ли как-нибудь сделать задержку скажем в 1сек перед раскрытием пункта меню?

Дык! Все можно сделать.
строки 102-104 переписать на  
Код

                    add_event(header,'mouseover',function(){
                        var el=ee;
                        // магия... немного дикая, но симпатичная
                        setTimeout(
                        function (){
 строку 123 - вот так
Код

                        },500);
                    })




--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
Дата 28.1.2008, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Пытаюсь немного модифицировать:
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Simple menu</title>
<style>
ul.Menu { margin: 0; padding: 0; list-style-type: none; width: 200px; }
ul.Menu li { margin: 0; margin-bottom: 0px; padding: 0; border: solid 1px RED}
ul.Menu li a.head { display: block; padding-left: 5px; margin: 0px;
    height: 28px; background: #AFF423; color: #000000; text-decoration: none; line-height: 28px; }
ul.Menu li div.body{ overflow:hidden; display: block; margin: 0px; padding: 0px; list-style-type: none; } /* контейнер оказался необходим :-( */
</style>
<script type="text/javascript">
// бег по DOM'у
function scanDomTree(e,callback,lvl){
    var o= e,
        stack=[null]
    do {
        if(!o) {
            o=stack.pop(); continue  // go up
        }
        if(callback.call(this,o))
            return o;
        if (o.firstChild) {
            stack.push(o.nextSibling);
            o=o.firstChild; // go deep
        } else
            o=o.nextSibling
    } while(stack.length)
    return null;
}
// медленно и печально... в течении секунды...
function animate(e,from,to,callback){
    var i = 30, // <<< вот тут - частота смены кадров.
        disp=(from-to)/i,interval=
    setInterval(function(){
        try{
            e.style.height=(from-=disp)+'px';
        } catch(ee){;}
        if(!--i) {
            clearInterval(interval);
            callback()
        }
    },500/i);
    return interval;
}
// вот это - event handler
// хранилище событий для последующей чистки. Чистка нужна для IE :-(
var handlers=[]
// установка события
function add_event(a,e,o){
    if (a.addEventListener)
        a.addEventListener(e,o,false)
    else if (a.attachEvent) {
        try {
            a.attachEvent( e='on'+e, o);
        } catch (aEx) {}
    }
    handlers.push({a:a,e:e,o:o});
}
function clear_event(a,e,o) {
    if (a.removeEventListener) {
        a.removeEventListener(e, o, false);
    } else {
        try {
            a.detachEvent( /*'on'   */ e, o);
        } catch (aEx) {}
    }
}
// это то, ради чего огород с event manager'ом городили - чистка хвостов...
add_event(window,'unload',function(){
    for(var i in handlers){
        var h=handlers[i];
        clear_event(h.a,h.e,h.o);
    }
})

// все меню
var menu=[];

// а тут, собствено, жужжим ....
add_event(window,'load',function(){
    scanDomTree(document,function(e){
        // для всех элементов с классом Menu
        if(e && e.className && e.className=='Menu' ){
            var bodyer=null;
            var id=0;
            scanDomTree(e,function(ee){
                if (ee && ee.className && ee.className=='body') {
                    // нашли тело
                    bodyer=ee; // сохраним его для истории
                }
                else if (ee && ee.className && ee.className=='head'){
                    menu.push({id:id,body:bodyer,interval:null,current:false});
                    add_event(ee,'mouseover',(function(el){
                        // магия... немного дикая, но симпатичная
                        return function (){
                            menu[id].body.style.height='0px';
                            menu[id].body.style.display='';
                            menu[id].interval = animate(el,0,160,function(){});
                            menu[id].current = true;
                            /*// поехали
                            if(el.style.display=='none'){
                                // скрываем открытое
                                for(var i in menu) {
                                     clearInterval(menu[i].interval);
                                     animate(menu[i].current,menu[i].current.offsetHeight,0,function(){menu[i].current.style.display='none';})
                                     menu.pop();
                                     }
                                el.style.height='0px';
                                el.style.display='';
                                interval = animate(el,0,160,function(){  })
                                menu.push({current:el,interval:interval});
                            }*/
                        }
                    })(id));
                    add_event(ee,'mouseout',(function(el){
                        // магия... немного дикая, но симпатичная
                        return function (){
                            clearInterval(menu[id].interval);
                            menu[id].interval = animate(menu[id].body,menu[id].body.offsetHeight,0,function(){menu[id].body.style.display='none';});
                        }
                    })(id));
                    // скрываем пока ...
                    bodyer.style.display='none';
                    id++;
                }
            }) // end scanDomTree in Menu
        } // end if at Menu
    }) // end scanDomTree for all menu
}) // end add_event load
</script>
</head><body>

    <ul class='Menu'>
        <li>
            <div class="body"><img src="im.png" alt=""/></div>
            <a class="head" href="?p=1.1.1">Guitar</a>
        </li>
        <li>
            <div class="body">
            <img src="im.png" alt=""/>
            </div>
            <a class="head" href="?p=1.1.2">Bass</a>
        </li>
        <li>
            <div class="body">
            <img src="im.png" alt=""/>
            </div>
            <a class="head" href="?p=1.1.3">Drums</a>
        </li>
    </ul>

</body>
</html>


Но что-то магия не срабатывает. Передаётся id 3, а не 0,1 и 2 для каждого.
Мне кажеться так лучше делать, не нужно ждать пока одно закроется что бы другое открыть.


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 28.1.2008, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Магия она магия и есть... ;) Нужно вставить
Код

                        // магия... немного дикая, но симпатичная
                        var iid=id; // Еще одно заклинание
                        return function (){
 и использовать внутри функции iid вместо id. Тогда будет предаваться что надо... 


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
ksnk
Дата 28.1.2008, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Вообще-то использовать mouseout для этого дела как-то неправильно. при свертке-развертке окон легко "выскочить" мышкой за пределы раскрываемого окна и спровоцировать его закрытие...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
Дата 28.1.2008, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Во! Заработала! smile НО помоему это ужас какой-то. Как-нибудь оптимизировать нельзя ли?  smile 
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Simple menu</title>
<style>
ul.Menu { margin: 0; padding: 0; list-style-type: none; width: 200px; }
ul.Menu li { margin: 0; margin-bottom: 0px; padding: 0; border: solid 1px RED}
ul.Menu li a.head { display: block; padding-left: 5px; margin: 0px;
    height: 28px; background: #AFF423; color: #000000; text-decoration: none; line-height: 28px; }
ul.Menu li div.body{ overflow:hidden; display: block; margin: 0px; padding: 0px; list-style-type: none; } /* контейнер оказался необходим :-( */
</style>
<script type="text/javascript">
// бег по DOM'у
function scanDomTree(e,callback,lvl){
    var o= e,
        stack=[null]
    do {
        if(!o) {
            o=stack.pop(); continue  // go up
        }
        if(callback.call(this,o))
            return o;
        if (o.firstChild) {
            stack.push(o.nextSibling);
            o=o.firstChild; // go deep
        } else
            o=o.nextSibling
    } while(stack.length)
    return null;
}
// медленно и печально... в течении секунды...
function animate(e,from,to,callback){
    var i = 30, // <<< вот тут - частота смены кадров.
        disp=(from-to)/i,interval=
    setInterval(function(){
        try{
            e.style.height=(from-=disp)+'px';
        } catch(ee){;}
        if(!--i) {
            clearInterval(interval);
            callback()
        }
    },500/i);
    return interval;
}
// вот это - event handler
// хранилище событий для последующей чистки. Чистка нужна для IE :-(
var handlers=[]
// установка события
function add_event(a,e,o){
    if (a.addEventListener)
        a.addEventListener(e,o,false)
    else if (a.attachEvent) {
        try {
            a.attachEvent( e='on'+e, o);
        } catch (aEx) {}
    }
    handlers.push({a:a,e:e,o:o});
}
function clear_event(a,e,o) {
    if (a.removeEventListener) {
        a.removeEventListener(e, o, false);
    } else {
        try {
            a.detachEvent( /*'on'   */ e, o);
        } catch (aEx) {}
    }
}
// это то, ради чего огород с event manager'ом городили - чистка хвостов...
add_event(window,'unload',function(){
    for(var i in handlers){
        var h=handlers[i];
        clear_event(h.a,h.e,h.o);
    }
})

// все меню
var menu=[];
var current=null;
// а тут, собствено, жужжим ....
add_event(window,'load',function(){
    scanDomTree(document,function(e){
        // для всех элементов с классом Menu
        if(e && e.className && e.className=='Menu' ){
            var bodyer=null;
            var id=0;
            scanDomTree(e,function(ee){
                if (ee && ee.className && ee.className=='body') {
                    // нашли тело
                    bodyer=ee; // сохраним его для истории
                }
                else if (ee && ee.className && ee.className=='head'){
                    menu.push({id:id,body:bodyer,interval:null});
                    add_event(ee,'mouseover',(function(id){
                        // магия... немного дикая, но симпатичная
                        return function (){
                        if(current != id) {
                            clearInterval(menu[id].interval);
                            menu[id].body.style.height='0px';
                            menu[id].body.style.display='';
                            menu[id].interval = animate(menu[id].body,0,160,function(){});
                            current = id;
                            for(var i in menu)
                               if(current != i) {
                               clearInterval(menu[i].interval);
                               menu[i].interval = animate(menu[i].body,
                                                          menu[i].body.offsetHeight,0,
                                                          (function(ii){return function(){menu[ii].body.style.display='none';}})(i)); }//if(current != id)  
                        } }
                    })(id));
                    // скрываем пока ...
                    bodyer.style.display='none';
                    id++;
                }
            }) // end scanDomTree in Menu
        } // end if at Menu
    }) // end scanDomTree for all menu
}) // end add_event load
</script>
</head><body>

    <ul class='Menu'>
        <li>
            <div class="body"><img src="im.png" alt=""/></div>
            <a class="head" href="?p=1.1.1">Guitar</a>
        </li>
        <li>
            <div class="body">
            <img src="im.png" alt=""/>
            </div>
            <a class="head" href="?p=1.1.2">Bass</a>
        </li>
        <li>
            <div class="body">
            <img src="im.png" alt=""/>
            </div>
            <a class="head" href="?p=1.1.3">Drums</a>
        </li>
    </ul>

</body>
</html>


Добавлено через 7 минут и 43 секунды
Особенно вот тут:
Код

// все меню
var menu=[];
var current=null;
// а тут, собствено, жужжим ....
add_event(window,'load',function(){
    scanDomTree(document,function(e){
        // для всех элементов с классом Menu
        if(e && e.className && e.className=='Menu' ){
            var bodyer=null;
            var id=0;
            scanDomTree(e,function(ee){
                if (ee && ee.className && ee.className=='body') {
                    // нашли тело
                    bodyer=ee; // сохраним его для истории
                }
                else if (ee && ee.className && ee.className=='head'){
                    menu.push({id:id,body:bodyer,interval:null});
                    add_event(ee,'mouseover',(function(id){
                        // магия... немного дикая, но симпатичная
                        return function (){
                        if(current != id) {
                            clearInterval(menu[id].interval);
                            menu[id].body.style.height='0px';
                            menu[id].body.style.display='';
                            menu[id].interval = animate(menu[id].body,0,160,function(){});
                            current = id;
                            for(var i in menu)
                               if(current != i) {
                               clearInterval(menu[i].interval);
                               menu[i].interval = animate(menu[i].body,
                                                          menu[i].body.offsetHeight,0,
                                                          (function(ii){return function(){menu[ii].body.style.display='none';}})(i)); }//if(current != id)  
                        } }
                    })(id));
                    // скрываем пока ...
                    bodyer.style.display='none';
                    id++;
                }
            }) // end scanDomTree in Menu
        } // end if at Menu
    }) // end scanDomTree for all menu
}) // end add_event load


Это сообщение отредактировал(а) Elfet - 28.1.2008, 19:11


--------------------
PM MAIL WWW Skype   Вверх
Elfet
  Дата 28.1.2008, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



И вот ещё что:
user posted image
не могу понять откуда берётся этот пробел в IE. Что за стиль в css?!  smile

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



 smile 

PS меню можно вот тут посмотреть: http://elfet.ru/

Это сообщение отредактировал(а) Elfet - 28.1.2008, 19:34


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 28.1.2008, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Я бы рекомендовал не реагировать на события во время анимации, так как было сделано у меня вначале. Иначе придется разбираться с большим количеством одновременно исполняющихся процессов... smile Крыша может уехать... 


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
  Дата 28.1.2008, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Ну, да слабый компьютер не потянет?  smile:biggrin  Но всё таки так красивше  smile 

А что насчёт пробела и задержки можешь подсказать? smile




Если сделать задержку уже не так много одновременных процессов.

Это сообщение отредактировал(а) Elfet - 28.1.2008, 21:16


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 29.1.2008, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Все, это - окончательный вариант smile последняя ошибка исправлена. В менюшку влилась еще одна сущъность - "цепочечная анимация" из соседней темы. Это позволило описать алгоритм анимирования движения более (на мой взгляд) человекопонятно ;), правда, за счет некоей нечеловекопонятной сущьности chain ... Заодно вставлена и задержка... действительно, стало лучше.

P.S. Вариант оказался не окончательным... См сообщение ниже

Это сообщение отредактировал(а) ksnk - 29.1.2008, 17:51


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Elfet
Дата 29.1.2008, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Супер! [+]  smile 
Всё же тут есть что ещё совершенствовать. Если поставить задержку скажем, "5" - то совсем не здорово это выглядит smile


--------------------
PM MAIL WWW Skype   Вверх
ksnk
Дата 29.1.2008, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Вот тут файл chain.js, а вот - собственно скрипт 
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Simple menu</title>
<style>
ul.Menu { margin: 0; padding: 0; list-style-type: none; width: 200px; }
ul.Menu li { margin: 0; margin-bottom: 0px; padding: 0; border: solid 1px RED}
ul.Menu li a.head { display: block; padding-left: 5px; margin: 0px;
    height: 28px; background: #AFF423; color: #000000; text-decoration: none; line-height: 28px; }
ul.Menu li div.body{ overflow:hidden; display: block; margin: 0px; padding: 0px; list-style-type: none; } /* контейнер оказался необходим :-( */
</style>
<script type="text/javascript" src='chain.js'></script>
<script type="text/javascript">
// бег по DOM'у
function scanDomTree(e,callback,lvl){
    var o= e,
        stack=[null]
    if(!lvl)lvl=10000
    do {
        if(!o) {
            o=stack.pop(); continue  // go up
        }
        if(callback.call(this,o))
            return o;
        if (o.firstChild && lvl>=stack.length) {
            stack.push(o.nextSibling);
            o=o.firstChild; // go deep
        } else
            o=o.nextSibling
    } while(stack.length)
    return null;
}
function calcInnerHeight(e){
    var x=0;
    scanDomTree(e,function(e){
        if(e.offsetHeight) 
            x+=parseInt(e.offsetHeight);
        else if(e.height) 
            x+=e.height
        },1);
    return x;
}
// медленно и печально... в течении секунды...
function animate(e,from,to,callback){
    var i = 30, // <<< вот тут - частота смены кадров.
        disp=(from-to)/i,interval=
    setInterval(function(){
        try {
            e.style.height=(from-=disp)+'px';
        } catch(ee){;}
        var x=null;
        if(!--i) { 
            clearInterval(interval);
            if(callback)callback()
        }
    },15);
    return interval;
}
// вот это - event handler
// хранилище событий для последующей чистки. Чистка нужна для IE :-(
var handlers=[]
// установка события
function add_event(a,e,o){
    if (a.addEventListener)
        a.addEventListener(e,o,false)
    else if (a.attachEvent) {
        try {
            a.attachEvent( e='on'+e, o);
        } catch (aEx) {}
    }
    handlers.push({a:a,e:e,o:o});
}
function clear_event(a,e,o) {
    if (a.removeEventListener) {
        a.removeEventListener(e, o, false);
    } else {
        try {
            a.detachEvent( /*'on'   */ e, o);
        } catch (aEx) {}
    }
}
// это то, ради чего огород с event manager'ом городили - чистка хвостов...
add_event(window,'unload',function(){
    for(var i in handlers){
        var h=handlers[i];
        clear_event(h.a,h.e,h.o);
    }
})

//*********************************
// функции анимации
function expand(o,_to){//alert(1);
    return animate(o,0,_to,arguments.callee.next);
}
function expandfin(o){
    o.style.height='auto';
    if(arguments.callee.next)arguments.callee.next();
}
function collapse(o,_to){
    return animate(o,_to,0,arguments.callee.next);
}

function hideit(o){
    o.style.display='none';
    o.style.width='0px';
    if(arguments.callee.next)arguments.callee.next();
}
function showit(o){
    o.style.height='0px';
    o.style.display='';
    if(arguments.callee.next)arguments.callee.next();
}

function expand_menu(el,menu){
    for(var i=0;i< menu.length;i++){
    // круглое - носить, квадратное катать
        if(menu[i].body.style.display=='none') {// закрыто!
            if(menu[i].el==el) menu[i].ch
                .clear()
                .chain(showit,menu[i].body)
                .chain(expand,[menu[i].body,calcInnerHeight(menu[i].body)])
                .chain(expandfin,menu[i].body) //menu[id].body.offsetHeight})
                .run()
        } else { // открыто
            if(menu[i].el!=el) menu[i].ch
                .clear()
                .chain(collapse,[menu[i].body,menu[i].body.offsetHeight])
                .chain(hideit,menu[i].body)
                .run()
        }
    }
    if(arguments.callee.next)arguments.callee.next();
}

// все меню
var menu=[];
var current=null;
// а тут, собствено, жужжим ....
add_event(window,'load',function(){
    scanDomTree(document,function(e){
        // для всех элементов с классом Menu
        if(e && e.className && e.className=='Menu' ){
            var bodyer=null;
            var id=0;
            var timeout,ch=Chain(); // общий поток исполняемых функций
            scanDomTree(e,function(ee){
                if (ee && ee.className && ee.className=='body') {
                    // нашли тело
                    bodyer=ee; // сохраним его для истории
                }
                else if (ee && ee.className && ee.className=='head'){
                    menu.push({el:ee,body:bodyer,ch:Chain()});
                    add_event(ee,'mouseover',function(){
                        ch  .clear()
                            .wait(5)
                            .chain(expand_menu,[ee,menu])
                            .run();
                    });
                    // скрываем пока ...
                    hideit(bodyer);
                    id++;
                }
            }) // end scanDomTree in Menu
        } // end if at Menu
    }) // end scanDomTree for all menu
}) // end add_event load</script>
</head><body>

    <ul class='Menu'>
        <li>
            <div class="body"><img src="03.gif" alt=""/></div>
            <a class="head" href="?p=1.1.1">Guitar</a>
        </li>
        <li>
            <div class="body">
            <img src="03.gif" alt=""/>
            </div>
            <a class="head" href="?p=1.1.2">Bass</a>
        </li>
        <li>
            <div class="body">
            <img src="03.gif" alt=""/>
            </div>
            <a class="head" href="?p=1.1.3">Drums</a>
        </li>
    </ul>
<div id='debug'></div>
</body>
</html>

предыдущие варианты я из своих сообщений местами повыкидывал

Добавлено через 6 минут и 26 секунд
Насчет 5 миллисекунд. Дык, вариант с закрытием нескольких меню был предложен не мной ;) Сами нарисовали - сами и разбирайтесь. Оно сейчас находтся в функции expand_menu

Это сообщение отредактировал(а) ksnk - 29.1.2008, 17:53


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0896 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.