22.02.2010, 16:16
|
Интересующийся
|
|
Регистрация: 22.02.2010
Сообщений: 15
|
|
slider не успевает за мышью
Доброго Всем. Есть два слайдера, у каждого два ползунка. Проблема в том что везде, кроме лисички, onmousemove не успевает за движением мыши. Понятное дело, что размеры ползунка невелики, но тут даже onmouseout не помогает.(Кстати сие творение видно на ofis.ru/?devel-mode). Недавно работаю со скриптом, и не хочу исп-вать библиотеки.
Код скорее всего кому-то покажется корявым. Да, и не работает onmouseup, хотя хотелось бы. Фокус в том что при движении ползунка, растягиваются их родительские дивы, сам слайдер - таблица из 3-х ячеек.Если нужен код, я выложу, т.к. щас не имею возможность (чёртова Лиса не хочет firebug ставить), кому интересно, может у себя в жуке посмотреть пока(с того же адреса)
P.S. Извините что сразу не могу код вывести здесь, да и не маленький он(наверное по причине неоптимальности...))
|
|
22.02.2010, 16:52
|
|
Пионэр
|
|
Регистрация: 16.11.2009
Сообщений: 1,322
|
|
Ну, тут все достаточно просто.
Возьмём по горизонтали: у нас есть css свойство left (ну, или margin-left), которое однозначно определяет положение слайдера. Также, каждое мышиное событие имеет свойство .pageX, которое однозначно определяет положение курсора.
Дальше: при опускании кнопки над слайдером высчитываем что-то типа
offset = left - e.pageX
, и пока не поднята кнопка при каждом mousemove над документом считаем:
left = offset + e.pageX
.
Теоретически, эта привязка нехороша, если пользователь решит поменять размер окна во время перетягивания, но практически это делать пока никому не приходило в голову.
|
|
22.02.2010, 20:46
|
Интересующийся
|
|
Регистрация: 22.02.2010
Сообщений: 15
|
|
В mousemove'e пользуюсь clientX. А вот как раз пока не поднята кнопка - эта часть не работает (В IE только при повторном нажатии, в остальных - никак). У меня в onmousedown определяется onmousemove. В onmouseup идёт либо object.onmousemove=null, либо object.removeEventListener("mousemove",mov,false)( что не работает). Подскажите, где определить поднятие мышки? В функции движения? нажатия? или отдельно? и почему removeEventListener не работает? Спасибо...А фсё таки не успевает в ослике мышка))
Последний раз редактировалось goldmember, 22.02.2010 в 20:55.
|
|
22.02.2010, 21:31
|
Кандидат Javascript-наук
|
|
Регистрация: 21.11.2008
Сообщений: 114
|
|
Проблема в том, что лисичка в отличие от всех браузеров, автоматически захватывает мышь при mousedown. Тут нужно либо юзать готовую кроссбраузерную реализацию захвата мыши, либо писать свою. Есть вариант проще: можно повесить обработчики события на document, но тогда события будут гулять где попало, и возможны побочные эффекты в виде спонтанного выделения текста и т.п. Что касательно mousemove, то лучше каждый раз не цеплять и отцеплять обработчик события, а сделать где-нибудь флаг: если true, то тащим, иначе не тащим.
P.S. По поводу захвата: в осле это делается через setCapture, в остальных через 3-й параметр true в функции addEventListener.
Последний раз редактировалось vk65535, 22.02.2010 в 21:42.
|
|
23.02.2010, 13:57
|
Интересующийся
|
|
Регистрация: 22.02.2010
Сообщений: 15
|
|
Вот код сих потуг. Здесь ищу объекты и вешаю обработчики. Так в этом и вопрос где ставить флаг?
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)
|
|
23.02.2010, 16:42
|
|
Пионэр
|
|
Регистрация: 16.11.2009
Сообщений: 1,322
|
|
vk65535,
Огнелису достаточно и e.preventDefault() на mousedown, насколько мне известно.
|
|
23.02.2010, 19:23
|
Кандидат Javascript-наук
|
|
Регистрация: 21.11.2008
Сообщений: 114
|
|
Кстати, тут же есть статья, правда без захвата мыши, но как вариант вполне приемлемо.
http://javascript.ru/ui/draganddrop
|
|
24.02.2010, 10:25
|
Интересующийся
|
|
Регистрация: 22.02.2010
Сообщений: 15
|
|
Благодарен за ссылку. Делов то было поставить в обработчики return false, и нормальный захват на правую кнопку переписать...
|
|
24.02.2010, 12:03
|
Интересующийся
|
|
Регистрация: 22.02.2010
Сообщений: 15
|
|
Хех, не могу определить детей у таблицы(дальше TBODY не идёт), хотя определяю описанным способом...
|
|
|
|