jquery JSON структра из html меню - пример кода

Ниже пример кода нескольких jquery-плагинов, с помощью которых можно отсканировать имеющееся меню и вывести своё:

$.fn.getMenuStructure = function (options) {
    var defaults = {
        childrenSelector: 'li',
        subMenuListSelector: 'ul.sub-menu',
    },
    settings = $.extend(defaults, options);

    var structure = [];

    var $this = $(this);

    var children = $this.children(settings.childrenSelector);

    var i = 0;
    $.each(children, function (index, child) { // обходим все поля


        var $child = $(child);
        var $link = $child.find('a');

        structure[i] =  {'html': $link.html(), 'url': $link.attr('href')};

        if ($child.find('ul.sub-menu').length) {
            var $submenu = $($child.find('ul.sub-menu')[0]);
//                console.log('подменю', $submenu);
            structure[i].children = $submenu.getMenuStructure(settings);
        }
        i++;
    });

    return structure;
};

/**
 *  Построит внутренний html меню (начиная с элементов списка первого уровня)
 * @param {object} structure    объект со структурой (json) типа:
 * [
    {'html': 'Элемент 1', 'url': '#'},
    {'html': 'Элемент 2', 'url': '#', 
            'children': [
                    {'html': 'Потомок 1 Элемент 2', 'url': '#'},
                    {'html': 'Потомок 2 Элемент 2', 'url': '#'},
            ]
    },
    {'html': 'Элемент 3', 'url': '#'},
    {'html': 'Элемент 4', 'url': '#'},
   ]       
 * 
 * @return {String}
 */
$.getInnerMenuHtmlFromJson = function(structure)
{
    var html = '';


    $.each(structure, function (index, child) { // обходим все поля

        if (typeof child.children !== "undefined" 
                && child.children !== null) {
            html += '<li class="menu-drop"><a class="link-submenu" href="' 
                +  child.url + '">' +  child.html + '</a>';
                html += '<ul class="sub-menu">';
                html += $.getInnerMenuHtmlFromJson(child.children);
                html += '</ul>';
            html += '</li>';
        } else {
            html += '<li class=""><a href="' 
                +  child.url + '">' +  child.html + '</a>';
            html += '</li>';
        }

    });

    return html;
}

/**
 * Добавит блок с мобильным меню
 * (подразумевается добавление после блока содержащего основное меню
 *  - т.е. того, на котроом и вызывается данный плагин)
 * @param {type} options
 * @return {undefined}
 */
$.fn.addMobileMenuVersion = function (options) {

    var $this = $(this);
    var $menu = $('#topnav');
//    console.log('меню', $menu);

    var structure = $menu.getMenuStructure();
//    console.log('структура 2:', structure);

    var html = '<div id="mobile-nav" class="select-menu">' // открывающая статическая часть блока мобильного меню
    + '<div class="menu-holder">'
            + '<a href="#" class="toogle-menu menu-close">'
                    + '<span class="t"> </span>'
                    + '<span class="b"> </span>'
            + '</a><ul class="menu">';

    html += $.getInnerMenuHtmlFromJson(structure);

    html += '</ul></div>'  // закрывающая статическая часть блока меню
            + '<a href="#" class="toogle-menu">'
                + '<span class="t"> </span>'
                + '<span class="c"> </span>'
                + '<span class="b"> </span>'
            + '</a>'
            + '<div class="nav-overlay"> </div>'
        + '</div>';
    $this.after(html)
};

Пример использования:

$("head").append('<style type="text/css">@media(max-width: 767px){.sf-menu{display:none;} .select-menu{display: block;}}</style>');
var structure = $('#topnav').getMenuStructure();
//   console.log('структура:', structure);
            
 $('nav#basemenu').addMobileMenuVersion();

Пример сканируемого меню (можно использовать для отладки):

<nav id="nav">
	<div class="menu-holder">
		<a href="#" class="toogle-menu menu-close">
			<span class="t"> </span>
			<span class="b"> </span>
		</a>
		<ul class="menu">
			<li class=""><a href="#"></a></li>
			<li class="menu-drop">
				<a class="link-submenu" href="#"> </a>
				<ul class="sub-menu">
					<li><a href="#"></a></li>
					<li><a href="#"></a></li>
					<li><a href="#"></a></li>
				</ul>
			</li>
			<li><a href="#"></a></li>
			<li><a href="#"></a></li>
		</ul>
	</div>
	<a href="#" class="toogle-menu">
		<span class="t"> </span>
		<span class="c"> </span>
		<span class="b"> </span>
	</a>
	<div class="nav-overlay"> </div>
</nav>