jQuery UI Draggable:自定义管理单元方法

时间:2016-05-10 13:28:18

标签: javascript jquery jquery-ui drag-and-drop drag

我知道jQuery UI API内置了snapsnapMethodsnapTolerance,但在这种情况下这些不起作用。

这是我面临的问题:在容器内拖动时,我希望拖动器在一定距离内捕捉到容器的边缘。计算距离并触发这不是问题。这让我无法开始工作。

我期望类似:$draggable.position().left = 0;可能会将其捕捉到父容器的左边缘,但它没有任何区别。

这是一个小提示:https://jsfiddle.net/jwxrevL2/1/

JS:

//set draggable
$('.drag').draggable({
  drag: function(){ drag($(this)) },
  containment: 'parent',
});

//drag
function drag( $draggable ){
  var snap_tolerance = 10;

  //Draggable 
  var d_top     = $draggable.position().top;
  var d_middle  = ($draggable.position().top+($draggable.height()/2));
  var d_bottom  = ($draggable.position().top+$draggable.height());

  var d_left   = $draggable.position().left;
  var d_center = ($draggable.position().left+($draggable.width()/2));
  var d_right  = ($draggable.position().left+$draggable.width());

  //Wrapper 
  var $wrapper = $('.wrapper');
  var w_top     = 0;  
  var w_bottom  = $wrapper.height();

  var w_left   = 0 
  var w_right  = $wrapper.width();   

  //snap to left
  if( d_left <= (w_left+snap_tolerance )){
    console.log('snap left');
    $draggable.position().left = w_left; 
    within_snap = true;
  }

  //snap to right
  if( d_right >= (w_right-snap_tolerance)){
    console.log('snap right');
    $draggable.position().left = (w_right-$draggable.width());
    within_snap = true;
  }

  //snap to top
  if( d_top <= (w_top+snap_tolerance )){
    console.log('snap top');
    $draggable.position().top = w_top;
    within_snap = true;
  }

  //snap to bottom
  if( d_bottom >= (w_bottom-snap_tolerance )){
    console.log('snap bottom');
    $draggable.position().top = (w_bottom-$draggable.height());
    within_snap = true;
  }     

}//end fn drag

2 个答案:

答案 0 :(得分:1)

我已经设法让它运转起来。虽然我必须说我不完全明白发生了什么。这些是我所做的更改(updated fiddle):

//set draggable
$('.drag').draggable({
  drag: function(e, ui){ drag($(this), ui) },
  containment: 'parent',
});

所以在拖动事件中,我将ui对象以及jQuery对象(我认为,如果我对ui对象有误,请纠正我)进入drag函数。

//snap to left
if( d_left <= (w_left+snap_tolerance )){
  console.log('snap left');
  ui.position.left = w_left; 
  within_snap = true;
}

然后,通过更新ui对象position.left属性,我可以将其捕捉到位。

任何人都可以解释为什么使用ui而不是jQuery对象会有所不同吗?

答案 1 :(得分:0)

以下是一个例子。

你需要像这样指定一个网格:

import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import ru.pinspb.pinsupport.R;
import ru.pinspb.pinsupport.common.Constants;
import ru.pinspb.pinsupport.pojo.Message;
import ru.pinspb.pinsupport.pojo.SessionInterface;
import ru.pinspb.pinsupport.utils.Helpers;

public class SessionAdapter extends RecyclerView.Adapter<SessionAdapter.Holder> {

    public interface OnItemClickListener {
        void onItemClick(SessionInterface item);
    }

    private static final String TAG = SessionAdapter.class.toString();
    private final OnItemClickListener listener;
    List<SessionInterface> sessions = new ArrayList<>();
    Context context;
    private Message mLastMessage;
    private Handler mHandler = new Handler();

    public SessionAdapter(List<SessionInterface> sessions, Context context, OnItemClickListener listener) {
        this.sessions = sessions;
        this.context = context;
        this.listener = listener;
    }

    public void updateSessions(List<SessionInterface> sessionInterface) {
        this.sessions = sessionInterface;
    }

    public int getCount() {
        return sessions.size();
    }

    public SessionInterface getItem(int position) {
        return sessions.get(position);
    }

