gpt4 book ai didi

javascript - 触发方法定义在 javascript 对象中,但在对象本身之外

转载 作者:行者123 更新时间:2023-11-28 00:27:10 25 4
gpt4 key购买 nike

我怀疑我的问题可能有点迟钝,我很抱歉。这是我想要实现的目标:

我正在使用这个multi-level push menu ,而且开箱即用,效果很好。但是,我希望在提交并关闭模式后关闭多级菜单。我很难弄清楚如何触发此菜单关闭。

那么,我们来看一些代码。首先,运行菜单本身的 Javascript。

mlPushMenu.prototype = {
defaults : {
// overlap: there will be a gap between open levels
// cover: the open levels will be on top of any previous open level
type : 'overlap', // overlap || cover
// space between each overlaped level
levelSpacing : 40,
// classname for the element (if any) that when clicked closes the current level
backClass : 'mp-back'
},
_init : function() {
// if menu is open or not
this.open = false;
// level depth
this.level = 0;
// the moving wrapper
this.wrapper = document.getElementById( 'mp-pusher' );
// the mp-level elements
this.levels = Array.prototype.slice.call( this.el.querySelectorAll( 'div.mp-level' ) );
// save the depth of each of these mp-level elements
var self = this;
this.levels.forEach( function( el, i ) { el.setAttribute( 'data-level', getLevelDepth( el, self.el.id, 'mp-level' ) ); } );
// the menu items
this.menuItems = Array.prototype.slice.call( this.el.querySelectorAll( 'li' ) );
// if type == "cover" these will serve as hooks to move back to the previous level
this.levelBack = Array.prototype.slice.call( this.el.querySelectorAll( '.' + this.options.backClass ) );
// event type (if mobile use touch events)
this.eventtype = mobilecheck() ? 'touchstart' : 'click';
// add the class mp-overlap or mp-cover to the main element depending on options.type
classie.add( this.el, 'mp-' + this.options.type );
// initialize / bind the necessary events
this._initEvents();
},
_initEvents : function() {
var self = this;

// the menu should close if clicking somewhere on the body
var bodyClickFn = function( el ) {
self._resetMenu();
el.removeEventListener( self.eventtype, bodyClickFn );
};

// open (or close) the menu
this.trigger.addEventListener( this.eventtype, function( ev ) {
ev.stopPropagation();
ev.preventDefault();
if( self.open ) {
self._resetMenu();
}
else {
self._openMenu();
// the menu should close if clicking somewhere on the body (excluding clicks on the menu)
document.addEventListener( self.eventtype, function( ev ) {
if( self.open && !hasParent( ev.target, self.el.id ) ) {
bodyClickFn( this );
}
} );
}
} );

// opening a sub level menu
this.menuItems.forEach( function( el, i ) {
// check if it has a sub level
var subLevel = el.querySelector( 'div.mp-level' );
if( subLevel ) {
el.querySelector( 'a' ).addEventListener( self.eventtype, function( ev ) {
ev.preventDefault();
var level = closest( el, 'mp-level' ).getAttribute( 'data-level' );
if( self.level <= level ) {
ev.stopPropagation();
classie.add( closest( el, 'mp-level' ), 'mp-level-overlay' );
self._openMenu( subLevel );
}
} );
}
} );

// closing the sub levels :
// by clicking on the visible part of the level element
this.levels.forEach( function( el, i ) {
el.addEventListener( self.eventtype, function( ev ) {
ev.stopPropagation();
var level = el.getAttribute( 'data-level' );
if( self.level > level ) {
self.level = level;
self._closeMenu();
}
} );
} );

// by clicking on a specific element
this.levelBack.forEach( function( el, i ) {
el.addEventListener( self.eventtype, function( ev ) {
ev.preventDefault();
var level = closest( el, 'mp-level' ).getAttribute( 'data-level' );
if( self.level <= level ) {
ev.stopPropagation();
self.level = closest( el, 'mp-level' ).getAttribute( 'data-level' ) - 1;
self.level === 0 ? self._resetMenu() : self._closeMenu();
}
} );
} );
},
_openMenu : function( subLevel ) {
// increment level depth
++this.level;

// move the main wrapper
var levelFactor = ( this.level - 1 ) * this.options.levelSpacing,
translateVal = this.options.type === 'overlap' ? this.el.offsetWidth + levelFactor : this.el.offsetWidth;

this._setTransform( 'translate3d(' + translateVal + 'px,0,0)' );

if( subLevel ) {
// reset transform for sublevel
this._setTransform( '', subLevel );
// need to reset the translate value for the level menus that have the same level depth and are not open
for( var i = 0, len = this.levels.length; i < len; ++i ) {
var levelEl = this.levels[i];
if( levelEl != subLevel && !classie.has( levelEl, 'mp-level-open' ) ) {
this._setTransform( 'translate3d(-100%,0,0) translate3d(' + -1*levelFactor + 'px,0,0)', levelEl );
}
}
}
// add class mp-pushed to main wrapper if opening the first time
if( this.level === 1 ) {
classie.add( this.wrapper, 'mp-pushed' );
this.open = true;
}
// add class mp-level-open to the opening level element
classie.add( subLevel || this.levels[0], 'mp-level-open' );
},
// close the menu
_resetMenu : function() {
this._setTransform('translate3d(0,0,0)');
this.level = 0;
// remove class mp-pushed from main wrapper
classie.remove( this.wrapper, 'mp-pushed' );
this._toggleLevels();
this.open = false;
},
// close sub menus
_closeMenu : function() {
var translateVal = this.options.type === 'overlap' ? this.el.offsetWidth + ( this.level - 1 ) * this.options.levelSpacing : this.el.offsetWidth;
this._setTransform( 'translate3d(' + translateVal + 'px,0,0)' );
this._toggleLevels();
},
// translate the el
_setTransform : function( val, el ) {
el = el || this.wrapper;
el.style.WebkitTransform = val;
el.style.MozTransform = val;
el.style.transform = val;
},
// removes classes mp-level-open from closing levels
_toggleLevels : function() {
for( var i = 0, len = this.levels.length; i < len; ++i ) {
var levelEl = this.levels[i];
if( levelEl.getAttribute( 'data-level' ) >= this.level + 1 ) {
classie.remove( levelEl, 'mp-level-open' );
classie.remove( levelEl, 'mp-level-overlay' );
}
else if( Number( levelEl.getAttribute( 'data-level' ) ) == this.level ) {
classie.remove( levelEl, 'mp-level-overlay' );
}
}
}
}

