JavaScript: красивый скроллбар для любого элемента
Ожидает приглашения
Начну с того, что я бросил заниматься программирование уже давно, порядка 6 лет назад. Но если быть честным, иногда тешил себе вечерами программируя разные мелкие программки для собственных нужд. Т.е. программирование для меня перешло в разряд хобби.
И вот, на днях я решил взяться за один интернет проект.
Стоит отметить, что я один из тех программистов которые любят изобретать велосипед, каждый раз, когда берутся за что-то новое. Многие скажут, что работая над проектом в первую очередь необходимо учитывать время на разработку и многие будут использовать готовые фреймворки или библиотеки, даже если они будут не удобны и медленнее. Главное — они быстро компенсируют время на разработку. Для меня же в, первую очередь, важно качество, а не количество, важна скорость работы приложения и количество потребляемых им ресурсов.
Встала задача: реализовать свой скроллбар, вписывающийся в дизайн сайта, для div элемента фиксированного по ширине и высоте.
Погуглив немного я не нашел подходящего для себя решения, кроме как использовать jQuery плагин JscrollPane. Меня смутило, что для достижения цели мне придется цеплять сразу три библиотеки: jquery, jquery.mousewheel и jScrollPane. А как же трафик? ;)
В общем я решил накидать решение задачи самостоятельно.
В процессе работы выделились подзадачи:
Результат:

И вот моё решение:
Тут указываем ширину сроллбара и фоновую картинку, ширину, высоту и картинки для стрелочек.
Прописываем элемент
И добовляем наш скроллбар на него:
Данный код работает во всех последних браузерах.
И вот, на днях я решил взяться за один интернет проект.
Стоит отметить, что я один из тех программистов которые любят изобретать велосипед, каждый раз, когда берутся за что-то новое. Многие скажут, что работая над проектом в первую очередь необходимо учитывать время на разработку и многие будут использовать готовые фреймворки или библиотеки, даже если они будут не удобны и медленнее. Главное — они быстро компенсируют время на разработку. Для меня же в, первую очередь, важно качество, а не количество, важна скорость работы приложения и количество потребляемых им ресурсов.
Встала задача: реализовать свой скроллбар, вписывающийся в дизайн сайта, для div элемента фиксированного по ширине и высоте.
Погуглив немного я не нашел подходящего для себя решения, кроме как использовать jQuery плагин JscrollPane. Меня смутило, что для достижения цели мне придется цеплять сразу три библиотеки: jquery, jquery.mousewheel и jScrollPane. А как же трафик? ;)
В общем я решил накидать решение задачи самостоятельно.
В процессе работы выделились подзадачи:
- кроссбраузерность;
- скролл колесиком мыши;
- возможность добавлять скроллбар нескольким элементам на одной страничке.
Результат:

