用span替换标签

时间:2016-02-02 16:29:29

标签: javascript jquery html angularjs mmenu

我正在使用AngularJS和mmenu创建一个菜单,我有一些子菜单没有正确地作为子菜单运行。基本上mmenu将span作为菜单处理,当你单击它时,它会扩展(或尝试)并将标记视为链接,当你单击它时菜单关闭并且它会尝试将你发送到链接。问题是当我使用ng-repeat构建菜单时,我的一些项目是链接(a),而另一些应该有更多的子菜单使它们跨越。我可以想办法解决这个问题,但我似乎无法让它们发挥作用,这里有我尝试的解决方案:

  1. 使用ng-click函数运行if语句,查看被点击的菜单是否有嵌套的ul,如果是,则添加类mm.opened以扩展子菜单而不是跟随链接

  2. 使用函数在构建完整个菜单后运行,找到任何嵌套了ul的Unhandled rejection ValidationError: Field validation failed at MongooseError.ValidationError .... 标记,并用span替换a标记(" span" + this.innerHTML +" / span")

  3. 寻求帮助(当前步骤)

  4. 我对任何解决方案都很开放,我的角度可能是错误的,这可能导致我的所有问题,所以请随时纠正我。

    我无法附加一个工作示例,因为我的菜单是从json文件构建的,我无法将json导入代码编辑器(我知道)

    这是我的菜单:

    <a>

    它看起来像这样:

    Menu opened

    当我点击ATA 29时,它会扩展为:

    Menu opened with ATA 29 expanded

    你会发现ATA 29中有4个项目,其中3个应该是常规链接,第一个也有4个嵌套项目,所以当我点击它时我希望它像ATA 29一样扩展,但它认为它是一个链接所以它这样做:

    Menu opened with left hydraulic system selected

    我意识到没有工作代码很难提供帮助,但任何帮助都会受到赞赏。

    &#13;
    &#13;
    <ul>
      <li><a ng-href="#/home" class="menuBtn">Home</a></li>
      <li ng-repeat="menu in menuInfo" ng-class="countDisable(menu.schematics.length, menu)"> <a class="menuBtn">ATA {{menu.ata}} - {{menu.name}}</a>
        <ul>
          <li ng-click="subCheck()" ng-repeat="submenu in menu.schematics"><a ng-href="#{{submenu.view}}" class="menuBtn">{{submenu.name}}</a>
            <ul>
              <li ng-repeat="animated in submenu.subs"><a ng-href="#{{animated.view}}" ng-click="contentCtrl(animated)" class="menuBtn">{{animated.name}}</a></li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
    
    &#13;
    var app = angular.module('myApp', ['ngRoute'])
    
    .config(['$routeProvider',
      function($routeProvider) {
        //determines redirects go via shortcuts, clicking on the management icon on the main page sends the routeProvider /MG which it then uses to pull the relevant HTML file
        $routeProvider
          .when('/', {
            controller: 'projectController',
            templateUrl: './assets/html/home.html'
          })
          .when('/schematicView', {
            controller: 'projectController',
            templateUrl: './assets/html/schematicView.html'
          })
          .when('/staticView', {
            controller: 'projectController',
            templateUrl: './assets/html/staticView.html'
          })
          .otherwise({
            controller: 'projectController',
            templateUrl: './assets/html/home.html'
          })
      }
    ]);
    
    app.controller('projectController', function projectController($scope, $http, $rootScope, $timeout) {
      // $(document).ready(function($) {
      //     setTimeout(function() {
      //         $("#menu").mmenu({
      //             "slidingSubmenus": false,
      //             "counters": true,
      //             extensions: ["multiline"],
      //             offCanvas: {
      //                 position: "left",
      //                 zposition: "front"
      //             }
      //         });
      //     }, 100);
      //     // $("#menu").click(function() {
      //     //     $('.mm-opened').removeClass('mm-opened');
      //     // });
      // });
    
      $scope.menuInfo = [{
        name: "This is a span it should expand"
      }];
       $scope.secMenuInfo = [{
        name: "This is an a, it should close the menu",
        name2: "This is an a, but it needs to work like a span",
         name3: "This is an a, it should close the menu"
      }];
    
    
    
      // $scope.activeID = 'HM';
      // $scope.activePath = "Assets/images/allActive.png";
    
      // function getImgPath(item) {
      //     $scope.activePath = "Assets/images/" + item.path + "";
      //     console.log($scope.activePath);
      // }
    
      // $("#menu em").trigger("count");
    
      $scope.setImgPath = function(btnPath) {
        console.log(btnPath)
        $scope.activePath = "Assets/images/" + btnPath + "";
        console.log($scope.activePath);
      };
      $scope.contentCtrl = function(id) {
        $scope.active = id;
        console.log($scope.active);
        // $scope.activeItem = item;
        // getImgPath($scope.activeItem);
    
    
      };
      // $scope.subCheck = function() {
      //     if ($(this).children().find('mm-counter')) {
      //         alert("has ul");
      //         return false;
      //     } else {
      //         alert("no ul");
      //         return false;
      //     }
    
      // };
    
    
    
    });
    
    app.directive("mmenu", function($timeout) {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
    
            $timeout(function() {
              $(element).mmenu({
                "slidingSubmenus": false,
                "counters": true,
                extensions: ["multiline"],
                offCanvas: {
                  position: "left",
                  zposition: "front"
                } //ends offCanvas
              });
    
              $("em").each(function() {
                var t = $(this).text().trim();
                if (t == "0") {
                  $(this).next().remove();
    
                  $(this).remove();
    
                }
              });
            }, 10);
          } //ends link
      }
    
    });
    &#13;
    /* Helvetica Font */
    
    @font-face {
      font-family: HelveticaNeue;
      src: local('0'), url('../fonts/HelveticaNeueLTStd-Lt.woff') format('woff'), url('../fonts/HelveticaNeueLTStd-Lt.otf') format('otf');
    }
    body,
    html {
      font-family: Helvetica, Arial, sans-serif;
      overflow: none;
      color: #FFF;
    }
    body {
      background: #FFFFFF;
    }
    #header {
      background: #212121;
      box-shadow: 0 1.5px 4px rgba(0, 0, 0, 0.24), 0 1.5px 6px rgba(0, 0, 0, 0.12);
    }
    #footer {
      background: #212121;
      box-shadow: 0 -1.5px 4px rgba(0, 0, 0, 0.24), 0 -1.5px 6px rgba(0, 0, 0, 0.12);
    }
    .fa {
      color: #8ea5d0;
    }
    .fa:hover {
      color: #627EB0;
    }
    .fa:active {
      color: #415E95;
    }
    a:focus {
      outline: 0 none;
      color: #627EB0;
      text-decoration: none;
    }
    .info_btn {
      color: #FFF !important;
      background-color: #8ea5d0;
      box-shadow: 0 3px 12px rgba(0, 0, 0, 0.23), 0 3px 12px rgba(0, 0, 0, 0.16);
    }
    .info_btn:hover {
      background-color: #627EB0;
    }
    .info_btn:active {
      background-color: #415E95;
      color: #FFF;
      text-decoration: none;
    }
    .info_btn:hover,
    .info_btn:visited,
    .info_btn:link,
    .info_btn:active {
      text-decoration: none;
      color: #FFF;
    }
    #menu {
      background: #444444;
      box-shadow: 5px 0px 4px rgba(0, 0, 0, 0.3);
      z-index: 10;
    }
    #menu .li {
      background: #555555;
    }
    #menu > ul > li {
      list-style: none;
    }
    #menu > ul {
      padding: 0px;
    }
    .menuBtn {
      background-color: transparent;
      display: inline-flex;
      cursor: pointer;
      color: #ffffff;
      border: #212121;
      border-bottom-style: solid;
      border-width: 1px;
      width: 100%;
      font-size: 17px;
      padding: 10px 10px;
      -webkit-transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      -moz-transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      -o-transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      outline: none;
    }
    .menuBtn:hover {
      background-color: #333333;
      outline: none;
    }
    .menuBtn:active {
      position: relative;
      background-color: #222222;
      outline: none;
    }
    #homeContent {
      color: #000000;
    }
    /* Global and Overrides */
    
    #header {
      height: 96px;
      border: 0;
      top: 0px;
      width: 100%;
    }
    #content {
      width: 100%;
      position: fixed;
      top: 96px;
      bottom: 72px;
    }
    #footer {
      height: 72px;
      border: 0;
      bottom: 0px;
      position: fixed;
      width: 100%;
    }
    .fa {
      font-size: 36px;
      cursor: pointer;
      display: inline-block;
      padding-top: 30px;
      padding-left: 30px;
    }
    .title {
      position: absolute;
      right: 75px;
      top: 20px;
      max-width: 400px;
    }
    .info_btn {
      position: absolute;
      font-size: 40px;
      font-weight: 400;
      right: 30px;
      top: 48px;
      border-radius: 50px;
      padding: 0 21.8px;
      font-size: 20px;
      line-height: 48px;
      position: absolute;
      top: 72px;
      right: 1.6%;
      z-index: 100;
    }
    /*  causes the color to change when you hover over a button of class myButton */
    
    .revNum {
      font-size: 16px;
      position: absolute;
      bottom: 25px;
      left: 12px;
    }
    .footer_info {
      bottom: 25px;
      position: absolute;
      margin: 0px auto;
      width: 100%;
      font-size: 18px;
      display: block;
      text-align: center;
    }
    .logo {
      height: 48px;
      position: absolute;
      bottom: 12px;
      right: 75px;
    }
    &#13;
    &#13;
    &#13;

