Avalon JS to achieve a copy of Google Plus pictures multiple drag sorting with source download _javascript tips

Source: Internet
Author: User
Tags prev

SOURCE Download: Http://xiazai.jb51.net/201509/yuanma/drag_sort1 (jb51.net). rar

The results show as follows:

Google Plus


Drag + Response Effect:

Requirements

1. On both sides of the layout, that is, the space between the pictures are consistent, but the left and right sides of the picture and the spacing is not necessarily equal to the spacing between the pictures, compatible with Ie7,8,firefox,chrome.
2. Browser size changes, when larger than a certain size, each line automatically increase or reduce the picture, automatically adjust the spacing between the pictures to meet the two sides of the layout, when each picture size fixed (here is 200*200px), and less than a certain size, each line of the number of pictures fixed (here the minimum number of columns is 3), The picture is always stretched or scaled in equal proportions.
3. Browsers can still drag a sort under different sizes.
4. Picture, drag the picture in the agent always maintain equal proportions and horizontally vertically centered.
5. Drag to the appropriate position, the location of the picture occurred a certain offset. If it is on the leftmost or rightmost side, only the first picture of the row or the last picture is offset.
6. Support multiple picture dragging sort.

Realize

Layout and CSS

 <div id= ' wrap ' >
  <ul class= ' justify ' >
   <li>
    <a href= ' javascript:; "class=" No_ Selected "></a>
    <div class= ' photo_mask ' ></div>
    <div>
     <div class=" dummy " ></div>
     <p><i></i></p>
    </div>
   </li>
   <li class= ' justify_fix ' ></li>
  </ul>
 </div>
inline-block+flex-box+ Text-align:justify

This is compatible with the lower version of the browser, so the list Li layout is inline-block. And both sides align the layout

-Low version: inline-block+ ' text-align:justify '

-Hyundai: inline-block+ ' Flex-box '

See the Space-between of the simulated flexbox justify-content of this cock specifically

There is no use of flex-box ' align-content:space-around ' because it is not compatible with the low version browser through ' Text-align:justify '.

' Text-align:justify ' does not allow the leftmost, rightmost text to automatically adjust the spacing between the box edges. Even outside box to add padidng, such as:

li{
 margin:0 1%;
 ...
}
#wrap {
 padding:0 1%;
}

It looks like it's the leftmost, the right and the space between the box boundaries and the spacing between Li, is 2%. In fact, the padding set outside the box is never changed, and the margin between Li is the minimum between them. If the spacing between all Li is 1%, then there is still extra white space on one line, and the Li will divide the blanks evenly, and the spacing between them will be greater than 1%.
Specific implementation

