slider не успевает за мышью
Доброго Всем. Есть два слайдера, у каждого два ползунка. Проблема в том что везде, кроме лисички, onmousemove не успевает за движением мыши. Понятное дело, что размеры ползунка невелики, но тут даже onmouseout не помогает.(Кстати сие творение видно на ofis.ru/?devel-mode). Недавно работаю со скриптом, и не хочу исп-вать библиотеки.
Код скорее всего кому-то покажется корявым. Да, и не работает onmouseup, хотя хотелось бы. Фокус в том что при движении ползунка, растягиваются их родительские дивы, сам слайдер - таблица из 3-х ячеек.Если нужен код, я выложу, т.к. щас не имею возможность (чёртова Лиса не хочет firebug ставить), кому интересно, может у себя в жуке посмотреть пока(с того же адреса) P.S. Извините что сразу не могу код вывести здесь, да и не маленький он(наверное по причине неоптимальности...)) |
Ну, тут все достаточно просто.
Возьмём по горизонтали: у нас есть css свойство left (ну, или margin-left), которое однозначно определяет положение слайдера. Также, каждое мышиное событие имеет свойство .pageX, которое однозначно определяет положение курсора. Дальше: при опускании кнопки над слайдером высчитываем что-то типа offset = left - e.pageX, и пока не поднята кнопка при каждом mousemove над документом считаем: left = offset + e.pageX. Теоретически, эта привязка нехороша, если пользователь решит поменять размер окна во время перетягивания, но практически это делать пока никому не приходило в голову. |
В mousemove'e пользуюсь clientX. А вот как раз пока не поднята кнопка - эта часть не работает (В IE только при повторном нажатии, в остальных - никак). У меня в onmousedown определяется onmousemove. В onmouseup идёт либо object.onmousemove=null, либо object.removeEventListener("mousemove",mov,false)( что не работает). Подскажите, где определить поднятие мышки? В функции движения? нажатия? или отдельно? и почему removeEventListener не работает? Спасибо...А фсё таки не успевает в ослике мышка))
|
Проблема в том, что лисичка в отличие от всех браузеров, автоматически захватывает мышь при mousedown. Тут нужно либо юзать готовую кроссбраузерную реализацию захвата мыши, либо писать свою. Есть вариант проще: можно повесить обработчики события на document, но тогда события будут гулять где попало, и возможны побочные эффекты в виде спонтанного выделения текста и т.п. Что касательно mousemove, то лучше каждый раз не цеплять и отцеплять обработчик события, а сделать где-нибудь флаг: если true, то тащим, иначе не тащим.
P.S. По поводу захвата: в осле это делается через setCapture, в остальных через 3-й параметр true в функции addEventListener. |
Вот код сих потуг. Здесь ищу объекты и вешаю обработчики. Так в этом и вопрос где ставить флаг?
1var isIE=0;isOp=0;isFF=0; 2var verBr=navigator.userAgent; 3if (verBr.indexOf("Opera")!=-1) 4isOp=1; 5else 6{ 7if (verBr.indexOf("MSIE")!=-1) 8isIE=1; 9else isFF=1; 10} 11 12var offX; 13var knobWidth=9; 14 15function pageInit(){ 16 var allEl=document.getElementsByTagName('IMG'); 17 var allSlide=document.getElementsByTagName('TABLE'); 18 for(var i=0;i<allEl.length;i++){ 19 if(isIE){ 20 allEl[i].onmousedown=handleMouseDown; 21 allEl[i].onmouseup=handleMouseUp; 22 } 23 else{ 24 allEl[i].addEventListener("mousedown",handleMouseDown,false); 25 allEl[i].addEventListener("mouseup",handleMouseUp,false); 26 } 27 } 28 for(var i=0;i<allSlide.length;i++){ 29 if(isIE) 30 allSlide[i].onclick=sliderClick; 31 else 32 allSlide[i].addEventListener("click",sliderClick,false); 33 } 34} 35 36function handleMouseDown(){ 37 var movableObject=getMovableObject(this); 38 if(movableObject) 39 offX=offsetPosition(movableObject.parentNode); 40 if(isIE){ 41 movableObject.onmousemove=handleMouseMove; 42 movableObject.onmouseout=handleMouseOut; 43 } 44 else{ 45 movableObject.addEventListener("mousemove",handleMouseMove,false); 46 movableObject.addEventListener("mouseout",handleMouseOut,false); 47 } 48} 49 50function handleMouseMove(e){ 51 var event=(window.event)?window.event:e; 52 var movableObject=getMovableObject(this); 53 if(movableObject){ 54 if((movableObject.id!="rBegun")&&(movableObject.id!="rBegun1")){ 55 movableObject.parentNode.style.width=((event.clientX-offX)+Math.ceil(knobWidth/2))+"px"; 56 if(movableObject.id=="lBegun") 57 document.getElementById('minsq').value=offsetPosition(movableObject)-offsetPosition(movableObject.parentNode); 58 else 59 document.getElementById('minco').value=offsetPosition(movableObject)-offsetPosition(movableObject.parentNode); 60 } 61 else{ 62 var tab=document.getElementById('forslide2'); 63 var tab1=document.getElementById('forslide1'); 64 var offRight=offsetPosition(tab)+tab.offsetWidth; 65 var offRight1=offsetPosition(tab1)+tab1.offsetWidth; 66 if(movableObject.id=="rBegun"){ 67 document.getElementById('maxsq').value=offRight1+event.clientX; 68 movableObject.parentNode.style.width=(offRight1-event.clientX+Math.ceil(knobWidth/2))+"px" 69 } 70 else{ 71 movableObject.parentNode.style.width=(offRight-event.clientX+Math.ceil(knobWidth/2))+"px"; 72 document.getElementById('maxco').value=offRight+event.clientX; 73 } 74 } 75 } 76} 77 78function handleMouseOut(e){ 79 var event=(window.event)?window.event:e; 80 var movableObject=getMovableObject(this); 81 if(movableObject){ 82 if((movableObject.id!="rBegun")&&(movableObject.id!="rBegun1")) 83 if(isIE||isOp){ 84 movableObject.parentNode.style.width=movableObject.parentNode.offsetWidth+10+(event.clientX-offsetPosition(movableObject)-Math.ceil(knobWidth/2)); 85 } 86 else 87 movableObject.parentNode.style.width=movableObject.parentNode.offsetWidth+(event.clientX-offsetPosition(movableObject)-Math.ceil(knobWidth/2)); 88 else 89 if(isIE||isOp) 90 movableObject.parentNode.style.width=(movableObject.parentNode.offsetWidth+Math.ceil(knobWidth/2))+(offsetPosition(movableObject)-event.clientX); 91 else 92 movableObject.parentNode.style.width=(movableObject.parentNode.offsetWidth+Math.ceil(knobWidth/2))+(offsetPosition(movableObject)-event.clientX); 93 } 94} 95 96function handleMouseUp(){ 97 var movableObject=getMovableObject(this); 98 if(movableObject){ 99 if(isIE||isOp){ 100 movableObject.onmousemove=null; 101 movableObject.onmouseout=null; 102 } 103 else 104 movableObject.removeEventListener("mousemov",handleMouseMove,false); 105 } 106} 107function buttonalert(event) 108{ 109 var button; 110 if (event.which == null) 111 button= (event.button < 2) ? "LEFT" : 112 ((event.button == 4) ? "MIDDLE" : "RIGHT"); 113 else 114 button= (event.which < 2) ? "LEFT" : 115 ((event.which == 2) ? "MIDDLE" : "RIGHT"); 116 dont(event); 117 return button; 118} 119function dont(event) 120{ 121 if (event.preventDefault) 122 event.preventDefault(); 123 else 124 event.returnValue= false; 125 return false; 126} 127function sliderClick(e){ 128 var event=(window.event)?window.event:e; 129 var slider=getSlideObject(this); 130 if(slider){ 131 if(slider.id=="forslide1") 132 var right=offsetPosition(slider)+slider.offsetWidth; 133 var beg1=document.getElementById('lBegun'); 134 var beg2=document.getElementById('rBegun'); 135 var beg3=document.getElementById('lBegun1'); 136 var beg4=document.getElementById('rBegun1'); 137 if(slider.id=="forslide2"){ 138 var right1=offsetPosition(slider)+slider.offsetWidth; 139 if((event.clientX-offsetPosition(beg3))<(offsetPosition(beg4)-event.clientX)){ 140 beg3.parentNode.style.width = (event.clientX-offsetPosition(slider)+Math.round(knobWidth/2))+"px"; 141 document.getElementById("minco").value=(offsetPosition(beg3)-offsetPosition(slider)+Math.round(knobWidth/2)) 142 } 143 else{ 144 beg4.parentNode.style.width = (right1-event.clientX+Math.round(knobWidth/2))+"px"; 145 document.getElementById("maxco").value=(right1+offsetPosition(beg4)+Math.round(knobWidth/2)) 146 } 147 } 148 if(slider.id=="forslide1"){ 149 var right=offsetPosition(slider)+slider.offsetWidth; 150 if((event.clientX-offsetPosition(beg1))<(offsetPosition(beg2)-event.clientX)){ 151 beg1.parentNode.style.width = (event.clientX-offsetPosition(slider)+Math.round(knobWidth/2))+"px"; 152 document.getElementById("minsq").value=(offsetPosition(beg1)-offsetPosition(slider)+Math.round(knobWidth/2)) 153 } 154 else{ 155 beg2.parentNode.style.width = (right-event.clientX+Math.round(knobWidth/2))+"px"; 156 document.getElementById("maxsq").value=(right+offsetPosition(beg2)+Math.round(knobWidth/2)) 157 } 158 } 159 } 160} 161 162function offsetPosition(elem){ 163 var offsetLeft=0; 164 do{ 165 offsetLeft+=elem.offsetLeft; 166 } 167 while(elem=elem.offsetParent); 168 return offsetLeft; 169} 170function getMovableObject(object){ 171 if (object.tagName == "BODY") return null; 172 if(object.className=="knob") return object; 173 return getMovableObject(object.parentNode); 174} 175function getSlideObject(object){ 176 if (object.tagName == "BODY") return null; 177 if(object.className=="polzun") return object; 178 return getSlideObject(object.parentNode); 179} 180function getParent(obj, parentClassName) { 181 return (obj.className==parentClassName)?obj:getParent(obj.parentNode, parentClassName); 182} 183window.onload=pageInit; На заморочки с родителями внимания не обращайте, не в них суть. И кстати захват я делал, всё равно не помогает (параметр true) |
vk65535,
Огнелису достаточно и e.preventDefault() на mousedown, насколько мне известно. |
Кстати, тут же есть статья, правда без захвата мыши, но как вариант вполне приемлемо.
http://javascript.ru/ui/draganddrop |
Благодарен за ссылку. Делов то было поставить в обработчики return false, и нормальный захват на правую кнопку переписать...
|
Хех, не могу определить детей у таблицы(дальше TBODY не идёт), хотя определяю описанным способом...
|
Часовой пояс GMT +3, время: 00:04. |