$ SelectElement
module to easily select any element on a page.
by Laurens Maneschijn
HTML
<div>
oneliner for testing as bookmarklet on any website:<br>
(as long as jQuery >= 1.7 is loaded there)<br>
<textarea>javascript:(function(f,e,c){function r(){h&&f.console&&f.console.log&&f.console.log.apply(f.console,[].slice.call(arguments))}function g(a){var d={type:a,elements:b.elements,start_element:b.elements[0],selected_element:b.elements[b.element_i]};r("SelectElement trigger event: "+a,d);c(e).trigger("selectelement"+a,d);c(e).trigger("selectelement",d)}function k(a){a=Math.max(-1,a);a=Math.min(1,a);a=Math.round(a);var c=b.element_i;b.element_i+=a;b.element_i=Math.max(b.element_i,0);b.element_i=Math.min(b.element_i, b.elements.length-1);c!=b.element_i&&g("change");l()}function n(){c("style#style_selectelement").remove();var a=c("<style>",{id:"style_selectelement"});a.appendTo(c("head,body").eq(0));a.append(".selectelement_target { outline: 2px dashed rgba(255,0,255,1 )!important; background: rgba(255,0,255, 0.5); }");a.append(".selectelement_targetparent { outline: 1px dashed rgba(255,0,200,0.5)!important; background: rgba(255,0,200, 0.1); }");a.append(".selectelement_targetchild { outline: 1px dashed rgba(200,0,255,0.5)!important; background: rgba(200,0,255, 0.1); }"); c(e.body).off(".selectelementinternal");c(e.body).on("click.selectelementinternal",t);c(e.body).on("keyup.selectelementinternal",u);c(e.body).on("mousewheel.selectelementinternal",v)}function t(a){b.selector_active?(a.preventDefault(),a.stopImmediatePropagation(),g("selected"),m()):h&&a.ctrlKey&&a.altKey&&(a.preventDefault(),a.stopImmediatePropagation(),p(a.target))}function u(a){b.selector_active&&(27==a.which?(a.preventDefault(),a.stopImmediatePropagation(),q()):13==a.which?(a.preventDefault(), a.stopImmediatePropagation(),g("selected"),m()):38==a.which?(a.preventDefault(),a.stopImmediatePropagation(),k(1)):40==a.which&&(a.preventDefault(),a.stopImmediatePropagation(),k(-1)))}function v(a){if(b.selector_active){a.preventDefault();a.stopImmediatePropagation();var...
CSS
.demo, .demo div {
display: inline-block;
margin: 4px;
padding: 4px;
border: 1px dotted #888;
}
.demo table tbody tr td { border: 1px dotted #888; }
JavaScript
(function(window, document, $){
if(!$ || !$.fn.on){return alert('missing $ or $.fn.on');}
// triggers events on document:
// 'selectelementstart.selectelement'
// 'selectelementchange.selectelement'
// 'selectelementcancel.selectelement'
// 'selectelementselected.selectelement'
// private static data:
var eventnameprepend = 'selectelement';
var debug = false;
var data = {
selector_active: false,
elements: [],
element_i: null,
};
function log(){
if(debug && window.console && window.console.log){
window.console.log.apply(window.console, [].slice.call(arguments));
}
}
function trigger(name, data){
// TODO: trigger on document? or document.body? or ... ?
$(document).trigger(eventnameprepend + name, data);
$(document).trigger(eventnameprepend, data);
}
function triggerType(eventtype){
// NB: call BEFORE calling reset() so data is still there.
var eventdata = {
type: eventtype,
elements: data.elements,
start_element: data.elements[0],
selected_element: data.elements[data.element_i]
}
log('SelectElement trigger event: ' + eventtype, eventdata);
trigger(eventtype, eventdata);
}
function triggerStart(){
triggerType('start');
}
function triggerCancel(){
triggerType('cancel');
}
function triggerChange(){
triggerType('change');
}
function triggerSelected(){
triggerType('selected');
}
function selectN(n){
var prev = data.element_i;
data.element_i = n;
data.element_i = Math.max(data.element_i, 0);
data.element_i = Math.min(data.element_i, data.elements.length - 1);
if(prev != data.element_i){
triggerChange();
}
DisplayUpdate();
}
function selectDiffN(d){
// never hop more that 1 up/down the parent-child chain,
// normalize to -1,0,1:
d = Math.max(-1, d);
d = Math.min(+1, d);
d = Math.round(d);
selectN(data.element_i + d);
}
function init(){
setupcss();
$(document.body).off('.selectelementinternal');
$(document.body).on('click.selectelementinternal',...