li{
 List-style-type:none;
 Display:inline-block;
 *display:inline;
 zoom:1;
 max-width:200px;
 max-height:200px;
 width:28%;
 border:1px solid red;
 position:relative;
 Overflow:hidden;
 margin:10px 2%;
li[class= ' Justify_fix ']{
 border:none;
Justify {
 Display:flex;
 Align-items:flex-start;
 Flex-flow:row Wrap;
 Justify-content:space-between;
 text-align:justify;
 Text-justify:inter-ideograph;
 *zoom:1; 
 -moz-text-align-last:justify;
 -webkit-text-align-last:justify;
 text-align-last:justify;
}
@media (-webkit-min-device-pixel-ratio:0) {
 . justify:after {
  content: "";
  Display:inline-block;
  width:100%
 }
}

Here we'll add ' max-width ', ' max-height '. You can see the percentages inside the cell, and you need to limit the maximum size to the outside.

Picture Response + Horizontal Vertical Center

See the CSS picture response of this cock + Vertical Horizontal Center

Select picture

Google Plus is holding down CTRL, clicking on the picture, completing multiple selections, and here's clicking on the "box" (Here's ' <a class= ' no_selected ' ></a> ').
After clicking, pass the index of the current picture to the array that holds the selected image index (Selected_index here). If the index does not exist, it is added, if it already exists, it is deleted. "Box" now adjusts the style according to whether the index is present in the array.

<div id= ' wrap ' ms-controller= ' photo_sort ' > <ul class= ' Justify '
  > <li ms-repeat= ' photo_list '
   >
    <a href= "javascript:;" class= "no_selected" ms-class-selected_icon= ' Selected_index.indexof ($index) > -1 ' ms-click= ' Select ($index) ' ></a> ...
   </li>
   <li class= ' justify_fix ' ></li>
  </ul>
 </div>

var photo_sort= Avalon.define ({
 selected_index:[],//) Select the index list for the picture
 ...
 Select:function (i) {
  var selected_index=photo_sort.selected_index;
  if (Selected_index.indexof (i) ==-1)//The index list of the selected picture does not exist, add
   photo_sort.selected_index.ensure (i);
  else
   photo_sort.selected_index.remove (i);
 }
});

MouseDown

This uses a mask layer and binds the MouseDown event above.

<a href= "javascript:;" class= "no_selected" ms-class-selected_icon= ' Selected_index.indexof ($index) >-1 ' ms-click= ' Select ($index) ' ></a> <div class= ' photo_mask ' ms-mousedown= ' Start_drag ($event, $index) ' > </div> var photo_sort=avalon.define ({$id: ' Photo_sort ', photo_list:[],//Picture list selected_index:[],//selected pictures ind Ex list drag_flag:false, sort_array:[],//range list, cell_size:0,//each cell size, where the ratio of width to height is 1 target_index:-1,//the final target position of the index Co
l_num:0,//Number of columns x_index:-1,//the x direction of the current drag position index ...}; Start_drag:function (E,index) {if (Photo_sort.selected_index.size ()) {//have selected picture photo_sort.target_index=index;//
  Avoid the user does not drag the picture, but click on the picture, set the default target is the current click picture Photo_sort.cell_size=this.clientwidth; var xx=e.clientx-photo_sort.cell_size/2,yy=e.clienty-photo_sort.cell_size/2;//click on the picture, set the proxy location to click on the point as the center $ (' Drag_proxy ')
  . Style.top=yy+avalon (Window). scrolltop () + ' px ';
  $ (' Drag_proxy '). style.left=xx+ ' px ';
  $ (' Drag_proxy '). style.width=photo_sort.cell_size+ ' px '; $ (' Drag_proxy '). Style.height=photo_sort.cell_size+ ' px '; drag_proxy.select_num=photo_sort.selected_index.length;//set the number of pictures selected in the agent if (drag_proxy.select_num>0) {var drag_
   Img=photo_sort.photo_list[photo_sort.selected_index[drag_proxy.select_num-1]];
   drag_proxy.src=drag_img.src;//the last sheet in the selected picture as the "cover" photo_sort.drag_flag=true of the proxy object;
  $ (' Drag_proxy '). style.display= ' block '; //cell_gap: spacing between pictures, First_gap: The space between the first picture and the outer div is Var wrap_width=avalon ($ (' wrap ')). Width (), wrap_offset=$ (' Wrap '). offsetleft,first_left=$ (' Wrap_photo0 '). Offsetleft, second_left=$ (' wrap_photo1 '). Offsetleft,first_gap=first_
  Left-wrap_offset,cell_gap=second_left-first_left;
  Photo_sort.col_num=math.round ((wrap_width-2*first_gap+ (cell_gap-photo_sort.cell_size))/cell_gap); for (var i=0;i<photo_sort.col_num;i++)//A row of pictures in the center of each picture in the X-direction value as the dividing point, add to the range list Photo_sort.sort_array.push (first_gap
  +CELL_GAP*I+PHOTO_SORT.CELL_SIZE/2);
  var Target=this.parentnode;
  Avalon.bind (document, ' MouseUp ', function (e) {onMouseUp (target);
  }); if (Isie) target.seTcapture ()//Let IE drag sliding e.stoppropagation ();
 E.preventdefault ();

 }
}

Under the mouse point, the selected picture's mask appears, here is to add '. Photo_maskon '

<div class= ' photo_mask ' ms-class-photo_maskon= ' Drag_flag&&selected_index.indexof ($index) >-1 ' 
Ms-mousedown= ' Start_drag ($event, $index) ' ></div>

MouseMove

 Drag_move:function (e) {if (Photo_sort.drag_flag) {var xx=e.clientx,yy=e.clienty,offset
  =avalon ($ (' wrap ')). offset ();
  var offsetx=xx-offset.left,offsety=yy-offset.top; Photo_sort.sort_array.push (OffsetX)//list of ranges added to the current mouse position photo_sort.sort_array.sort (function (a,b) {//Sort range list return
  parseint (a)-parseint (b);//Convert to numeric type, otherwise the ' 1234 ' < ' 333 '} will appear; Finds the index of the current mouse position from the sorted range list, that is, the index var x_index=photo_sort.sort_array.indexof (OffsetX) in the horizontal direction of the target position, Y_index=math.floor
  (offsety/(PHOTO_SORT.CELL_SIZE+20)), Size=photo_sort.photo_list.size ();
  Photo_sort.x_index=x_index; photo_sort.target_index=photo_sort.col_num*y_index+x_index;//the index if (photo_sort.target_index>size) of the target in all pictures
  The target position crosses the photo_sort.target_index=size; Photo_sort.sort_array.remove (OffsetX);//Remove current position $ (' drag_proxy '). Style.top=avalon (window). scrolltop () +yy-photo_
  sort.cell_size/2+ ' px ';
 $ (' Drag_proxy '). style.left=xx-photo_sort.cell_size/2+ ' px ';
} e.stoppropagation (); }

