JSFiddle - React, Tailwind, and code Playground

by NerfAnarchist

HTML

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="viewport" content="width=device-width, user-scalable=no" />

<table>
    <tbody>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
            <td class="handle">-</td>
        </tr>
        <tr>
            <td>data1</td>
            <td>data2</td>
...

CSS

html, body {
    width: 100%;
    height: 100%;
    margin: 0px;
}

table {
    width: 100%;
    margin: 0px;
}

.clone {
    position: absolute;
    opacity: 0.5;
    left: 10px;
}

.handle {
    width: 100px;
    background-color: #FF0000;
}

JavaScript

// sortable list on an iphone

var iOS = true, scrollInterval;
mouse_position = function (mode, event, id) {
    'use strict';
    var offset = $(id).offset(), pageX, pageY;
    
    pageX = (iOS ? event.originalEvent.touches[0].pageX: event.pageX);
    pageY = (iOS ? event.originalEvent.touches[0].pageY: event.pageY);
    
    if (mode === 'top') {
        return pageY - offset.top;
    }
    if (mode === 'left') {
        return pageX - offset.left;
    }
    return '';
};

$('.handle').on('touchstart', function (event) {
    event.preventDefault();
    event.stopPropagation();
    
    $('body').append('<div class="clone" style="top:' + mouse_position('top', event, 'body') + 'px;">' +
                         $(this).parents('tr').html() +
                     '</div>');
    
    $('body').on('touchmove.resort_move', function (event) {
        var top = mouse_position('top', event, 'body'),
            left = mouse_position('left', event, 'body');
        
        event.preventDefault();
        event.stopPropagation();
        
        clearInterval(scrollInterval);
        
        if ((top + 40) - $('body').scrollTop() > window.innerHeight) {
            scrollInterval = setInterval(function () {
                $('body').scrollTop($('body').scrollTop() + 3);
                $('.clone').css('top', ($('body').scrollTop() + window.innerHeight - 26) + 'px');
            }, 30);
        } else if (top - 40 < $('body').scrollTop()) {
            scrollInterval = setInterval(function () {
                $('body').scrollTop($('body').scrollTop() - 3);
                $('.clone').css('top', ($('body').scrollTop() + 26) + 'px');
            }, 30);
        } else {
            $('.clone').css('top', top + 'px');
        }
    });
    
    $('body').one('touchend.resort', function (event) {
        event.preventDefault();
        event.stopPropagation();
        
        $('.clone').remove();
        $('body').off('touchmove.resort_move');
    });
});