JSFiddle - React, Tailwind, and code Playground

by yijiang

HTML

<script src="http://dl.dropbox.com/u/1722364/rangy-core.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/ui-lightness/jquery-ui.css">
<ul>
    <li class="wrapper">
        <span class="text">A</span>
    </li>
    <li class="wrapper">
        <span class="text">B</span>
    </li>
    <li class="wrapper">
        <span class="text">C</span>
    </li>
    <li class="wrapper">
        <span class="text">D</span>
    </li>
    <li class="wrapper">
        <span class="text">A</span>
    </li>
    <li class="wrapper">
        <span class="text">B</span>
    </li>
    <li class="wrapper">
        <span class="text">C</span>
    </li>
    <li class="wrapper">
        <span class="text">D</span>
    </li>
    <li class="wrapper">
        <span class="text">D</span>
    </li>
</ul>

CSS

.wrapper {
    position: relative;
    float: left;
    margin: 20px;
    
    background: url('http://static.arstechnica.net/assets/2010/09/feat-pc-trolls-macs-sq-thumb-280x280-16871-f.jpg') center;
    width: 200px;
    height: 200px;
    overflow: hidden;
}

.wrapper img {
    margin: -40px 0 0 -40px;
}

.wrapper .text {
    position: absolute;
    
    font-size: 100px;
    font-family: Arial, sans-serif;
    font-weight: bold;
    
    display: block;
    text-align: center;
    vertical-align: middle;
    line-height: 1em;
    
    width: 100px;
    height: 100px;
    left: 50px;
    top: 50px;
    
    color: rgba(255, 255, 255, 0);
}

.ui-selectable-helper { 
    border:1px dotted orange; 
}

JavaScript

var selected = []; 


function drawSelection(){
    if(selected.length){
        selected.sort(function(a, b){
            if(a.sourceIndex){
                return a.sourceIndex - b.sourceIndex;
            } else if(a.compareDocumentPosition){
                if(a.compareDocumentPosition(b) == Node.DOCUMENT_POSITION_PRECEDING){
                    return 1;
                } else {
                    return -1;
                }
            }
        });
        var range = rangy.createRange(),
            sel = rangy.getSelection();
        
        range.setStart(selected[0].children[0], 0);
        range.setEnd(selected[selected.length - 1].children[0], 1);
        sel.setSingleRange(range);
    }
}

$('ul').selectable({
    delay: 100, 
    selecting: function(event, ui) {
        if(ui.selecting.getAttribute('class').indexOf('wrapper') !== -1 && $.inArray(ui.selecting, selected) === -1) {
            selected.push(ui.selecting);
            drawSelection();
        }
    }, 
    unselecting: function(event, ui){
        if(ui.unselecting.getAttribute('class').indexOf('wrapper') !== -1 && $.inArray(ui.unselecting, selected) > -1){
            selected.splice($.inArray(ui.unselecting, selected), 1);
            drawSelection();
        }
    }
});