прокручивающееся подменю
доброго времени суток.
проблема в том что подменю очень длинные и выходят за границу страницы, и ничего другого представить себе не могу как прокручивающееся подменю. помогите с реализацией на javascript. уже который день сижу на месте, не знаю что искать, куда смотреть. |
css-свойство overflow
|
)), угу.
но ставить полосу прокрутки подменюшке не красиво. а значит надо без неё "проворачивать" список, скрывая элементы которые "уходят" за границу видимости. к тому же надо "родить" )) как определить стрелка(курсор) мышки ниже половины списка или выше, что бы прокрутить список к началу или концу |
каждый элемент списка ловит события наведения мышки, далее начинается просчет координат каждого элемента, при этом должны быть два массива с отображенными элементами и скрытыми. функция изменения положения элементов должна знать координаты начала и конца списка. если координаты первого отображенного элемента выходят за границы дива то мы его скрываем и переносим в массив скрытых, и одновременно показываем первый скрытый элемент в конце списка. (организуем два стека, короче) вместе с тем запускается функция перемещения всех элементов списка вверх или вниз. Хотя в том что удасться обеспечить их плавное перемещение я сильно сомневаюсь :)
вот наверно как-то так :) |
огого. страшно звучит. я думал вообще без массивов обойтись, просто статичными списками, которыми "ёрзать" :D
Slavenin то что вы описали смахивает на эту реализацию http://deluxe-menu.com/scrollable-submenus-sample.html...но такое собирать это ужас, да и у меня двуязычное меню, в два раза больше возни... |
ну да, примерно тоже самое, ничего сложного, меню разве что прописывать, но их можно отдельно в файликах хранить или в бд. я просто точно не помню, можно ли переместить элемент за границу дива, чтобы при этом не изменился сам размер дива, если можно, то вполне можно обойтись одним списком менюшек, просто менять их координаты и вверх вниз и все, самая большая сложность это отслеживать и менять функции смещения для каждого элемента, чтобы то что ниже центра смещало элементы вниз, а то что выше вверх.
|
<ul id="p" onmousemove="gg(event, this)"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> </ul> * { margin: 0; padding: 0; } #p { border:1px solid #000; height: 200px; overflow-y: scroll; } function gg(e,t){ var percent=t.offsetHeight/100; // %=(всего/100) percent=Math.floor(e.clientY/percent); // %=(позиция/%) if(percent<25) { //up } else if(percent>75) { //down } } вот такую фигню собрал...но не получается список "провернуть", не срабатывает ни scroll, ни scrollBy, ни scrollTo, даже когда overflow-y: scroll, не говоря уже о overflow-y: hidden. может кто подскажет, как должно быть? как правильно |
спасибо отозвавшимся. сам разобрался. хотя если у кого нить идеи возникнут, я буду рад услышать.
|
каждый элемент на страницу имеет свои координаты можно их менять http://javascript.ru/ui/offset двигая весь список целиком вверх или вниз
|
всё никак скрипт до ума не доведу.
попытался приспособить код к меню. меню многоуровневое, с выпадающими списками которые ограничены высотой в 200px var sliding=false; function up(t){ sliding=clearInterval(sliding); sliding=setInterval( function() { if(t.scrollTop>0) t.scrollTop--; else sliding=clearInterval(sliding); } , 20); } function down(t){ var From=t.scrollTop+t.offsetHeight; sliding=clearInterval(sliding); sliding=setInterval( function() { if(From<t.scrollHeight) t.scrollTop++; else sliding=clearInterval(sliding); } , 20); } function gg(e,t){ var ee = e.target || e.srcElement; var percent=t.offsetHeight/100; percent=Math.floor((e.clientY-t.offsetParent.offsetTop)/percent); if(percent<20) up(t); else if(percent>80) down(t); } function stop(){ sliding=clearInterval(sliding); } window.onload = function(){ var start=document.getElementById('nav_v'); var height=start.getElementsByTagName('li')[0].offsetHeight; var all=start.getElementsByTagName('ul'); for(var i=0; i<all.length; i++) { if((all[i].childNodes.length * height) > 200) { all[i].style.overflow = 'hidden'; all[i].onmouseout = stop; all[i].onmouseover=function(event){ gg(event || window.event, this); }; } } } больше всего волнует функция gg(e,t) (хотя не против если и в других укажите на ошибки). в прототипе "процент" (позицию курсора мышки относительно выпадающего списка) вычислял в при помощи percent=Math.floor((e.clientY-t.offsetTop)/percent); и всё бы ничего, но когда прикрутил к рабочему меню скрипт начал "козлить", долго думая и ища окольные пути додумал до percent=Math.floor((e.clientY-t.offsetParent.offsetTop)/percent); работает лучше, но процент вычисляет с погрешностью. кто по толковее подскажите как исправить :help: буду весьма признателен. |
неужели ни у кого идей нет, критики хотя бы ;)
|
у меня там ещё в 43 строчке ошибка :( (с ней разобрался)
|
all[i].childNodes.length тут?? |
угу. исправил. там заодно и текстовые узлы подсчитывались.
но до сих пор не знаю как функцию gg() поправить |
что она должна делать?
|
оооо....хоть кто-то заинтересовался моим вопросом :dance:
есть многоуровневое меню, некоторые выпадающие подменю очень длинные, и выходят за нижнюю границу страницы. соответственно задумал ограничить списки максимальной высотой и всё лишнее "обрезать" свойством all[i].style.overflowY = 'hidden'; а функция должна вычислить позицию стрелки мышки относительно выпадающего списка, в процентном соотношении (я вроде тоже самое на первой странице топика сказал). то есть если стрелка внизу выпадающего списка, то прокрутить список вверх, что бы показать те элементы которые скрыты внизу, и наоборот, если стрелка рядом с верхней границей то прокрутить вниз, что бы показать что сверху скрыто. не знаю как ещё объяснить :-? тоже самое можно наблюдать если в браузерах (проверял только на FF, Opera, Crome) нажать среднюю кнопку мышки, а потом вводить стрелкой вверх, низ. |
я делал так. но чуть по-другому. называл это скроллом аля Iphone
только у меня было горизонтально. http://mazktest.ucoz.ru/shabla/ осталось только тут (меню сверху). делал на скорую руку, на JQuery структура у списка была такой <!-- для позиционирования ВСЕГО списка --> <div id="wrapper"> <!-- стрелка влево. --> <a class="ltr"> <- </a> <!-- сам список --> <ul> <!-- обертка для LI --> <span> <li>LOREM IPSUM</li> </span> </ul> <!-- стрелка вправо. --> <a class="rtr"> -> </a> </div> для UL в стилях прописал overflow:hidden, потому что у меня он горизонтальный, поэтому прокрутка только по X. Чтобы убрать их переносимость и сохранить выравнивание, поставил white-space: nowrap;. ( если поставить display:inline-block, будут проблемы с вертикальным выравниванием. я давно это делал, не помню, в каком браузере) у стрелок float:left и они сдвинуты в сторону. чтобы они не перемещались вместе со скроллом, поставлены рядом со списком у самих LI стоит просто display:inline-block попробую сделать пример для такого списка, но вертикального <style> #wrapper { height : 100px; width: 200px; } #wrapper a { margin : 10px 0; } #wrapper ul { border: 1px red dashed; height : 100%; overflow-y: scroll; } </style> <div id="wrapper"> <a class="ltr">ВВЕРХ</a> <ul> <span> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> <li>LOREM IPSUM</li> </span> </ul> <a class="rtr"> ВНИЗ </a> </div> сижу с FF4.01, отображается нормально. напишем код.попробую без JQuery. размещу на юкозе |
что-то я ничего не вижу на сайте
|
забыл логин и пароль на нем. пофигу :)
вот пример. убунту-стайл. прокрутка по наводке. <style> #wrapper { height : 100px; width: 200px; } #wrapper a { margin : 0; display:block; background-color: #555555; padding: 5px; } #wrapper ul { border: 1px red dashed; height : 100%; overflow-y: hidden; margin:0; } </style> <div id="wrapper"> <a class="up">UP</a> <ul> <span> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> <li>16</li> <li>17</li> <li>18</li> </span> </ul> <a class="down"> DOWN </a> </div> <script> // элементы скролла var wrapper = document.getElementById('wrapper'), as = document.getElementsByTagName( 'a' ), // 0 - UP, 1 - DOWN ul = document.querySelector( 'ul' ), span = document.querySelector( 'span' ), need = (span.offsetHeight||span.scrollHeight) > ul.offsetHeight, // если скролл есть, то true; val = 10; // будет прокручивать по 10 пикселей //универсальная ф-я для стрелок. function turn( el ){ //вверх или вниз? var up = el.className==='up'; ul.scrollTop = (up ? (ul.scrollTop - val) : (ul.scrollTop + val) ) } // обработчик для стрелок for(var i=0;i<2;i++) (function(i){ // при наведении на стрелку будет прокрутка, с интервалом. as[i].onmouseover = function(){ as[i].setAttribute('scid',setInterval( function(a){ turn(a); },50,as[i] )) } // когда уводят мышь со стрелки, прокрутка убирается as[i].onmouseout = function(){ clearInterval(as[i].getAttribute('scid'));as[i].removeAttribute('scid'); } })(i) </script> |
универсальность функции turn( el ) понравилась :)
буду разбираться. спасибо за пример. аха, у тебя другой метод. эти кнопки я думал после добавить, но и лучше будет твой вариант более простой и короткий использовать и не заморачиваться. |
если кто забредёт сюда, и увидит как улучшить мою функцию я буду рад выслушать замечания и предложения.
|
Часовой пояс GMT +3, время: 00:58. |