亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Jquery 自動導航高亮的相關問題,求大神指教.

Jquery 自動導航高亮的相關問題,求大神指教.

開心每一天1111 2018-09-12 10:09:15
想用JS直接實現系統菜單的導航高亮功能,其實就是自動檢測頁面url找到對應的元素addClass;不過因為本人菜鳥,實在寫不出,求大神指教。HTML結構如下(注釋中就是基本需求)如上代碼中的注釋,我寫了一個,已經基本滿足上面的要求,但是還有一個需求,就是某些頁面的url不在菜單里,也要讓某個菜單高亮。比如上面的用戶管理=admin/user/index ,進入用戶管理肯定沒問題,但是我還有一個 添加用戶admin/user/add,進入添加用戶這個頁面的時候也想讓 用戶管理 href=admin/user/index這個菜單高亮,就不知道怎么寫了。我的想法是,訪問頁面的時候如果url存在在菜單中就自動高亮,如果不存在,如剛才說的添加用戶admin/user/add,定義一個函數 如 set_nav_active(url) ,然后在admin/user/add這個頁面 傳入他想要高亮的菜單url ,比如se_nav_active(admin/user/index),但是,想法是有了,不知道怎么寫了,求大神指教,或者大神有沒有更好的辦法
查看完整描述

1 回答

?
富國滬深

TA貢獻1790條經驗 獲得超9個贊

這個問題很有意思,總結一下,你要解決的問題有兩個

  1. 根據當前 URL 找到匹配的 href 屬性

  2. 找到對應第 1 找到的 href 屬性的那個 <a>,對它以及它的幾級父元素添加狀態

下面來一個一個的解決

示例都是用的 es6 語法,不懂的話可以自己去 babel-try it out,或者 typescript playgournd 轉換成 es5 的。

找到匹配的 href

首先,得讓 href 和當前地址處于同樣的目錄級別表示。比如 href 里是 admin/....,那當前頁面地址 window.location.pathname 也要處理成這樣,比如當前地址可能是 /admin/... ,要去掉第一個 /;或者當前地址是 /appname/admin/....,要去掉前面的 /appname/。的過來,處理每個 href 去適配當前地址的表示也是一樣的(其實這樣更合理,只是處理起來更麻煩)

const root = "/appname/";const menuUrls = $(".sidebar-menu a").map(function() {    return `${root}${$(this).attr("href")}`;
});

這會得到包含所有鏈接的 href 屬性的一個數組(jQuery 對象),我們可以遍歷這個數組來尋找匹配的 URL,不過找到 URL 之后再去找對應的 <a> 是件麻煩事,所以,其實應該生成一個 map(JS 對象)

const urlsMap = $(".sidebar-menu a")
    .toArray()
    .reduce((map, a) => {        const $a = $(a);        const url = `${root}${$a.attr("href")}`;
        map[url] = $a;        return map;
    }, {});

現在會得到一個 urlsMap,它是鍵是 URL,就是根據 href 處理而來的 URL。值是一個被 jQuery 封裝的 <a> 的 DOM 對象,一一對應的關系。

第一輪,精確匹配

let pathname = window.location.pathname;let foundUrl = Object.keys(urlsMap)
    .fitler(url => {        return url === pathname;
    })[0];

如果 foundUrl 是一個字符串,說明找到了,不然就是沒找到(因為 filter 的結果是個空數組,所以它的第 0 個元素是 undefined)。如果沒找到,再進行第二輪,這時候需要截掉 pathname 的最后一部分,這也是 pathname 和 foundUrl 用 let 申明而不用 const 申明的原因

第二輪,startsWith 匹配

if (!foundUrl) {    // 去掉最后一個 / 及其后的部分
    pathname = pathname.replace(/\/[^\/]+$/, "");
    foundUrl = Object.keys(urlsMap)
        .filter(url => {            return url.startsWith(pathnem);
        })[0];
}

如果這樣還沒找到,你還需要再往前找,你可以考慮用一個循環代替上面的 if 分支,注意循環的結束條件,不要搞成死循環了。最終也沒找到,那就拉倒吧。

如果找到了,那么 foundUrl 對應的那個 <a> 就是要高亮的。這個 <a> 很好找,因為我們建了映射表

const $a = urlsMap[foundUrl];

下面進行第二步

改變相關元素的狀態

這時候就需要找三個東西,<a> 外層的 <li>,再外層的 .treeview-menu 和再外層的 .treeview。如果都是直接父級關系,那很好找,依次取 .parent() 就好。如果不是,那就用 .closest(),下面的代碼假設是這種情況

$li = $a.closest("li");
$treeViewMenu = $li.closest(".treeview-menu");
$treeView = $treeViewMenu.closest(".treeview");

都找到了,改個類就容易了(因為 jQuery 的容錯性,完全不需要去判斷找沒找到,直接改就是了)

$li.addClass("active");
$treeViewMenu.addClass("menu_open");
$treeView.addClass("active");

搞定是搞定了,但是上面的代碼都是直接寫的,沒測試,所以自己小心著用。


查看完整回答
反對 回復 2018-10-29
  • 1 回答
  • 0 關注
  • 629 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號