JSFiddle - React, Tailwind, and code Playground

by Nikita

HTML

<div id="topnav" class="topnav"></div>

CSS

@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,600,700);
@import url(http://fontawesome.io/assets/font-awesome/css/font-awesome.css);
body {
  font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
  font-size: 13px;
  font-weight: 400;
}
#topnav {
  clear: both;
}
/* Top Navigation */
.topnav {
  width: 100%;
  height: 38px;
  margin: 0;
  padding: 0;
  font-size: 13px;
  background: #505050;
  background: linear-gradient(to bottom, #505050 0%, #2e2e2e 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #505050), color-stop(1, #2e2e2e));
  background: -webkit-linear-gradient(top, #505050 0%, #2e2e2e 100%);
  background: -ms-linear-gradient(top, #505050, #2e2e2e);
  background: -moz-linear-gradient(center top, #505050 0%, #2e2e2e 100%);
  background: -o-linear-gradient(#2e2e2e, #505050);
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#505050', endColorstr='#2e2e2e', GradientType=0);
  -webkit-box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.4);
  -moz-box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.4);
  box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.4);
  /* Level 1 */
}
.topnav ul.menu {
  text-align: center;
  display: inline-block;
  padding: 0;
  margin: 0;
  width: 100%;
  height: 38px;
}
.topnav ul.menu li.item {
  list-style: none;
  display: inline-block;
  /* Leve 2 */
}
.topnav ul.menu li.item > a {
  text-transform: uppercase;
  font-weight: 600;
  color: #ffffff;
  height: 20px;
  display: inline-block;
  text-decoration: none;
  padding: 9px 20px;
}
.topnav ul.menu li.item a:hover {
  background: #f4f4f4;
  background: linear-gradient(to bottom, #f4f4f4 0%, #d2d2d2 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #f4f4f4), color-stop(1, #d2d2d2));
  background: -webkit-linear-gradient(top, #f4f4f4 0%, #d2d2d2 100%);
  background: -ms-linear-gradient(top, #f4f4f4, #d2d2d2);
  background: -moz-linear-gradient(center top, #f4f4f4 0%, #d2d2d2 100%);
 ...

JavaScript

/*getRandomInt() got here:
http://stackoverflow.com/questions/1527803/generating-random-numbers-in-javascript-in-a-specific-range,
vote for it plz :)*/
function getRandomInt(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

/** Generates <li class="item"><a href="#">Item {index}</a></li>*/
function createLeaf(index) {
	var a = $("<a/>", {
		href: "#",
		text: "Item " + (index+1)});
	var li = $("<li />", {
		class: "item"
	}).append(a);
		
	return li;
}
	
var MAX_NESTING_LEVEL = 7;
var MIN_CHILD_NUMBER = 4;
var MAX_CHILD_NUMBER = 7;

/** Generates <ul></ul> recursively*/
function createBranch(currentNode) {
	var numberOfParents = currentNode.parents("li").length;
	
	//if we don't reach deepest level - we can add more ul
	if(numberOfParents < MAX_NESTING_LEVEL-1) {
		//decide, should we create submenu for current <li>
		//here we can add additional check(s) if we always want to generate non-empty menu
		if ( Math.round(Math.random()) == 1) {
			//create <ul> submenu
			var ul = $("<ul />", {
				class: "submenu"
			});
			
			currentNode.append(ul);

			//adding children <li> to submenu
			var childNumber = getRandomInt(MIN_CHILD_NUMBER, MAX_CHILD_NUMBER);
			for(var i = 0; i < childNumber; i++) {
				var li = createLeaf(i);
				ul.append(li);
					
				//using recursion: submenu creation for current <li>
				createBranch(li);
			}
		}
	}
	return currentNode;
}

/**could generate empty (nothing will be added to "#topnav")*/
function randomMenu() {
	console.log("Started randomNonEmptyMenu: " + new Date());
	var start = new Date().getTime();

	var generated = createBranch($("#topnav"));
	console.log("structure generated: " + (new Date().getTime() - start) + "ms");

	generated.find("ul").parent("li").addClass("parent");
	console.log("\"parent\" class added to LIs: " + (new Date().getTime() - start) + "ms");

	generated.children("ul").removeClass("submenu").addClass("menu");

	console.log("complete ul appended to topnav: " + (new...