WEBLOG
JavaScript > oo_lib.js
Create:
Update:
Category:JavaScriptoo_lib.js
Series:jQuery 独自プラグイン「oo_lib」
弊社で標準プラグインとして設置するjQueryプラグイン(独自)「oo_lib.js」。
その中の「navCurrent」を紹介します。
自動で、nav 内の現在位置にclass属性「current」を付与します。
画像は、現在「/service/a/?type=c」というパラメータ付きページが表示されている時にメニューのプルダウンが開かれた状態。
例えば、グローバルメニューでクラスが付与されるのは、上記の2か所になります。
全て独自開発です。
jQuery.fn.navCurrent = function (config) {
const opt = jQuery.extend(
{
ganv: true,
submenuCurrent: true,
submenuWrapClass: 'submenu_wrap'
},
config
);
let $links = [],
$tempLinks = [],
$link = {},
$navWap = $(this),
$navHome = $navWap.find('a[data-nav="home"]').not('a[data-navcurrent="false"]'),
currentHref,
run,
i;
// home
if ($navHome.length > 0) {
$links.push({
dom: $navHome,
link: removeDomain($navHome.attr('href')),
home: true,
sub: []
});
}
// home,false,sub以外抽出
$navWap
.find('a')
.not('a[data-nav="home"], a[data-navcurrent="false"], + + a')
.each(function () {
if ($(this).attr('href') !== undefined) {
$link = {};
$link.dom = $(this);
$link.link = removeDomain($(this).attr('href'));
$link.home = false;
$link.sub = [];
if ($(this).parent().hasClass(opt.submenuWrapClass)) {
$(this)
.next()
.find('a[href]')
.each(function () {
$link.sub.push($(this));
});
// hrefを文字列の長い順にsort *長いものほど階層が下
$link.sub.sort(function (a, b) {
return removeDomain(b.attr('href')).length - removeDomain(a.attr('href')).length;
});
}
$tempLinks.push($link);
}
});
// hrefを文字列の長い順にsort *長いものほど階層が下
$tempLinks.sort(function (a, b) {
return b.link.length - a.link.length;
});
$.merge($links, $tempLinks);
/* match判定 */
currentHref = removeDomain(location.href);
run = true;
// nav home判定
labelAll: for (let i = 0; i < $links.length; i++) {
if ($links[i].home) {
if (checkMatch(currentHref, $links[i].link)) {
$links[i].dom.addClass('current');
run = false;
break labelAll;
}
}
}
// submenu完全一致のみ判定
if (run) {
labelAll: for (i = 0; i < $links.length; i++) {
if (!$links[i].home && $links[i].sub.length > 0) {
for (let j = 0; j < $links[i].sub.length; j++) {
if (checkMatch(currentHref, removeDomain($links[i].sub[j].attr('href')))) {
if (opt.ganv) $links[i].dom.addClass('current');
if (opt.submenuCurrent) $links[i].sub[j].addClass('current');
run = false;
break labelAll;
}
}
}
}
}
// submenu前方一致判定
if (run) {
labelAll: for (i = 0; i < $links.length; i++) {
if (!$links[i].home && $links[i].sub.length > 0) {
for (j = 0; j < $links[i].sub.length; j++) {
if (checkPreMatch(currentHref, removeDomain($links[i].sub[j].attr('href')))) {
if (opt.ganv) $links[i].dom.addClass('current');
if (opt.submenuCurrent) $links[i].sub[j].addClass('current');
run = false;
break labelAll;
}
}
}
}
}
// nav完全一致判定
if (run) {
labelAll: for (i = 0; i < $links.length; i++) {
if (!$links[i].home && checkMatch(currentHref, removeDomain($links[i].link))) {
$links[i].dom.addClass('current');
run = false;
break labelAll;
}
}
}
// nav前方一致判定
if (run && opt.ganv) {
labelAll: for (i = 0; i < $links.length; i++) {
if (!$links[i].home && checkPreMatch(currentHref, removeDomain($links[i].link))) {
$links[i].dom.addClass('current');
run = false;
break labelAll;
}
}
}
/* func */
// gnav リンクを正規化した上で配列生成(homeリンク除く)
function removeDomain(href) {
if (href === undefined) {
return;
}
let m = href.match(/^(http)*s*:?\/\/[a-zA-Z0-9-.]+(.*)$/);
if (m) {
return m[2] === '' ? '/' : m[2];
} else {
return href;
}
}
// 前方一致
function checkPreMatch(string, pattern) {
if (string.indexOf(pattern) === 0) {
return true;
} else {
return false;
}
}
// 完全一致
function checkMatch(string, pattern) {
if (string === pattern) {
return true;
} else {
return false;
}
}
return this;
};
下記を記述すると .nav クラス属性の箇所での動作します。
$('.nav').navCurrent();
// オプション設定付き
$('.nav').navCurrent({
submenuCurrent: true,
ganv: true,
submenuWrapClass: 'submenu_wrap'
});
下記のオプション値が使用できます。
<ul class="nav">
<li><a href="/" data-nav="home">HOME</a></li>
<li class="submenu_wrap">
<a href="/service/">SERVICE</a>
<ul>
<li><a href="/service/">SERVICE</a></li>
<li><a href="/service/a/">A</a></li>
<li><a href="/service/a/?type=c">A-typeC</a></li>
<li><a href="/faq/">FAQ</a></li>
</ul>
</li>
<li><a href="/company/">COMPANY</a></li>
</ul>
※ 本サイトでも使用しています。
弊社のコーディングに合わせて作ったものですので、li li a の箇所など合わないマークアップがあるかもしれません。