![]() |
![]()
![]()
![]() ![]() ![]() ![]() ![]() ![]()
![]() ![]()
![]() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
Nejprve vÜak musφm zaΦφt milou povinnostφ. Jak mnozφ z vßs jist∞ post°ehli, na sv∞te je dalÜφ verze Opery. AΦ se jednß o beta verzi, i ta naznaΦila mnoho pozitivnφho. Pro mne je tφm nejv∞tÜφm krokem vp°ed mnohem v∞tÜφ podpora DOM. Pravda, nenφ kompletnφ, ale mnoh²m skript∙m dostaΦujφcφ. Jak jsem v diskusi nad n∞kter²m z minul²ch dφl∙ prohlßsil, tφm jedin²m d∙vodem, proΦ jsem Operu vylouΦil z tohoto serißlu, byla jejφ chyb∞jφcφ DOM implementace.
Tento ale ji₧ argument padß, proto je nunΘ nejprve zm∞nit skript pro rozpoznßvßnφ prohlφ₧eΦ∙ sniffer.js. Jednak p°ibylo rozpoznßnφ Opery 7.0, dßle pak rozliÜenφ verzφ MSIE 5.5, 5 a 6. To proto, neb n∞kterΘ drobnΘ rozdφly mohou vadit a bylo by na Ükodu vÜechny MSIE hßzet do jednoho pytle. Na obranu proti mo₧nΘ faleÜnΘ identifikaci Opery byla zp°φsn∞na kritΘria pro p°i°azenφ jednotliv²ch prom∞nn²ch (IE a NS), pouhß identifikace nßzvu a zßkladnφch metod ji₧ nestaΦily.
if(ua.indexOf('opera')>-1 && document.getElementById && document.childNodes) {OPERA=true;}
....
// Identifikace OPERY 7 s falesnym oznacovanim
if(!IE && !NS && !OPERA && document.addEventListener) {OPERA=true;}
Ale zp∞t k nosnΘmu tΘmatu toho Φlßnku. Nejprve co budeme k realizaci pot°ebovat. Jak vÜichni vφte, drag&drop je vlastn∞ uchycenφ n∞jakΘho objektu, ta₧enφ na jinou pozici a upuÜt∞nφ na cφlovΘ pozici, vÜe pomocφ kursoru. Mφsφ se zde udßlosti, pozicovßnφ a prßce se strukturou dokumentu. Ne₧ zaΦnu popisovat svΘ myÜlenkovΘ pochody, podφvejte se na jednoduchou ukßzku, vyu₧φvajφcφ zmi≥ovanou knihovnu sniffer.js a popisovanou knihovnu dragdrop.js.
Inicißtorem ka₧dΘho pokusu o p°esunutφ objektu je stisknutφ tlaΦφtka myÜi nad dan²m elementem. Tuto udßlost obslou₧φ metoda m_move. Ne₧ se k nφ ale dostanu, zaΦnu nejd°φve procedurou, umo₧≥ujφcφ elementu b²t p°etahovßn. V tΘto implementaci je oznaΦenφ °eÜeno konkrΘtnφ konstrukcφ stargDrag, je₧ objektu (parametr what) p°i°adφ reakci na stisk tlaΦφtka v podob∞ volßnφ zmi≥ovanΘ metody m_down:
{
what.onmousedown = function(e) {if(e) {event=e;} m_down(event,what);}
what.drag = 1;
}
function stopDrag(what)
{
what.onmousedown = null;
what.drag = 0;
}
Pouze nad oznaΦen²mi elementy se tedy vyvolß obsluhujφcφ funkce m_down se vstupujφcφm parametrem objektu, kter² prßv∞ obsluhuje (parametr object) a vyvolanΘ udßlosti (parametr event). Mo₧nß se setkßte se zßpisem, p°i°azujφcφ celΘmu dokumentu reakci na ka₧d² stisk. Jen₧e v takovΘmto p°φpad∞ je t°eba slo₧it∞ji zjiÜ¥ovat, kter² objekt vlastn∞ obsluhuje udßlost stisku a zda-li je v∙bec urΦen k p°etahovßnφ. K oznaΦovßnφ se pak obvykle zneu₧φvß atribut class, co₧ se mi osobn∞ nezamlouvß, neb se drag&drop omezuje jen na konkrΘtnφ t°φdu. UrΦit²m v²chodiskem by bylo pou₧itφ atributu name Φi zcela jinΘho smyÜlenΘho atributu. To ale zase odmφtne validßtor.
Jakmile je nad oznaΦen²m objektem kliknuto myÜφ, je to signßl, ₧e by m∞l b²t p°etahovßn, a je zavolßna metoda m_down. Ta ve svΘm t∞le zaznamenß p°edevÜφm aktußlnφ pozici objektu (atributy top a left) a myÜi (atributy clickX a clickY) v dob∞ stisku a dßle pov∞sφ na pohyb myÜi proceduru m_move. Jak²koli pohyb tedy bude obsluhovßn touto metodou.
dragobj.clickY = event.clientY;
dragobj.left = parseInt(dragobj.style.left);
dragobj.top = parseInt(dragobj.style.top);
if(IE)
{
document.attachEvent('onmousemove', m_move);
document.attachEvent('onmouseup', m_up);
}
if(NS || OPERA)
{
document.addEventListener('mousemove', m_move, true);
document.addEventListener('mouseup', m_up, true);
}
Jak jsem p°edeslal, a₧ do chvφle, kdy sejmeme prst z tlaΦφtka, se p°i ka₧dΘm pohybu volß m_move. Ta je ve svΘ podstat∞ jen jak²si prost°ednφk, neb nerealizuje samotn² p°esun, ale pouze poΦφtß rozdφl mezi pozici myÜi v okam₧iku poΦßtku p°esunu a v jeho pr∙b∞hu. Dan² rozdφl se pak p°edß p°φmo metod∞ danΘho objektu, nesoucφ povinn² nßzev ondragdrop, kterß pak podle pot°eby provede samotnou zm∞nu pozice p°iΦtenφm vypoΦφtanΘho rozdφlu k p∙vodnφ pozici objektu. Zase se jist∞ setkßte s tφm, ₧e se p°esun zajiÜ¥uje ji₧ na ·rovni m_move. Ostatn∞ vÜe pot°ebnΘ je k dispozici. Pokud ale budete pot°ebovat s p°esunem dßle pracovat a ka₧dΘmu objektu jej budete chtφt m∞nit, nap°φklad omezovat na urΦitΘ osy nebo rozmezφ, p∙jde to jen st∞₧φ.
{
// Spocti rozdil mezi puvodni pozici mysi a nynejsi pozici
dragobj.ondragdrop(event.clientX-dragobj.clickX,event.clientY-dragobj.clickY);
return stopEvent(event);
}
Uvoln∞nφ tlaΦφtka logicky znamenß, ₧e mß u₧ivatel p°etahovßnφ dost a je t°eba ukonΦit p°esun a hlavn∞ odstranit ovladaΦe udßlosti pohybu myÜi. Pro mo₧nou rozÜi°itelnost je op∞t volßna metoda ondragend, abychom mohli jeÜt∞ po skonΦenφ provΘst n∞jakou volitelnou akci.
{
if(IE)
{
document.detachEvent('onmousemove', m_move);
document.detachEvent('onmouseup', m_up);
if(dragobj.ondragend)dragobj.ondragend(event);
}
if(NS || OPERA)
{
document.removeEventListener('mousemove', m_move, true);
document.removeEventListener('mouseup', m_up, true);
if(dragobj.ondragend)dragobj.ondragend(event);
}
To byl samotn² systΘm knihovny dragdrop.js. Implementace je velmi jednoduchß a modifikovatelnß dle pot°eb. Nezapome≥te vlo₧it knihovny sniffer.js a dragdrop.js. V druhΘ fßzi pak ka₧dΘmu objektu definujte "p°esouvacφ" metodu ondragdrop. Nakonec p°esun aktivovujte volßnφm startDrag s parametrem souvisejφcφho objektu, nap°φklad takto:
{
this.style.left = (this.left + posunx)+"px";
this.style.top = (this.top + posuny)+"px";
}
startDrag(document.getElementById('box1'));
Na zßv∞r bych v krßtkosti uvedl dva mφrn∞ pokroΦilejÜφ p°φklady. Ten p∙vodnφ se ji₧ objevil na Intervalu a jeho ekvivalent, vytvo°en² pomocφ tΘto knihovny, najdete v p°φloze. Zmi≥uji jej proto, abych nßzorn∞ ukßzal, jak jednoduÜe lze drag&drop pro jednotlivΘ objekty specifikovat. V tomto p°φpad∞ je pot°eba omezit jednu osu a rozsah, respektive provΘst diskretizaci.
{
temp = (this.left + posunx);
// Presun pouze o kazdych 18 pixelu
temp -= temp%18;
// Omezeni rozsahu
if(temp<0) temp=0;
if(temp>34) temp=34;
this.style.left = temp+"px";
}
Druh² p°φklad vychßzφ ze stßle populßrn∞jÜφho nastavovßnφ vlastnφho barevnΘho schΘmatu webu a ukazuje, jak by bylo mo₧nΘ umo₧nit u₧ivateli interaktivn∞ definovat vlastnφ barevnΘ kombinace. VÜechny soubory pou₧itΘ v tomto Φlßnku naleznete p°ipravenΘ ke sta₧enφ v souboru dhtml6.zip