PageSourceSearch

https://www.honda.co.jp/Nbox/common/includes/header/scripts/car-header.js

js honda.co.jp collected 2026-10-01 08:45:02 UTC 12,875 bytes, 313 lines download raw bytes

1(function() {
2	"use strict";
3
4class CarHeader {
5    constructor(content) {
6        if (!content)
7            return;
8        this.el = content;
9        this.headerInner = this.el.querySelector('.l-auto-local-header__inner');
10        this.headerBody = this.el.querySelector('.l-auto-local-header__body');
11        this.dropMenuParents = this.el.querySelectorAll('.js-header-dropmenu');
12        this.dropMenu = this.el.querySelectorAll('.js-header-dropmenu > a');
13        this.dropMenuLink = this.el.querySelectorAll('.js-header-dropmenu > div a');
14        this.currentMenu = this.el.querySelectorAll('.js-header-currentmenu');
15        this.headerCloseButton = this.el.querySelectorAll('.js-header-close');
16        this.accordionMenu = this.el.querySelectorAll('.js-header-sp-menu');
17
18        // PC/Tab判定用クラス
19        // カテゴリリンク
20        this.dropMenuParentAnchor = this.el.querySelectorAll('js-header-parent-anchor');
21
22        this.menuEventPc = this.dropMenuOpen.bind(this);
23        this.menuEventSp = this.accordionMenuOpen.bind(this);
24        this.menuAccEventSp = this.open.bind(this);
25        this.bg = this.el.querySelector('.l-auto-local-header__overlay');
26        this.init();
27    }
28    init() {
29        this.event();
30    }
31    event() {
32        // eventの付け替え
33        const mediaQuery = window.matchMedia('(max-width: 768px)');
34        mediaQuery.addListener(this.eventSet.bind(this));
35        this.eventSet(mediaQuery);
36
37        // 同画面内リンクの動作設定
38        this.linkOpen();
39
40        const urlArray = window.location.pathname.split('/');
41
42        if(urlArray.length === 3) {
43            // 第1階層の場合、TOPにカレント指定を追加
44            this.el.querySelector('.js-header-top').classList.add('current');
45        } else {
46            // カレント表示
47            this.currentSet();
48        }
49
50        // drop menuの閉じるボタン
51        this.headerCloseButton.forEach(el => {
52            el.addEventListener('click', event => {
53                event.preventDefault();
54                const parent = event.target.closest('.js-header-dropmenu');
55                if (parent) {
56                    const menuButton = parent.querySelector('.l-auto-local-header__nav__link');
57                    parent.classList.remove('is-active');
58                    menuButton.classList.remove('is-active');
59                    this.activeDropMenuIndex = undefined;
60                }
61                else {
62                    const body = document.querySelector('.l-auto-local-header__body');
63                    body.classList.remove('is-active');
64                    this.activeDropMenuIndex = undefined;
65                }
66                this.reset();
67            });
68        });
69        this.bg.addEventListener('click', event => {
70            if (document.documentElement.clientWidth > 768) {
71                const menuButton = this.el.querySelector('.js-header-dropmenu > a.is-active');
72                menuButton.classList.remove('is-active');
73                this.bg.classList.remove('is-active');
74                this.activeDropMenuIndex = undefined;
75            }
76            else {
77                this.menuButton.classList.toggle('is-active');
78                this.headerBody.classList.toggle('is-active');
79                this.bg.classList.remove('is-active');
80            }
81        });
82    }
83    eventSet(event) {
84        if (event.matches) {
85            // sp
86            this.dropMenu.forEach(el => {
87                el.removeEventListener('click', this.menuEventPc);
88                const parent = el.closest('.l-auto-local-header__nav__item');
89                parent.removeEventListener('mouseenter', this.menuEventPc);
90                parent.removeEventListener('mouseleave', this.menuEventPc);
91                el.addEventListener('click', this.menuEventSp);
92            });
93            this.accordionMenu.forEach(el => {
94                el.addEventListener('click', this.menuAccEventSp);
95            });
96        }
97        else {
98            // pc
99            this.dropMenu.forEach(el => {
100                const parent = el.closest('.l-auto-local-header__nav__item');
101
102                if(!this.isTablet()) {
103                    el.addEventListener('click', this.menuEventPc);
104                    // clickイベントとの重複を避けるため、タッチデバイスでのmouseenter時は処理をスキップ
105                    parent.addEventListener('mouseenter', this.menuEventPc);
106                    parent.addEventListener('mouseleave', this.menuEventPc);
107                } else {
108                    parent.addEventListener('mouseleave', this.menuEventPc);
109                    el.addEventListener('click', (event) => {
110                        if(!event.currentTarget.classList.contains('is-active')) {
111                            event.preventDefault();
112                        }
113                        this.menuEventPc(event);
114                    });
115                }
116                el.removeEventListener('click', this.menuEventSp);
117            });
118
119            // 青帯内リンクのイベント設定
120            this.dropMenuParentAnchor.forEach(el => {
121                el.addEventListener('click', (event) => {
122                    if(this.isTablet() && !this.dropMenu.classList.contains('is-active')) {
123                        // タッチデバイスかつ吹き出しが表示されていない場合、ドロップメニューを開く
124                        this.dropMenuOpen(event);
125                    }
126                });
127            });
128            this.accordionMenu.forEach(el => {
129                el.removeEventListener('click', this.menuAccEventSp);
130            });
131        }
132        this.reset();
133    }
134    currentSet() {
135        for(let i = 0; i < this.dropMenu.length; i++) {
136            if(this.currentCheck(this.dropMenu[i])) {
137                this.dropMenu[i].classList.add('current');
138                break;
139            }
140        }
141
142        for(let i = 0; i < this.currentMenu.length; i++) {
143            if(this.currentCheck(this.currentMenu[i])) {
144                this.currentMenu[i].classList.add('current');
145                break;
146            }
147        }
148    }
149    currentCheck(target) {
150        const urlArray = window.location.pathname.split('/');
151
152        if(!target.dataset.subdir) { return false; }
153        // カレント対応したいURLのパスを抽出
154        // ,区切りで複数ディレクトリを対象に取ることも可(Specialなどの対応用)
155        const subdirArray = target.dataset.subdir.replace(' ', '').split(',');
156
157        for(let j = 0; j < subdirArray.length; j++) {
158            // data-subdir内の文字列とpathが一致する場合、カレント判定
159            if(urlArray.indexOf(subdirArray[j]) > -1) {
160                return true;
161            }
162        }
163
164        // カレントなしならfalse
165        return false;
166    }
167    isTablet() {
168        // タッチデバイスかチェック
169        return ('ontouchstart' in window) && ('orientation' in window);
170    }
171    reset() {
172        this.dropMenu.forEach(el => {
173            el.classList.remove('is-active');
174            el.classList.remove('is-open');
175        });
176        this.dropMenuParents.forEach(el => {
177            el.classList.remove('is-active');
178        });
179        this.accordionMenu.forEach(el => {
180            el.classList.remove('is-active');
181        });
182        this.headerBody.classList.remove('is-active');
183        this.bg.classList.remove('is-active');
184    }
185    dropMenuOpen(event) {
186        const target = event.currentTarget;
187        const index = event.type === 'mouseenter' || event.type === 'mouseleave'
188            ? Array.prototype.indexOf.call(this.dropMenuParents, target)
189            : Array.prototype.indexOf.call(this.dropMenu, target);
190        if (event.type === 'mouseenter') {
191            this.dropMenu.forEach(el => {
192                el.classList.remove('is-active');
193            });
194        }
195        if (typeof this.activeDropMenuIndex !== 'undefined' &&
196            this.activeDropMenuIndex !== index) {
197            this.dropMenu
198                .item(this.activeDropMenuIndex)
199                .classList.remove('is-active');
200        }
201        target.classList.toggle('is-active');
202        this.activeDropMenuIndex = target.classList.contains('is-active')
203            ? index
204            : undefined;
205        if (event.type === 'mouseleave') {
206            target.classList.remove('is-active');
207        }
208        if (event.type === 'mouseenter' || event.type === 'mouseleave') {
209            if (this.dropMenu
210                .item(this.activeDropMenuIndex)
211                .classList.contains('is-active')) {
212                return;
213            }
214        }
215        if (target.classList.contains('is-active')) {
216            this.bg.classList.add('is-active');
217        }
218        else {
219            this.bg.classList.remove('is-active');
220        }
221    }
222    accordionMenuOpen(event) {
223        event.preventDefault();
224        const target = event.currentTarget;
225        target.classList.toggle('is-active');
226        this.activeDropMenuIndex = Array.prototype.indexOf.call(this.dropMenu, target);
227    }
228    open(event) {
229        event.preventDefault();
230        const target = event.target;
231        target.classList.toggle('is-active');
232        this.headerBody.classList.toggle('is-active');
233        this.bg.classList.toggle('is-active');
234    }
235    linkOpen(){
236        this.dropMenuLink.forEach(el => {
237            const href = el.getAttribute('href');
238            if(!href) {
239                return;
240            }
241            const locationPath = location.pathname + location.search;
242            // パス+クエリの文字列で同ページか判定
243            if(href.split('#')[0] == locationPath) {
244                el.addEventListener('click', event => {
245                    const hash = href.split('#')[1];
246                    const targetElement = document.querySelector('#' + hash);
247
248                    if(targetElement) {
249                        event.preventDefault();
250
251                        const header = document.querySelector('.l-auto-local-header');
252                        const subMenu = document.querySelector('.c-box-link__base');              
253                        const headerH = header ? header.clientHeight : 0;
254                        const subMenuH = subMenu ? subMenu.clientHeight : 0;
255                        const adjustPosition = 10;
256                        const targetPosition = window.pageYOffset +
257                        targetElement.getBoundingClientRect().top -
258                        headerH -
259                        subMenuH -
260                        adjustPosition;
261            
262                        window.scrollTo(0, targetPosition);
263
264                        this.reset();
265                    }
266                });
267            }
268        });
269    }
270}
271
272var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
273    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
274    return new (P || (P = Promise))(function (resolve, reject) {
275        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
276        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
277        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
278        step((generator = generator.apply(thisArg, _arguments || [])).next());
279    });
280};
281
282(function () {
283    let header;
284    class InitHeader {
285        constructor() {
286            this.url = '/Nbox/common/includes/header/index.html';
287            this.targetEl = document.getElementById('l-auto-local-header');
288            this.init();
289        }
290        init() {
291            return __awaiter(this, void 0, void 0, function* () {
292                const html = yield fetch(this.url)
293                    .then(res => res.text())
294                    .then(text => {
295                    const html = new DOMParser().parseFromString(text, 'text/html');
296                    const targetHtml = html.querySelector('body').innerHTML;
297                    return targetHtml;
298                });
299                this.targetEl.innerHTML = html;
300                header = new CarHeader(this.targetEl);
301            });
302        }
303    }
304    new InitHeader();
305
306    window.addEventListener('pageshow', function (event) {
307        if(header) {
308            header.reset();
309        }
310    });
311})();
312
313})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.