A few notes
-about the position you are dragging to determine

The vertical bar of each cell in the diagram divides the cell horizontally into two sides. Each vertical line divides one row into 5 parts, and when judged, look at what part of the current ' E.clientx ' in the 5-part of the mouse.

-This is the sort of time to judge. Specifically, the x coordinates of each vertical bar and the x-coordinate of the current mouse position are saved to the array (' Sort_array ' here), sorted, and ' indexOf ' looks at the position of the x-coordinate of the current mouse position in the array to get the target position of the current drag.

If you don't have to sort, the code will look like this

var target;
if (x>50+50) {
 if (x>3*100+3*100+50+50) {//Last part
  target=4
 } else{
  target= (x-50-50)/(50+100+50);
 }
else
 target=0;

-Deletes the x-coordinate of the current mouse position, leaving the position in place for the next MouseMove event's x-coordinate.
-About the current drag target location of the picture occurred a certain offset, nothing more than the target location around the picture plus the corresponding class.

. prev{
 right:40px;
next{
 left:40px;
}
 <div id= ' wrap ' ms-controller= ' photo_sort ' > <ul class= ' Justify ' ms-mousemove= ' drag_move
  ($event) ' >
   <li ms-repeat= ' photo_list ' ms-attr-id= ' wrap_photo{{$index}} ' ms-class-prev= ' $index ==target_index-1 
   ' ms-class-next= ' $index ==target_index ' > ...
   </li>
   <li class= ' justify_fix ' ></li>
  </ul>
 </div>

Notice here that when the agent is dragged to the left or the far right, the first cell of the row on which the target location is located (if any) is also offset because the layout is ' Inline-block '.

The workaround is to set the variable ' X_index ', which represents the index of the cell in the X direction. Increase the criteria when you add an offset class

<li ms-repeat= ' photo_list ' ms-attr-id= ' wrap_photo{{$index}} ' ms-class-prev= ' $index ==target_index-1&&x_ Index>0 ' 
ms-class-next= ' $index ==target_index&&x_index<col_num ' > ...
</li>

MouseUp

function OnMouseUp (target) {if (Photo_sort.drag_flag) {for (Var i=0,len=photo_sort.selected_index.size (); i<len;i+ +) {//traverse selected picture Var item_index=photo_sort.selected_index[i],data=photo_sort.photo_list, Target_index=photo_sort.targ
     Et_index,temp;
      if (Item_index<target_index) {//target location TEMP=DATA[ITEM_INDEX].SRC after the picture is selected;
      for (var j=item_index;j<target_index;j++) data[j].src=data[j+1].src;
     Data[target_index-1].src=temp;
      }else{//the target position before temp=data[item_index].src the selected picture;
      for (var j=item_index;j>target_index;j--) data[j].src=data[j-1].src;
     Data[target_index].src=temp;
    } photo_sort.target_index=-1;//various resets, initialize photo_sort.sort_array=[];
    photo_sort.col_num=0;
    Photo_sort.x_index=-1;
    Photo_sort.selected_index=[];
    $ (' Drag_proxy '). style.display= ' None ';
    Photo_sort.drag_flag=false;
    Avalon.unbind (document, ' MouseUp ');
   if (Isie) target.releasecapture ();
 }
  }

This is mainly the rearrangement of the list of pictures.
-Target location before the picture is selected

First save the original picture in ' temp ', and then move the picture from the target position to the original picture, then shift one position, and finally the ' temp ' to the target position.
-Target location After the picture is selected

Similar to the above, but here is the picture from the target location to the original picture in the next position, and then move forward one position.

Attention

You cannot assign a value like ' data[j]=data[j+1 ' because Avalon does not support a single transformation, and if you want to update, you need to reassign the entire child VM to a new object. That is, define a arr, then add model to it from the beginning, and finally ' photo_sort.photo_list.clear () ' Delete all pictures, ' Photo_sort.photo_list=arr ' to reassign, update the view.

Postscript

In fact, Google Plus has done more in detail.
-Box Select picture
-If there is a scroll bar and the drag position is about to exceed the current interface, the scroll bar will automatically move up or down.
These two are not done, the principle is very simple.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.