2 个答案:

答案 0 :(得分:1)

  • 兄弟li未关闭,并且在没有正确设置成为子菜单的情况下成为嵌套菜单。

  • li没有像我预期的那样生成span。所以我只是简单地复制了我在顶部菜单中看到的模式,它起作用了。

改变这个:

 <li ng-repeat="submenu in secMenuInfo">
   <a ng-href="#{{submenu.view}}" class="menuBtn">{{submenu.name}}</a>
   <li ng-repeat="submenu in secMenuInfo">
     <a ng-href="#{{submenu.view}}" class="menuBtn">{{submenu.name2}}</a>

对此:

 <li ng-repeat="submenu in secMenuInfo">
    <a ng-href="#{{submenu.view}}" class="menuBtn">{{submenu.name}}</a>
 </li>
 <li ng-repeat="submenu in secMenuInfo">
    <span class="menuBtn">{{submenu.name2}}</span>

<!DOCTYPE html>
<html>
<meta charset="utf-8">

<head>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/jQuery.mmenu/5.6.1/css/jquery.mmenu.all.css" rel="stylesheet" />

  <style>
    /* Helvetica Font */
    @font-face {
      font-family: HelveticaNeue;
      src: local('0'), url('../fonts/HelveticaNeueLTStd-Lt.woff') format('woff'), url('../fonts/HelveticaNeueLTStd-Lt.otf') format('otf');
    }
    body,
    html {
      font-family: Helvetica, Arial, sans-serif;
      overflow: none;
      color: #FFF;
    }
    body {
      background: #FFFFFF;
    }
    #header {
      background: #212121;
      box-shadow: 0 1.5px 4px rgba(0, 0, 0, 0.24), 0 1.5px 6px rgba(0, 0, 0, 0.12);
    }
    #footer {
      background: #212121;
      box-shadow: 0 -1.5px 4px rgba(0, 0, 0, 0.24), 0 -1.5px 6px rgba(0, 0, 0, 0.12);
    }
    .fa {
      color: #8ea5d0;
    }
    .fa:hover {
      color: #627EB0;
    }
    .fa:active {
      color: #415E95;
    }
    a:focus {
      outline: 0 none;
      color: #627EB0;
      text-decoration: none;
    }
    .info_btn {
      color: #FFF !important;
      background-color: #8ea5d0;
      box-shadow: 0 3px 12px rgba(0, 0, 0, 0.23), 0 3px 12px rgba(0, 0, 0, 0.16);
    }
    .info_btn:hover {
      background-color: #627EB0;
    }
    .info_btn:active {
      background-color: #415E95;
      color: #FFF;
      text-decoration: none;
    }
    .info_btn:hover,
    .info_btn:visited,
    .info_btn:link,
    .info_btn:active {
      text-decoration: none;
      color: #FFF;
    }
    #menu {
      background: #444444;
      box-shadow: 5px 0px 4px rgba(0, 0, 0, 0.3);
      z-index: 10;
    }
    #menu .li {
      background: #555555;
    }
    #menu > ul > li {
      list-style: none;
    }
    #menu > ul {
      padding: 0px;
    }
    .menuBtn {
      background-color: transparent;
      display: inline-flex;
      cursor: pointer;
      color: #ffffff;
      border: #212121;
      border-bottom-style: solid;
      border-width: 1px;
      width: 100%;
      font-size: 17px;
      padding: 10px 10px;
      -webkit-transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      -moz-transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      -o-transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      transition: color .25s linear, background-color .25s ease-in-out, border-color .25s ease-in-out;
      outline: none;
    }
    .menuBtn:hover {
      background-color: #333333;
      outline: none;
    }
    .menuBtn:active {
      position: relative;
      background-color: #222222;
      outline: none;
    }
    #homeContent {
      color: #000000;
    }
    /* Global and Overrides */
    #header {
      height: 96px;
      border: 0;
      top: 0px;
      width: 100%;
    }
    #content {
      width: 100%;
      position: fixed;
      top: 96px;
      bottom: 72px;
    }
    #footer {
      height: 72px;
      border: 0;
      bottom: 0px;
      position: fixed;
      width: 100%;
    }
    .fa {
      font-size: 36px;
      cursor: pointer;
      display: inline-block;
      padding-top: 30px;
      padding-left: 30px;
    }
    .title {
      position: absolute;
      right: 75px;
      top: 20px;
      max-width: 400px;
    }
    .info_btn {
      position: absolute;
      font-size: 40px;
      font-weight: 400;
      right: 30px;
      top: 48px;
      border-radius: 50px;
      padding: 0 21.8px;
      font-size: 20px;
      line-height: 48px;
      position: absolute;
      top: 72px;
      right: 1.6%;
      z-index: 100;
    }
    /*  causes the color to change when you hover over a button of class myButton */
    .revNum {
      font-size: 16px;
      position: absolute;
      bottom: 25px;
      left: 12px;
    }
    .footer_info {
      bottom: 25px;
      position: absolute;
      margin: 0px auto;
      width: 100%;
      font-size: 18px;
      display: block;
      text-align: center;
    }
    .logo {
      height: 48px;
      position: absolute;
      bottom: 12px;
      right: 75px;
    }
  </style>
