首页 > 解决方案 > 如何在 js 菜单对象上设置活动属性?

问题描述

我创建了一个到我的网站的菜单导航,这个菜单很简单并且由我的对象构建:

const routes = [
  {
    text: "im foo",
    path: "foo",
    active: null,
    children: [
      {
        text: "im foo",
        path: "baz",
        active: null,
        children: [
          {
            text: "im foo",
            path: "baz",
            active: null,
            children: [{ text: "im foo", path: "daz", active: null }]
          }
        ]
      }
    ]
  },
  {
    text: "im A",
    path: "a",
    active: null,
    children: [
      {
        text: "im B",
        path: "b",
        active: null,
        children: [
          {
            text: "im c",
            path: "c",
            active: null
          },
          {
            text: "im d",
            path: "d",
            active: null
          }
        ]
      }
    ]
  }
];

此菜单具有折叠行为。这意味着我可以像这样打开和关闭菜单中的项目:

在此处输入图像描述

active属性设置为 true 时,我会给出一个使菜单打开的类。

我的问题是如何active通过给定的 url 设置属性?例如我的 url 是foo/bar/baz/daz,所以我需要找到在哪里daz然后上去。

问题是我怎么做“上去”?我不确定如何实现这个东西。

标签: javascript

解决方案


const routes = [
  {
    text: "im foo",
    path: "foo",
    active: null,
    children: [
      {
        text: "im foo",
        path: "baz",
        active: null,
        children: [
          {
            text: "im foo",
            path: "baz",
            active: null,
            children: [{ text: "im foo", path: "daz", active: null }]
          }
        ]
      }
    ]
  },
  {
    text: "im A",
    path: "a",
    active: null,
    children: [
      {
        text: "im B",
        path: "b",
        active: null,
        children: [
          {
            text: "im c",
            path: "c",
            active: null
          },
          {
            text: "im d",
            path: "d",
            active: null
          }
        ]
      }
    ]
  }
];


function setActive(routes, paths) {
  if (paths.length === 0) return true; // match all
  if (!routes) return false; // not match all
  const path = paths.shift();
  const matchRoute = routes.find(i => i.path === path);
  if (matchRoute) {
    const preState = matchRoute.active;
    const isMatchAll = setActive(matchRoute.children, paths);
    matchRoute.active = isMatchAll || preState;
    return isMatchAll;
  }
  // no route found
  return false;
}

// ok,  mark the path with active true
setActive(routes, "foo/baz/baz/daz".split("/"));

// No match, leave it as it is
// setActive(routes, "foo/baz/baz/dz".split("/"));
console.log(routes);   


推荐阅读