JSFiddle - React, Tailwind, and code Playground
HTML
<div id="cntnt" class="grid" style="10000px;">
<textarea id="txt" onchange="build()" style="width: 90vw; height: 90vh;">
$( '.post__image-link' ).toArray().map( a => a.href ).join(', ')
В консоли браузера на странице Нуботреда выполнить вон ту ⬆ строку и скопировать сюда полученный текст — массив ссылок на картинки, почистить от ненужных ссылок.
Потом щёлкнуть мимо текстового поля ввода.
Двумя щелчками картинки перемещаются в конец.
</textarea>
</div>
CSS
*{transition:all 0.2s linear;}
.group{
display: inline-block;
box-shadow: inset 0 0 20px #004;
text-align: center;
}
.selected{
transform: scale(0.8);
box-shadow: 0 0 20px 3px #800;
}
img{
height: 400px;
margin: 5px;
}
.grid img{
margin: 0;
}
JavaScript
function qf( s, f, n ) { return s=[...(n||document).querySelectorAll(s)],f?s.map(f):s }
function qs( s, n ) { return (n||document).querySelector(s) }
function wr( e, t ) { e.innerHTML = t }
function debounce( f, delay = 50, ...b ) {
let t;
return function( ...a ) {
clearTimeout( t );
t = setTimeout( f, delay, ...b, ...a );
}
}
function delayed( f, ...b ) {
let t;
return function( delay = 50, ...a ) {
clearTimeout( t );
t = setTimeout( f, delay, ...b, ...a );
}
}
function getel( ev, tag = 'IMG' ) { return ev?.target.tagName === tag && ev.target }
function moveve( c, a, b ) {
if( !c ) return;
a.forEach( a => {
if( ! a?.tagName ) return;
let p = a.parentNode;
if( p?.parentNode === b ) b.insertBefore( a, p );
else if( c !== b ) c.append( a );
if( p.childNodes.length === 0 ) p.remove();
} );
}
function wrapel( e ) {
let p = e.parentNode;
if( !p ) return;
if( !p.classList.contains( 'group' ) ) {
const d = document.createElement( 'div' );
d.className = "group";
p.insertBefore( d, e );
d.append( e );
p = d;
}
return p;
}
function build() {
wr(
cntnt,
qs('#txt').value.replace( /^\W+|\W+$/g, '').split(',')
.map(s=>'<img src="'+s+'" class="grid-item">').join('')
);
}
const { body } = document;
const images = new Set();
const cntnt = qs('#cntnt');
let droponimg, dropondiv;
body.ondblclick = ev => {
ev = getel( ev );
( ev.parentNode === body ? cntnt : body ).append( ev );
}
body.ondragstart = ev => {
holdsel();
}
body.ondragenter = ev => {
droponimg = getel( ev );
dropondiv = getel( ev, 'DIV' );
}
body.ondragend = ev => {
images.add( getel( ev ) );
moveve( wrapel( droponimg ) || dropondiv, images, dropondiv );
images.forEach( imgsel );
}
const holdsel = delayed( imgsel );
body.onmousedown = ev => holdsel( 200, getel( ev ) );
body.onmouseup = ev => holdsel();
function imgsel( e ) {
if( !e ) return;
if( images.has( e ) ) {
images.delete( e );
}else{
...