</head>

<body ng-app="myApp" ng-controller="projectController">
  <title>{{projectInfo.title}}</title>
  <div id="wrapper">
    <div id="header">

      <a class="fa fa-home" ng-href="#/home"></a>
      <img class="title" src="assets/images/title.svg"></img>
      <a href class="info_btn"><span>i</span></a>
      <nav id="menu" mmenu>
        <ul>
          <li><a ng-href="#/home" class="menuBtn">Home</a>
          </li>
          <li ng-repeat="menu in menuInfo" ng-class="countDisable(menu.schematics.length, menu)"> <span class="menuBtn">ATA {{menu.ata}} - {{menu.name}}</span>
            <ul>
              <li ng-repeat="submenu in secMenuInfo"><a ng-href="#{{submenu.view}}" class="menuBtn">{{submenu.name}}</a>
              </li>
              <li ng-repeat="submenu in secMenuInfo"><span class="menuBtn">{{submenu.name2}}</span>
                <ul>
                  <li ng-repeat="animated in secMenuInfo"><a ng-href="#{{animated.view}}" ng-click="contentCtrl(animated)" class="menuBtn">{{submenu.name3}}</a>
                  </li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </nav>
    </div>
    <div id="content">
      <a href="#menu" target="_self"><h1>HOME</h1></a>
    </div>
    <div id="footer">
      <div class="revNum">Revision: {{projectInfo.version}}</div>
      <div class="footer_info">{{projectInfo.footer}}</div>
      <img class="logo" ng-src="./assets/images/{{projectInfo.logo}}">
    </div>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery.mmenu/5.6.1/js/jquery.mmenu.all.min.js"></script>
  <script src="https://code.angularjs.org/1.5.0-rc.2/angular-route.js"></script>
  <script>
    var app = angular.module('myApp', ['ngRoute'])

    .config(['$routeProvider',
      function($routeProvider) {
        //determines redirects go via shortcuts, clicking on the management icon on the main page sends the routeProvider /MG which it then uses to pull the relevant HTML file
        $routeProvider
          .when('/', {
            controller: 'projectController',
            templateUrl: './assets/html/home.html'
          })
          .when('/schematicView', {
            controller: 'projectController',
            templateUrl: './assets/html/schematicView.html'
          })
          .when('/staticView', {
            controller: 'projectController',
            templateUrl: './assets/html/staticView.html'
          })
          .otherwise({
            controller: 'projectController',
            templateUrl: './assets/html/home.html'
          })
      }
    ]);

    app.controller('projectController', function projectController($scope, $http, $rootScope, $timeout) {
      // $(document).ready(function($) {
      //     setTimeout(function() {
      //         $("#menu").mmenu({
      //             "slidingSubmenus": false,
      //             "counters": true,
      //             extensions: ["multiline"],
      //             offCanvas: {
      //                 position: "left",
      //                 zposition: "front"
      //             }
      //         });
      //     }, 100);
      //     // $("#menu").click(function() {
      //     //     $('.mm-opened').removeClass('mm-opened');
      //     // });
      // });

      $scope.menuInfo = [{
        name: "This is a span it should expand"
      }];
      $scope.secMenuInfo = [{
        name: "This is an a, it should close the menu",
        name2: "This is an a, but it needs to work like a span",
        name3: "This is an a, it should close the menu"
      }];



      // $scope.activeID = 'HM';
      // $scope.activePath = "Assets/images/allActive.png";

      // function getImgPath(item) {
      //     $scope.activePath = "Assets/images/" + item.path + "";
      //     console.log($scope.activePath);
      // }

      // $("#menu em").trigger("count");

      $scope.setImgPath = function(btnPath) {
        console.log(btnPath)
        $scope.activePath = "Assets/images/" + btnPath + "";
        console.log($scope.activePath);
      };
      $scope.contentCtrl = function(id) {
        $scope.active = id;
        console.log($scope.active);
        // $scope.activeItem = item;
        // getImgPath($scope.activeItem);


      };
      // $scope.subCheck = function() {
      //     if ($(this).children().find('mm-counter')) {
      //         alert("has ul");
      //         return false;
      //     } else {
      //         alert("no ul");
      //         return false;
      //     }

      // };



    });

    app.directive("mmenu", function($timeout) {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {

            $timeout(function() {
              $(element).mmenu({
                "slidingSubmenus": false,
                "counters": true,
                extensions: ["multiline"],
                offCanvas: {
                  position: "left",
                  zposition: "front"
                } //ends offCanvas
              });

              $("em").each(function() {
                var t = $(this).text().trim();
                if (t == "0") {
                  $(this).next().remove();

                  $(this).remove();

                }
              });
            }, 10);
          } //ends link
      }

    });
  </script>
</body>

</html>

答案 1 :(得分:0)

抱歉没有彻底阅读这个问题,这有点长......

听起来您想要用<a>标签替换所有<span>标签。一种解决方案是向控制器添加一个函数以拉出锚文本并进行替换,然后通过函数在ng-repeat中运行变量。

$scope.replaceAnchors = function(item) {
  var matches = /<a\s+[^>]*href="([^"]*)"[^>]*>(.*)<\/a>/i.exec(str);
  return '<span>' + matches[2] + '</span>';
}

在你的模板中:

{{replaceAnchors(YOUR.MENU.VARIABLE)}}