И вот моё решение:
scroller.css
Тут указываем ширину сроллбара и фоновую картинку, ширину, высоту и картинки для стрелочек.
.scrollUp
{
width: 24px;
height: 28px;
position: absolute;
left: 0px;
top: 0px;
cursor: pointer;
background-image: url(../imgs/maininterface/scroller_top_i.png);
}
.scrollUp:hover
{
background-image: url(../imgs/maininterface/scroller_top_s.png);
}
.scrollDown
{
width: 24px;
height: 28px;
position: absolute;
left: 0px;
bottom: 0px;
cursor: pointer;
background-image: url(../imgs/maininterface/scroller_bottom_i.png);
}
.scrollDown:hover
{
background-image: url(../imgs/maininterface/scroller_bottom_s.png);
}
.scroller
{
width: 24px;
height: 5px;
position: absolute;
left: 0px;
top: 28px;
cursor: pointer;
background-image: url(../imgs/maininterface/scroller_i.png);
}
.scroller:hover
{
background-image: url(../imgs/maininterface/scroller_s.png);
}
.scrollBody
{
width: 24px;
min-height: 100%;
cursor: pointer;
background-image: url(../imgs/maininterface/scroller_body.png);
}
.scrollBox
{
float: right;
width: 24px;
height: 100%;
position: absolute;
top: 0px;
right: 0px;
background-color: #000000;
}
scroller.js
function getTrueOffsetLeft(ele)
{
var n = 0;
while (ele)
{
n += ele.offsetLeft || 0;
ele = ele.offsetParent;
}
return n;
}
function getTrueOffsetTop(ele)
{
var n = 0;
while (ele)
{
n += ele.offsetTop || 0;
ele = ele.offsetParent;
}
return n;
}
function getMouse(e, obj)
{
var x = e.clientX - getTrueOffsetLeft(obj) + window.pageXOffset;
var y = e.clientY - getTrueOffsetTop(obj) + window.pageYOffset;
return [x,y];
}
function scrollDown(id)
{
document.getElementById(id).scrollTop += 10;
scrollYdelta = (document.getElementById(id).scrollHeight-(document.getElementById(id).offsetHeight));
widthScrollArrows = document.getElementById(id+'ScrollDown').offsetHeight*2;
posYScroller = ((document.getElementById(id).offsetHeight-widthScrollArrows)/scrollYdelta)*
document.getElementById(id).scrollTop +document.getElementById(id+'ScrollDown').offsetHeight;
if (posYScroller>(document.getElementById(id).offsetHeight -
document.getElementById(id+'ScrollDown').offsetHeight -
document.getElementById(id+'Scroller').offsetHeight))
posYScroller=document.getElementById(id).offsetHeight-document.getElementById(id+'ScrollDown').offsetHeight-document.getElementById(id+'Scroller').offsetHeight;
document.getElementById(id+'Scroller').style.top = posYScroller+"px";
document.getElementById(id+'ScrollBox').style.top = document.getElementById(id).scrollTop + "px";
}
function scrollUp()
{
document.getElementById(id).scrollTop -= 10;
scrollYdelta = (document.getElementById(id).scrollHeight-(document.getElementById(id).offsetHeight));
widthScrollArrows = document.getElementById(id+'ScrollDown').offsetHeight*2;
posYScroller = ((document.getElementById(id).offsetHeight-widthScrollArrows)/scrollYdelta)*
document.getElementById(id).scrollTop + document.getElementById(id+'ScrollDown').offsetHeight;
document.getElementById(id+'Scroller').style.top = posYScroller+"px";
document.getElementById(id+'ScrollBox').style.top = document.getElementById(id).scrollTop + "px";
}
function onMouseWheelScroll(e)
{
id = this.id;
e = e || event;
if (!e.wheelDelta)
{
e.wheelDelta = -40*e.detail; // для Firefox
}
document.getElementById(id).scrollTop -= e.wheelDelta;
widthScrollArrows = document.getElementById(id+'ScrollDown').offsetHeight*2;
scrollYdelta = (document.getElementById(id).scrollHeight-(document.getElementById(id).offsetHeight));
posYScroller = ((document.getElementById(id).offsetHeight-widthScrollArrows)/scrollYdelta)*
document.getElementById(id).scrollTop + document.getElementById(id+'ScrollDown').offsetHeight;
if (posYScroller>(document.getElementById(id).offsetHeight -
document.getElementById(id+'ScrollDown').offsetHeight -
document.getElementById(id+'Scroller').offsetHeight))
posYScroller=document.getElementById(id).offsetHeight-document.getElementById(id+'ScrollDown').offsetHeight-document.getElementById(id+'Scroller').offsetHeight;
document.getElementById(id+'ScrollBox').style.top = document.getElementById(id).scrollTop + "px";
document.getElementById(id+'Scroller').style.top = posYScroller+"px";
}
function onMouseScrollDown (e,id)
{
e = e || event;
mouse = getMouse(e, document.getElementById(id+'ScrollBody'));
mouse[1]= mouse[1]+document.getElementById(id).scrollTop;
posYScroller = mouse[1];
widthScrollArrows = document.getElementById(id+'ScrollDown').offsetHeight*2;
scrollYdelta = (document.getElementById(id).scrollHeight-(document.getElementById(id).offsetHeight-widthScrollArrows));
document.getElementById(id).scrollTop = (posYScroller-document.getElementById(id+'ScrollDown').offsetHeight)/
((document.getElementById(id).offsetHeight-widthScrollArrows)/scrollYdelta);
document.getElementById(id+'ScrollBox').style.top = document.getElementById(id).scrollTop + "px";
document.getElementById(id+'Scroller').style.top = posYScroller+"px";
}
function addScroller(element)
{
id=element.id;
src='<div id="'+id+'ScrollBox" class="scrollBox">\n\
<div id="'+id+'Scroller" class="scroller"></div>\n\
<div id="'+id+'ScrollUp" class="scrollUp" onmousedown="scrollUp(\''+id+'\')"></div>\n\
<div id="'+id+'ScrollBody" class="scrollBody" onmousedown="onMouseScrollDown(event,\''+id+'\')"></div>\n\
<div id="'+id+'ScrollDown" class="scrollDown" onmousedown="scrollDown(\''+id+'\')"></div>';
jsText = 'document.getElementById("'+id+'").addEventListener ("mousewheel", onMouseWheelScroll, false);\n\
document.getElementById("'+id+'").addEventListener ("DOMMouseScroll", onMouseWheelScroll, false);';
js = document.createElement('script');
js.setAttribute('type', 'text/javascript');
js.setAttribute('defer', 'defer');
js.innerHTML = jsText;
element.innerHTML=element.innerHTML+src;
element.appendChild(js);
}
Прописываем элемент
<div id="boxxx" style=" height: 300px; width: 200px; background-color: #aaaaaa; overflow: hidden; position: relative; left: 300px;" >
Длинный текст
</div>
И добовляем наш скроллбар на него:
<script type='text/javascript'>
addScroller(document.getElementById("boxxx"));
</script>
Данный код работает во всех последних браузерах.