我构建了一个自定义元素,它是一个汉堡包按钮,现在我正在处理侧面导航。在这个侧面导航中,我想使用我的汉堡包按钮,所以我尝试导出HCHamburger
与我的按钮对应的类并将其导入我的SideNav
类中。这个想法是在侧导航打开时为我的按钮位置设置动画。我尝试扩展我的SideNav
课程,HCHamburger
但出现以下错误:Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
我的 HChambuger 类看起来像这样:
'use strict';
export default class HCHamburger extends HTMLElement {
get menuButton() {
if (!this._menuButton) {
this._menuButton = this.querySelector('.hamburger-menu');
}
return this._menuButton;
}
get bar() {
if (!this._bar) {
this._bar = this.querySelector('.bar');
}
return this._bar;
}
attachedCallback() {
this.menuButton.addEventListener('click', _ => {
const sideNavContainerEl = document.querySelector('.js-side-nav-container');
this.bar.classList.toggle("animate");
if (sideNavContainerEl.getAttribute('nav-opened') == 'false') {
this.openMenuButton(sideNavContainerEl);
} else {
this.closeMenuButton(sideNavContainerEl);
}
});
}
sayHello() {
console.log('TOTO');
}
openMenuButton(sideNavContainerEl) {
this.style.transform = `translateX(${sideNavContainerEl.offsetWidth}px)`;
}
closeMenuButton(sideNavContainerEl) {
this.style.transform = `translateX(0px)`;
}
}
document.registerElement('hc-hamburger', HCHamburger);
我的 SideNav 类是这样的:
'use strict';
import Detabinator from './detabinator.js';
import HCHamburger from './hamburger.js';
class SideNav extends HCHamburger {
constructor () {
super();
this.toggleMenuEl = document.querySelector('.js-menu');
this.showButtonEl = document.querySelector('.js-menu-show');
this.hideButtonEl = document.querySelector('.js-menu-hide');
this.sideNavEl = document.querySelector('.js-side-nav');
this.sideNavContainerEl = document.querySelector('.js-side-nav-container');
// Control whether the container's children can be focused
// Set initial state to inert since the drawer is offscreen
this.detabinator = new Detabinator(this.sideNavContainerEl);
this.detabinator.inert = true;
this.toggleSideNav = this.toggleSideNav.bind(this);
this.showSideNav = this.showSideNav.bind(this);
this.hideSideNav = this.hideSideNav.bind(this);
this.blockClicks = this.blockClicks.bind(this);
this.onTouchStart = this.onTouchStart.bind(this);
this.onTouchMove = this.onTouchMove.bind(this);
this.onTouchEnd = this.onTouchEnd.bind(this);
this.onTransitionEnd = this.onTransitionEnd.bind(this);
this.update = this.update.bind(this);
this.startX = 0;
this.currentX = 0;
this.touchingSideNav = false;
this.supportsPassive = undefined;
this.addEventListeners();
}
// apply passive event listening if it's supported
applyPassive () {
if (this.supportsPassive !== undefined) {
return this.supportsPassive ? {passive: true} : false;
}
// feature detect
let isSupported = false;
try {
document.addEventListener('test', null, {get passive () {
isSupported = true;
}});
} catch (e) { }
this.supportsPassive = isSupported;
return this.applyPassive();
}
addEventListeners () {
this.toggleMenuEl.addEventListener('click', this.toggleSideNav);
this.sideNavEl.addEventListener('click', this.hideSideNav);
this.sideNavContainerEl.addEventListener('click', this.blockClicks);
this.sideNavEl.addEventListener('touchstart', this.onTouchStart, this.applyPassive());
this.sideNavEl.addEventListener('touchmove', this.onTouchMove, this.applyPassive());
this.sideNavEl.addEventListener('touchend', this.onTouchEnd);
}
onTouchStart (evt) {
if (!this.sideNavEl.classList.contains('side-nav--visible'))
return;
this.startX = evt.touches[0].pageX;
this.currentX = this.startX;
this.touchingSideNav = true;
requestAnimationFrame(this.update);
}
onTouchMove (evt) {
if (!this.touchingSideNav)
return;
this.currentX = evt.touches[0].pageX;
const translateX = Math.min(0, this.currentX - this.startX);
if (translateX < 0) {
evt.preventDefault();
}
}
onTouchEnd (evt) {
if (!this.touchingSideNav)
return;
this.touchingSideNav = false;
const translateX = Math.min(0, this.currentX - this.startX);
this.sideNavContainerEl.style.transform = '';
if (translateX < 0) {
this.hideSideNav();
}
}
update () {
if (!this.touchingSideNav)
return;
requestAnimationFrame(this.update);
const translateX = Math.min(0, this.currentX - this.startX);
this.sideNavContainerEl.style.transform = `translateX(${translateX}px)`;
}
blockClicks (evt) {
evt.stopPropagation();
}
onTransitionEnd (evt) {
this.sideNavEl.classList.remove('side-nav--animatable');
this.sideNavEl.removeEventListener('transitionend', this.onTransitionEnd);
}
showSideNav () {
this.sideNavEl.classList.add('side-nav--animatable');
this.sideNavEl.classList.add('side-nav--visible');
this.detabinator.inert = false;
this.sideNavEl.addEventListener('transitionend', this.onTransitionEnd);
}
hideSideNav () {
this.sideNavEl.classList.add('side-nav--animatable');
this.sideNavEl.classList.remove('side-nav--visible');
this.detabinator.inert = true;
this.sideNavEl.addEventListener('transitionend', this.onTransitionEnd);
}
toggleSideNav () {
if (this.sideNavContainerEl.getAttribute('nav-opened') == 'true') {
this.hideSideNav();
this.sideNavContainerEl.setAttribute('nav-opened', 'false');
} else {
this.showSideNav();
this.sideNavContainerEl.setAttribute('nav-opened', 'true');
}
}
}
new SideNav();
我正在使用 webpack 来构建我的 JS 代码,这可能是我的问题的原因......我尝试了不同的方法来导入/导出,但没有任何效果。
我想只导出我需要的方法,但它也不起作用。
谢谢