So I have created my own module that overrides Topmenu.php.
<?php namespace Perso\Menu\Block\Html; class Topmenu extends \Magento\Theme\Block\Html\Topmenu { protected function _getHtml( \Magento\Framework\Data\Tree\Node $menuTree, $childrenWrapClass, $limit, $colBrakes = [] ) { $html = ''; $children = $menuTree->getChildren(); $parentLevel = $menuTree->getLevel(); $childLevel = $parentLevel === null ? 0 : $parentLevel + 1; $counter = 1; $itemPosition = 1; $childrenCount = $children->count(); $parentPositionClass = $menuTree->getPositionClass(); $itemPositionClassPrefix = $parentPositionClass ? $parentPositionClass . '-' : 'nav-'; foreach ($children as $child) { $child->setLevel($childLevel); $child->setIsFirst($counter == 1); $child->setIsLast($counter == $childrenCount); $child->setPositionClass($itemPositionClassPrefix . $counter); $outermostClassCode = ''; $outermostClass = $menuTree->getOutermostClass(); if ($childLevel == 0 && $outermostClass) { $outermostClassCode = ' class="' . $outermostClass . '" '; $child->setClass($outermostClass); } if (count($colBrakes) && $colBrakes[$counter]['colbrake']) { $html .= '</ul></li><li class="column"><ul>'; } $html .= '<li ' . $this->_getRenderedMenuItemAttributes($child) . '>'; $html .= '<span class="menu" data-atc="'.base64_encode($child->getUrl()) . '" ' . $outermostClassCode . '>' . $this->escapeHtml($child->getName()) . '</span>' . $this->_addSubMenu( $child, $childLevel, $childrenWrapClass, $limit ) . '</li>'; $itemPosition++; $counter++; } if (count($colBrakes) && $limit) { $html = '<li class="column"><ul>' . $html . '</ul></li>'; } return $html; } }
Then I have created a custom JS that replace that do the opposite when someone mouves the mouse or scroll down. It turns the in .
require(['jquery', 'jquery/ui'], function($){ var job= false; function update_dom(){ if(job == false) { $(".menu").each(function(){ var url = atob($(this).attr("data-atc")); var anchor = $(this).html(); $(this).replaceWith('<a href="'+url+'" target="_self" >'+anchor+'</a>'); }); job= true; } }$(function(){ $("body").mousemove(update_dom); $("body").scroll(update_dom); $("body").touchmove(update_dom); }); }
My purpose is to avoid Google follow my mega menu links but allow my visitors to navigate with proper <a href>. So Google sees with base 64 encrypted "data-atc" where users see classic <a href>.
My problem : if I move my mouse when the page is loading, everything is fine (my source code is with <span> instead of <a href>, my menu and submenu load as <span> then turn into <a href> etc...everything is perfect). But if I don't move my mouse during the loading and let it end, when I move it, my submenu doesn't appear. My menu and submenu are loaded but when my mouse comes over my top menu element the action of displaying <display : block> my submenu is not working.
It looks like magento needs both <a> and class ="level-top" in Topmenu.php to activate the display:block action... I really don't know how to do...