我想调用的方法是_resetMenu。我已经尝试了几种方法。主要尝试触发打开菜单的按钮的单击事件:

<a href="#" id="trigger" class="show-root-menu"><i class="fa fa-reorder"></i></a>

但是:

$('#trigger').trigger('click');

未按预期工作。我希望这会被解雇:

// open (or close) the menu
this.trigger.addEventListener( this.eventtype, function( ev ) {
ev.stopPropagation();
ev.preventDefault();
if( self.open ) {
self._resetMenu();
}
else {
self._openMenu();
// the menu should close if clicking somewhere on the body (excluding clicks on the menu)
document.addEventListener( self.eventtype, function( ev ) {
if( self.open && !hasParent( ev.target, self.el.id ) ) {
bodyClickFn( this );
}
} );
}
} );

在本例中,this.eventtype 为“click”。

我怀疑这可能与此功能如何使用对象进行编码有关。虽然我有不错的 Javascript 技能,但我还没有太多接触过以这种方式使用它。

我正在实例化菜单:

new mlPushMenu(document.getElementById('mp-menu'), document.getElementById('trigger'));

我意识到我可以提取这个方法,但这似乎违反了一些一般的最佳实践。

如有任何建议,我们将不胜感激!

最佳答案

您不能按原样使用此模块来执行此操作。它支持的唯一事件类型是“click”和“touchstart”及其 mobilecheck()方法确定它使用两者中的哪一个。

您要么必须假装点击触发元素,要么必须修改此模块。您可以使用 .click() 来执行此操作DOM 元素的方法。 .trigger.click()可能不会这么做;您可能最好只获取元素(通过 $('#trigger')document.getElementById() ),然后调用它的 .click() 方法。

我刚刚在 Chrome 中使用 <a> 尝试过此操作有风格display:none它遵循链接,因此它可能适用于另一个隐藏元素集来触发。虽然有点 hacky,但可能比更改模块更好。

关于javascript - 触发方法定义在 javascript 对象中,但在对象本身之外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29380408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com