JSFiddle - React, Tailwind, and code Playground

by Joe Cisneros

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<section class="elements" id="elements">
  <header>
    <h2>
      Attachable and Detachable Elements
    </h2>
  </header>
  <div>
    <p>
      Click the items to make them change colour
    </p>
    <ul class="items">
      <li id="first-item">First item</li>
      <li id="second-item">Second item</li>
    </ul>
    <p>
      The click behaviour should still exist after detaching and re-attaching the item
    </p>
  </div>
</section>

<section class="controls" id="controls">
  <header>
    <h2>
      Controls
    </h2>
  </header>
  <div class="columns">
    <div class="column">
      <h3>
        First Item
      </h3>
      <button id="detach-first-item" type="button">
        Detach First Item
      </button>
      <button id="attach-first-item" type="button">
        Re-attach First Item
      </button>
    </div>
    <div class="column">
      <h3>
        Second Item
      </h3>
      <button id="detach-second-item" type="button">
        Detach Second Item
      </button>
      <button id="attach-second-item" type="button">
        Re-attach Second Item
      </button>
    </div>
  </div>
</section>

CSS

.elements, .controls {
  font-family: Arial, sans-serif;
}

.elements {
  margin-bottom: 2em;
}

.items {
  margin: 2em 0;
}

.items li {
  cursor: pointer;
  margin: 1em 0;
}

.blue {
  color: #0026FF;
}

.brown {
  color: #7F3F3F;
}

.cyan {
  color: #00ffff;
}

.green {
  color: #007F46;
}

.orange {
  color: #FF6A00;
}

.maroon {
  color: #ff34b3;
}

.purple {
  color: #B200FF;
}

.red {
  color: #ff0000;
}

.column {
  box-sizing: border-box;
  float: left;
  max-width: 50%;
  padding-right: 5em;
}

.column button {
  display: block;
  margin: 0.75em 0;
}

JavaScript

(function(){
	var item1Colors = ['green', 'orange', 'blue', 'red'];
  
  var item2Colors = ['maroon', 'brown', 'cyan', 'purple'];
  
  var item1PreviousSibling, item1Parent;
  
  var item2PreviousSibling, item2Parent;
  
  function getRandomNumber(max) {
  	return Math.floor(Math.random() * (max + 1));
  }
  
  var $firstItem =  $('#first-item');
  
  $firstItem.on('click', function (e) {
  	var colorClass;
    
    do
    {
    	var index = getRandomNumber(item1Colors.length - 1);
    
    	colorClass = item1Colors[index];
    } while (colorClass === this.className); // Make sure the same color isn't applied twice in a row
  
    this.className = colorClass;
  });
  
  var $secondItem = $('#second-item');
  
  $secondItem.on('click', function (e) {
  	var colorClass;
    
    do
    {
    	var index = getRandomNumber(item2Colors.length - 1);
    
    	colorClass = item2Colors[index];
    } while (colorClass === this.className); // Make sure the same color isn't applied twice in a row
  
    this.className = colorClass;
  });
  
  $('#detach-first-item').on('click', function (e) {
  	if (!$.contains(document.documentElement, $firstItem[0])) {
    	alert('Item already detached');
      return;
    }
    
    item1PreviousSibling = $firstItem.prop('previousSibling');
    
    item1Parent = $firstItem.prop('parentElement');
      
    $firstItem.detach();
  });
  
  $('#attach-first-item').on('click', function (e) {
  	if ($.contains(document.documentElement, $firstItem[0])) {
    	alert('Item already attached');
      return;
    }
    
    if (item1PreviousSibling !== undefined) {
    	$firstItem.insertAfter(item1PreviousSibling);
    } else {
    	$firstItem.prependTo(item1Parent);
    }
    
    item1PreviousSibling = item1Parent = undefined;
  });
  
  $('#detach-second-item').on('click', function (e) {
   	if (!$.contains(document.documentElement, $secondItem[0])) {
    	alert('Item already detached');
      return;
    }
    
    item2PreviousSibling =...