


The following is a very detailed explanation of how to drag and adjust the order of imitation Weibo pictures. There are definitely deficiencies in the article. Welcome to criticize and correct. Not much nonsense, let’s look at the specific content.
Click here to enterSource code download
What is drag-and-drop image sorting?
Just like Weibo, users are allowed to adjust the order of several pictures by dragging them after uploading.
You can see that Weibo has fixed the size of each picture here. If you are a little stricter, you need to be like the previous article, with several responsive div containers of equal height and width outside. , which contains proportionally scaled responsive images.
The following are the requirements.
1. Of course, the image must be draggable first.
2. Move the image out of its original position, drag it to the target position, and before completing the dragging without releasing the mouse, you need to set a placeholder at the target position to allow the user to preview the effect after the drag is completed.
3. Responsive. After the size is changed, the above requirements can still be completed.
4. Compatible with as many browsers as possible. In fact, I wrote the previous article to pave the way for this one, so this one is also compatible with IE7.
Final effect
chrome
ie8
ie7
First is dragging.
The proxy used here means that there is an extra div in the original layout, and the actual dragged object is this div. Specifically,
<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 src="/static/imghwm/default1.png" data-src="el.src" class="lazy" ms-attr- alt="avalon js implements imitating Weibo drag image sorting_javascript skills" ><i></i></p> </div> </li> </ul> <div id='drag_proxy'></div> </div>
Bind mousedown to each cell. When start_drag is triggered, put the img in the cell into the proxy
. At the same time, get the size of the image and write it down. The current mouse click position, and the click position is used as the center point of the proxy div rectangle (picture), the proxy is displayed, and the clicked picture is hidden.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(); }
Note a few points:
1.drag_sort.cell_size records the size of the current cell. The aspect ratio here is 1:1. Because the layout is responsive, it needs to be recorded. You can see how to use this later.
2. The target of the event needs to determine whether it is triggered by the img tag, because the click position may be the blank area between the cell and the picture.
3.ori_src is used to save the picture of the current cell, because the cell at the original position of the picture will be deleted when mousemove later.
4.drag_sort.target_index records the index of the current cell, and will later compare this index with the index of the cell to which the agent moves.
5.drag_flag indicates whether mousemove is allowed.
6. For ie, target.setCapture(); must be used, otherwise
You can see that the browser's default behavior will be executed when dragging.
7.event.preventDefault(); must also be added, otherwise the browser's default behavior will occur. For example, when Firefox drags an image, it will open a new tab and display the image.
Then comes mousemove, which is bound to the ul tag. Events like mousemove and mouseup are usually bound to several common parent elements that need to be triggered, thus reducing the number of objects to which the event is bound.
Specific
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(); }
A few notes
1.drag_flag ensures that mousedown must be triggered before mousemove can be triggered.
2.drag_sort.container is the root element of the entire layout, here is
.#wrap{ position: relative; max-width: 620px; font-size: 0; } #drag_proxy{ position: absolute; border:1px solid #009be3; z-index: 100; display: none; }
When calculating later, you need to subtract the left and top of the root element.
3. The vertical scroll bar of the avalon(window).scrollTop() browser should also be considered when calculating.
4. The size of each cell is always the same, so the position where the cursor moves directly is divided by the number of rows and columns, and rounded to get the index of the target cell.
5.move_to!=drag_sort.target_index The cell that the current cursor is moved to is not the cell where the picture originally resides. Delete the cell at the original location of the picture and insert a placeholder cell in the target cell. At this time, the dragged The image has not been placed in the target cell yet, and the index of the initial cell is finally updated.
Finally, 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' alt="avalon js implements imitating Weibo drag image sorting_javascript skills" ></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仿微博拖动图片排序的功能,本文写的不好还请见谅。

JavaScript core data types are consistent in browsers and Node.js, but are handled differently from the extra types. 1) The global object is window in the browser and global in Node.js. 2) Node.js' unique Buffer object, used to process binary data. 3) There are also differences in performance and time processing, and the code needs to be adjusted according to the environment.

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

Notepad++7.3.1
Easy-to-use and free code editor

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function
