1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
| function addEvent(obj,event,fct)
{
if( obj.attachEvent)
obj.attachEvent('on' + event,fct);
else
obj.addEventListener(event,fct,true);
}
//Connaître le vrai style d'un élément
function getCssStyleValue(element /*element html*/, style/*style recherché*/)
{
if( element.currentStyle ) {
return element.currentStyle[style];
}
else {
return window.getComputedStyle(element,null).getPropertyValue(style);
}
}
//Fonction "magique" pour ajouter une règle css:
function insertCss(selector,rule)
{
if( document.styleSheets && document.styleSheets[0] ) {
var feuille = document.styleSheets[0];
if( feuille.insertRule ) //internet explorer
feuille.insertRule(selector + " { " + rule + " } ", feuille.cssRules.length);
else if( feuille.addRule ) //Pour firefox
feuille.addRule(selector,rule);
}
else { //Pour le reste
var ss = document.createElement('style');
ss.setAttribute('type','text/css');
ss.appendChild(document.createTextNode(selector + " { " + rule + " } ") );
document.getElementsByTagName('head')[0].appendChild(ss);
}
}
addEvent(
window,'load', function () {
insertCss('.ordre','display: none;');
insertCss('ul.liste li', 'cursor: move;');
}
);
var dragged = null; //balise li en cours de déplacement
var liste = null; //liste en cours de modification (balise ul)
var dX, dY; //Décalages
var ghost = document.createElement('li');
//Pour le différencier un peu des vraies "div"
ghost.style.backgroundColor = 'transparent';
ghost.style.borderStyle = 'dashed';
function list_onmousedown(event) {
var target = event.target || event.srcElement;
//Si il y a déjà un ul en déplacement, on "simule" un évènement onmouseup
if( dragged ) list_onmouseup(event);
//A la recherche d'une balise ul class="liste"
var element = target;
while(element)
{
if( element.className && element.className.match(/\bliste\b/) )
break;
element = element.parentNode;
}
if( element == null ) //si element = null, alors on n'a rien trouvé, on quite cette fonction
return;
liste = element;
//Reste maintenant à trouver le "li" déplacé
var element = target;
while(element)
{
if( element == liste) //On est remonté jusqu'à la liste elle-même, cela signifie que l'on n'a pas cliqué sur une balise li
return;
else if ( element.tagName && element.tagName.toLowerCase() == 'li' )
break;
element = element.parentNode;
}
dragged = element;
//On annule le comportement par défaut:
event.returnValue = true;
event.preventDefault && event.preventDefault();
dX = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
dY = event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
var element = dragged;
do {
dX -= element.offsetLeft;
dY -= element.offsetTop;
element = element.offsetParent;
} while( element && getCssStyleValue(element, 'position') != 'top');
dragged.style.width = dragged.offsetWidth + 'px';
dragged.style.height = dragged.offsetHeight + 'px';
liste.insertBefore(ghost, dragged); //Insérer le fantôme juste avant l'élément en cours de déplacement
//On simule un premier déplacement
list_onmousemove(event);
}
function list_onmousemove(event) {
if( dragged) {
dragged.style.position = 'absolute';
dragged.style.left = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft - dX + 'px';
dragged.style.top = event.clientY + document.documentElement.scrollTop + document.body.scrollTop - dY + 'px';
//Déplacement du ghost
var avant = null; //La balise que l'on va utiliser pour insertBefore()
//On va parcourir tous les enfants direct de notre liste
for( var i = 0; i < liste.childNodes.length; i++)
{
var el = liste.childNodes.item(i);
//Premièrement il faut s'assurer qu'il s'agit bien d'une balise (tagName) puis d'une balise li
//Ensuite, on exclut de nos tests la balise ghost elle-même ainsi que la balise en cours de déplacement
//Enfin, on vérifie les valeurs de offsetTop
if( el.tagName && el.tagName.toLowerCase() == 'li' && el != dragged && el != ghost && el.offsetTop + dY - el.offsetHeight/2 > dragged.offsetTop )
{
avant = el;
break; //On arrête la boucle
}
}
if( avant != ghost.nextSibling ) //Si ghost est avant "avant", alors "avant" est après ghost :p
{
liste.removeChild(ghost);
if( avant == null )
liste.appendChild(ghost);
else
liste.insertBefore(ghost, avant);
}
}
}
function list_onmouseup(event)
{
if( dragged) {
dragged.style.position = dragged.style.width = dragged.style.height = '';
liste.replaceChild(dragged, ghost);
dragged = null;
var inputs = liste.getElementsByTagName('input');
var n = 1; //Compteur
for(var i = 0; i < inputs.length; i++) {
if( inputs.item(i).className.match(/\bordre\b/) ) {
inputs.item(i).value = n++;
}
}
}
}
addEvent(document,'mousedown',list_onmousedown);
addEvent(document,'mousemove',list_onmousemove);
addEvent(document,'mouseup',list_onmouseup); |
Partager