$ drag bookmarklet with click add

Add class .drag and .draghandle to anything to be able to drag the element around as a seperate window. Also has ctrl+alt+shift+click support to add draghandle and drag classes to any element on the fly.

by Laurens Maneschijn

HTML

<div class="drag">
	a demo element which already has drag and draghandle classes.
	<div class="draghandle">
		&#10019; draghandle, dragging only starts here
	</div>
	<div>
		some other content<br>
		click dragging here selects text as usual but does not drag container around.
	</div>
</div>

<div>
	A demo element to add draghandle and drag class to using ctrl-alt-shift-click.<br>
	<ul>
		<li>First ctrl-alt-click on a sensible draghandle target</li>
		<li>use mousewheel or up/down key to travel up/down the parents tree</li>
		<li>click to select current highlighted element as draghandle</li>
		<li>use mousewheel or up/down key to travel up/down the parents tree</li>
		<li>click to select current highlighted element as drag container</li>
		<li>ESC to abort</li>
	</ul>
	This main div would make a sensible drag container target.<br>
	<span>span a - A sensible draghandle target, a seperate child of the container not containing the rest.</span>
	<div>
		<span>span b</span>
		<div>
			<span>span c</span>
		</div>
	</div>
</div>

To reset to original position:
<ul>
	<li>ctrl+alt click draghandle, or</li>
	<li>ESC while dragging</li>
</ul>

<hr>

<div>
	Drag to bookmarks: <a href="javascript:(function($){ if(!$ || !$.fn.on){return alert('missing $ or $.fn.on');} var log = (console && typeof console.log === 'function') ? console.log : function(){}; var drag = { dragging:false, dragtarget:null, dragstart_target_offset:null, dragstart_mouse_x:null, dragstart_mouse_y:null, create_selecting_parent:false, create_selecting_handle:false, create_selecting_elements:[], create_selecting_elements_i:null, z:0 }; function init(){ css(); $(document).off('.ev_drag'); $(document).on('dragstart.ev_drag mousedown.ev_drag ','.draghandle', DragStart ); $(document).on('dragend.ev_drag mouseup.ev_drag',DragStop); $(document).on('mousemove.ev_drag', DragMove); $(document).on('click.ev_drag', handleClick); $(document).on('mousewheel.ev_drag', handleMouseWheel); $(document).on('keyup.ev_drag',...

CSS

div {
	border: 1px solid #888;
	margin: 2px;
	padding: 2px;
}
span {
	display: inline-block;
	border: 1px solid #ccc;
	margin: 2px;
	padding: 2px;
}

.drag {
	border: 1px solid #00f;
}
.draghandle {
	outline: 1px solid #0f0;
}
.dragged {
	background: rgba(255,255,255,0.8);
	resize: both;
	overflow: auto;
}

JavaScript

javascript:
(function($){
	if(!$ || !$.fn.on){return alert('missing $ or $.fn.on');}
	// drag any element (max one at a time)
	// .drag .draghandle
	// tip: to drag anything; inspect any element, then open console and do $($0).addClass('drag draghandle');
	// TODO currently only supports position:fixed dragging; also allow position:relative and position:absolute dragging?
	// TODO: prevent text selection when dragging. especially if the draghandle has text in it.
	// TODO: prevent odd things happening when dragging from draghandle that is/has a link in it (holding ALT helps with this).
	// TODO: add background to .drag to prevent transparant box moving around?
	// TODO: add z-index to .drag to prevent it going behind other things?

	var log = (console && typeof console.log === 'function') ? console.log : function(){};
	var drag = {
		dragging:false,
		dragtarget:null,
//		dragstart_target_position:null,
		dragstart_target_offset:null,
//		dragstart_target_topleft:null,
		dragstart_mouse_x:null,
		dragstart_mouse_y:null,
		create_selecting_parent:false,
		create_selecting_handle:false,
		create_selecting_elements:[],
		create_selecting_elements_i:null,
		z:0
	};
//	window.drag = drag;

	function init(){
		css();
		$(document).off('.ev_drag');
		$(document).on('dragstart.ev_drag mousedown.ev_drag ','.draghandle', DragStart );
		$(document).on('dragend.ev_drag mouseup.ev_drag',DragStop);
		$(document).on('mousemove.ev_drag', DragMove);
		$(document).on('click.ev_drag', handleClick);
		$(document).on('mousewheel.ev_drag', handleMouseWheel);
		$(document).on('keyup.ev_drag', handleKeyUp);
	}
	function css(){
		$('style#style_drag').remove();
		var $s = $('<style>', {id:'style_drag'});
		$s.appendTo( $('head,body').eq(0) );
		$s.append('.drag { z-index: 999; }');
		$s.append('.drag.dragging { outline: 1px dashed #888; background: rgba(128,128,128, 0.5); }');
		$s.append('.draghandle { cursor: move; }');
		// TODO: make this optional? could be in the way of something...