Im Folgenden finden Sie eine sehr detaillierte Erklärung zum Verschieben und Anpassen der Reihenfolge nachgeahmter Weibo-Bilder. Es gibt definitiv Mängel im Artikel. Nicht viel Unsinn, schauen wir uns den konkreten Inhalt an.
Klicken Sie hier, um einzusteigenQuellcode-Download
Was ist Drag-and-Drop-Bildsortierung?
Genau wie bei Weibo können Benutzer die Reihenfolge mehrerer Bilder anpassen, indem sie sie nach dem Hochladen ziehen.
Sie können sehen, dass Weibo die Größe jedes Bildes hier festgelegt hat. Wenn Sie etwas strenger sind, müssen Sie wie im vorherigen Artikel vorgehen, mit mehreren responsiven Div-Containern gleicher Höhe und Breite außen . , das proportional skalierte responsive Bilder enthält.
Im Folgenden sind die Anforderungen aufgeführt.
1. Natürlich muss das Bild zuerst ziehbar sein.
2. Verschieben Sie das Bild aus seiner ursprünglichen Position, ziehen Sie es an die Zielposition und bevor Sie das Ziehen abschließen, ohne die Maus loszulassen, müssen Sie einen Platzhalter an der Zielposition festlegen, damit der Benutzer anschließend eine Vorschau des Effekts sehen kann Das Ziehen ist abgeschlossen.
3. Reaktionsfreudig. Nachdem die Größe geändert wurde, können die oben genannten Anforderungen weiterhin erfüllt werden.
4. Kompatibel mit möglichst vielen Browsern. Tatsächlich habe ich den vorherigen Artikel geschrieben, um den Weg für diesen Artikel zu ebnen, sodass dieser auch mit IE7 kompatibel ist.
Endeffekt
Chrom
ie8
ie7
Das erste ist das Ziehen.
Der hier verwendete Proxy bedeutet, dass es im ursprünglichen Layout ein zusätzliches Div gibt und das tatsächlich gezogene Objekt dieses Div ist
<div id='wrap' ms-controller='drag_sort' class='ms-controller'> <ul ms-mousemove='drag_move($event)'> <li ms-repeat='photo_list'> <div ms-mousedown='start_drag($event,$index,el)'> <div class="dummy"></div> <p ms-attr-id='wrap_img{{$index}}'><img ms-attr-src="el.src"><i></i></p> </div> </li> </ul> <div id='drag_proxy'></div> </div>
start_drag:function(e,i,el){ var img=$('wrap_img'+i).firstChild,target_img_width=img.clientWidth,target_img_height=img.clientHeight; drag_sort.cell_size=$('wrap_img0').clientWidth; var xx=e.clientX-target_img_width/2,yy=e.clientY-target_img_height/2,offset=avalon($(drag_sort.container)).offset(),target=e.target.parentNode.parentNode.parentNode; $('drag_proxy').style.top=yy+avalon(window).scrollTop()-offset.top+'px'; $('drag_proxy').style.left=xx-offset.left+'px'; $('drag_proxy').style.width=target_img_width+'px'; $('drag_proxy').style.height=target_img_height+'px'; if(target&&target.nodeName=='LI'){ ori_src=el; // $('drag_proxy').innerHTML=target.querySelector('p').innerHTML; $('drag_proxy').innerHTML=$('wrap_img'+i).innerHTML; $('drag_proxy').style.display='block'; drag_sort.target_index=i; drag_flag=true; } if(isIE) target.setCapture(); avalon.bind(document,'mouseup',function(){ up(target); }); e.stopPropagation(); e.preventDefault(); }
Beachten Sie ein paar Punkte:
1.drag_sort.cell_size zeichnet die Größe der aktuellen Zelle auf. Das Seitenverhältnis beträgt hier 1:1. Da das Layout responsiv ist, muss es aufgezeichnet werden. Sie können später sehen, wie Sie dies verwenden.2. Das Ziel des Ereignisses muss bestimmen, ob es durch das img-Tag ausgelöst wird, da die Klickposition der leere Bereich zwischen der Zelle und dem Bild sein kann.
3.ori_src wird zum Speichern des Bildes der aktuellen Zelle verwendet, da die Zelle an der ursprünglichen Position des Bildes bei späterer Mausbewegung gelöscht wird.
4.drag_sort.target_index zeichnet den Index der aktuellen Zelle auf und vergleicht diesen Index später mit dem Index der Zelle, zu der der Agent wechselt.
5.drag_flag gibt an, ob Mausbewegungen erlaubt sind.
6. Zum Beispiel muss target.setCapture(); verwendet werden, andernfalls
Sie können sehen, dass beim Ziehen das Standardverhalten des Browsers ausgeführt wird.
7.event.preventDefault(); muss ebenfalls hinzugefügt werden, sonst tritt das Standardverhalten des Browsers auf. Wenn Firefox beispielsweise ein Bild zieht, wird ein neuer Tab geöffnet und das Bild angezeigt.
Dann kommt die Mausbewegung, die an das ul-Tag gebunden ist. Ereignisse wie „mousemove“ und „mouseup“ sind normalerweise an mehrere gemeinsame übergeordnete Elemente gebunden, die ausgelöst werden müssen, wodurch die Anzahl der Objekte reduziert wird, an die das Ereignis gebunden ist.
Spezifisch
drag_move:function(e){ if(drag_flag){ var xx=e.clientX,yy=e.clientY,offset=avalon($(drag_sort.container)).offset(); var x=xx-offset.left,y=avalon(window).scrollTop()+yy-offset.top; var x_index=Math.floor(x/drag_sort.cell_size),y_index=Math.floor(y/drag_sort.cell_size),move_to=3*y_index+x_index; $('drag_proxy').style.top=y-drag_sort.cell_size/2+'px'; $('drag_proxy').style.left=x-drag_sort.cell_size/2+'px'; if(move_to!=drag_sort.target_index){ drag_sort.photo_list.removeAt(drag_sort.target_index); drag_sort.photo_list.splice(move_to,0,{src:'1.jpg'}); drag_sort.target_index=move_to; } } e.stopPropagation(); }
Ein paar Anmerkungen
1.drag_flag stellt sicher, dass Mousedown ausgelöst werden muss, bevor Mousemove ausgelöst werden kann.2.drag_sort.container ist das Stammelement des gesamten Layouts, hier ist .
#wrap{ position: relative; max-width: 620px; font-size: 0; } #drag_proxy{ position: absolute; border:1px solid #009be3; z-index: 100; display: none; }
3. Bei der Berechnung sollte auch die vertikale Bildlaufleiste des Browsers avalon(window).scrollTop() berücksichtigt werden.
4. Die Größe jeder Zelle ist immer gleich, daher wird die Position, an der sich der Cursor direkt bewegt, durch die Anzahl der Zeilen und Spalten geteilt und gerundet, um den Index der Zielzelle zu erhalten.
5.move_to!=drag_sort.target_index Die Zelle, in die der aktuelle Cursor verschoben wird, ist nicht die Zelle, in der sich das Bild ursprünglich befindet. Löschen Sie die Zelle an der ursprünglichen Position des Bildes und fügen Sie eine Platzhalterzelle in die Zielzelle ein. Zu diesem Zeitpunkt wurde das Bild noch nicht in die Zielzelle eingefügt und der Index der ursprünglichen Zelle wurde schließlich aktualisiert
Endlich Mouseup
function up(target){ if(isIE) target.releaseCapture(); var target_index=drag_sort.target_index; if(ori_src&&target_index!=-1){ drag_sort.photo_list.splice(target_index,1); drag_sort.photo_list.splice(target_index,0,ori_src); } drag_holder=null; drag_flag=false; drag_sort.target_index=-1; $('drag_proxy').style.display='none'; avalon.unbind(document,'mouseup'); }
判断ori_src&&target_index!=-1目的在于排除在非绑定对象上mouseup这种无效操作。因为是在document上绑定mouseup,就要排除类似于随便在空白处点击这种情况。这时不能对单元格删除,插入。
然后是把各变量设为初始值。
图片效果:
HTML代码:
<div id='post_img' ms-controller='post_img'> <ul id='post_img_inner' ms-mousemove='onmousemove'> <li ms-repeat-el="post_img_list" class='inline-block' ms-mousedown='onmousedown($event,$index,el)' ms-attr-id='post_img_item{{$index}}'> <img ms-src='el' class='uploaded_img'></li> </ul> </div>
JS代码:
var drag_holder=null,index=-1,ori_src=null,drag_flag=false;//拖动的代理,原图片,原图片的src var post_img = avalon.define('post_img', function(vm) { vm.post_img_list=[];//保存所有图片的src vm.onmousedown=function(e,i,el){ $('drag_proxy').style.display='block'; var target=e.target.parentNode; var xx = e.clientX; var yy = e.clientY; $('drag_proxy').style.top=yy+'px'; $('drag_proxy').style.left=xx+'px'; if(target&&target.nodeName=='LI'){ ori_src=el; index=target.getAttribute('id').substring(13); $('drag_proxy').innerHTML=target.innerHTML; post_img.post_img_list.splice(i, 1, 'about:blank'); } drag_flag=true; }; vm.onmousemove=function(e){ if(drag_flag){//如果点下了图片 var xx = e.clientX; var yy = e.clientY; $('drag_proxy').style.top=yy+'px'; $('drag_proxy').style.left=xx+'px'; var x=xx-avalon($('post_img')).offset().left; var y=yy-avalon($('post_img')).offset().top; //例子没有考虑滚动条的情况 var x_index=Math.floor(x/100);//图片尺寸100*100 var y_index=Math.floor(y/100); post_img.post_img_list.splice(index, 1);//删除当前图片的li var target_index=3*y_index+x_index;//目标图片的位置(3*3) if(post_img.post_img_list.indexOf('about:blank')!=target_index) //如果图片数组中没有src=about:blank这个占位置的li post_img.post_img_list.splice(target_index, 0, 'about:blank'); //添加src=about:blank index=target_index; //会触发很多次move,所以触发一次就改动一次 } }; }); document.onmouseup=function(e){ drag_holder=null; if(ori_src){ post_img.post_img_list.splice(index, 1); //删除src=about:blank post_img.post_img_list.splice(index, 0,ori_src); //添加原图片 } $('drag_proxy').style.display='none'; $('drag_proxy').innerHTML=''; drag_flag=false; };
以上代码实现了avalon js仿微博拖动图片排序的功能,本文写的不好还请见谅。