    @Override
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_sessions, null);
        return new Holder(v);
    }

    @Override
    public void onBindViewHolder(final Holder holder, int position) {

        final SessionInterface session = sessions.get(position);
        mLastMessage = session.getMessages().get(session.getMessages().size() - 1);

        holder.bind(session, listener);

        holder.label.setText("Чат #" + session.getId());
        holder.sessionTitle.setText(Helpers.stringLimit(session.getQueue().getName(), 30));


        try {
            SimpleDateFormat ru = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", new Locale("ru"));
            ru.setTimeZone(TimeZone.getTimeZone("GMT+03:00"));
            Date jud = ru.parse(mLastMessage.getDate());
            String targetFormat = new SimpleDateFormat("d MMMM, HH:mm", new Locale("ru")).format(jud);
            final long milliseconds = jud.getTime();
            holder.date.setText(targetFormat);

            if(session.getClosedTimeAgo() == null) {
                startUpdateTimer(new Runnable() {
                    @Override
                    public void run() {
                        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Moscow"));
                        Date currentDate = calendar.getTime();
                        holder.updateTimeRemaining(currentDate.getTime(), milliseconds);
                    }
                });
//                Log.d(TAG, "Sid: " + session.getId() + " ;\nnow: " + System.currentTimeMillis() + ";\n last date: " + mLastMessage.getDate() + "; \nmill: " + milliseconds );
                holder.timeRemaining.setVisibility(View.VISIBLE);
            } else {
                holder.timeRemaining.setVisibility(View.GONE);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        holder.message.setText(Helpers.stringLimit(Helpers.stripLineBreaks(mLastMessage.getText(), " "), 50));

        if(session.getIs_closed() == 1) {
            holder.setClosed();
        } else {
            if(mLastMessage.getSender_type().equals(Constants.CLIENT_TYPE)) {
                holder.setClientWaiting();
            } else {
                holder.setOperatorWaiting();
            }
        }
    }

    @Override
    public long getItemId(int position) {
        SessionInterface session = sessions.get(position);
        return session.getId();
    }

    @Override
    public int getItemCount() {
        return sessions.size();
    }

    public long getPositionById(long id) {
        for (int i = 1; i < sessions.size(); i++) {
            long sessionId = getItemId(i);
            boolean eq = id == sessionId;
            if(eq) {
                return i;
            }
        }
        return 0;
    }

    private void startUpdateTimer(final Runnable runnable) {
        Timer tmr = new Timer();
        tmr.schedule(new TimerTask() {
            @Override
            public void run() {
                mHandler.post(runnable);
            }
        }, 1000, 1000);
    }

    public static class Holder extends RecyclerView.ViewHolder {
        TextView label;
        TextView sessionTitle;
        TextView date;
        TextView message;
        TextView status;
        ImageView chatStatusImage;
        TextView timeRemaining;

        public Holder(View itemView) {
            super(itemView);
            this.label = (TextView) itemView.findViewById(R.id.label);
            this.sessionTitle = (TextView) itemView.findViewById(R.id.ticket_title);
            this.date = (TextView) itemView.findViewById(R.id.date);
            this.message = (TextView) itemView.findViewById(R.id.comment);
            this.status = (TextView) itemView.findViewById(R.id.status);
            this.chatStatusImage = (ImageView) itemView.findViewById(R.id.ticket_status);
            this.timeRemaining = (TextView) itemView.findViewById(R.id.time_remaining);
        }

        public void updateTimeRemaining(long currentTime, long timeAgo) {
//            Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(currentTime - timeAgo) = " + (currentTime - timeAgo));
//            Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(timeAgo - currentTime) = " + (timeAgo - currentTime));
            long timeDiff = currentTime - timeAgo;
            long seconds = TimeUnit.MILLISECONDS.toSeconds(timeDiff) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeDiff));
            String time = String.format("%d:%s",
                    TimeUnit.MILLISECONDS.toMinutes(timeDiff),
                    seconds < 10 ? seconds + "0" : String.valueOf(seconds)
            );
            timeRemaining.setText(time);
        }

        public void setClosed() {
            this.status.setText("closed");
            this.status.setTextColor(itemView.getResources().getColor(R.color.closedText));
            this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_closed));
        }

        public void setOperatorWaiting() {
            this.status.setText("some text");
            this.status.setTextColor(itemView.getResources().getColor(R.color.clientColor));
            this.timeRemaining.setTextColor(itemView.getResources().getColor(R.color.clientColor));
            this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_client));
        }

        public void setClientWaiting() {
            this.status.setText("some text");
            this.status.setTextColor(itemView.getResources().getColor(R.color.operatorColor));
            this.timeRemaining.setTextColor(itemView.getResources().getColor(R.color.operatorColor));
            this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_operator));
        }

        public void bind(final SessionInterface item, final OnItemClickListener listener) {
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    listener.onItemClick(item);
                }
            });
        }
    }

}

https://jsfiddle.net/m3r2xra3/