-4
我使用了一個使用這個語句塊來顯示菜單的插件,現在我在角度js中使用它。如何將JavaScript函數轉換爲角度js?
(function(window) {
\t 'use strict';
\t var support = { animations : Modernizr.cssanimations },
\t \t animEndEventNames = { 'WebkitAnimation' : 'webkitAnimationEnd', 'OAnimation' : 'oAnimationEnd', 'msAnimation' : 'MSAnimationEnd', 'animation' : 'animationend' },
\t \t animEndEventName = animEndEventNames[ Modernizr.prefixed('animation') ],
\t \t onEndAnimation = function(el, callback) {
\t \t \t var onEndCallbackFn = function(ev) {
\t \t \t \t if(support.animations) {
\t \t \t \t \t if(ev.target != this) return;
\t \t \t \t \t this.removeEventListener(animEndEventName, onEndCallbackFn);
\t \t \t \t }
\t \t \t \t if(callback && typeof callback === 'function') { callback.call(); }
\t \t \t };
\t \t \t if(support.animations) {
\t \t \t \t el.addEventListener(animEndEventName, onEndCallbackFn);
\t \t \t }
\t \t \t else {
\t \t \t \t onEndCallbackFn();
\t \t \t }
\t \t };
\t function extend(a, b) {
\t \t for(var key in b) {
\t \t \t if(b.hasOwnProperty(key)) {
\t \t \t \t a[key] = b[key];
\t \t \t }
\t \t }
\t \t return a;
\t }
\t function MLMenu(el, options) {
\t \t this.el = el;
\t \t this.options = extend({}, this.options);
\t \t extend(this.options, options);
\t \t
\t \t // the menus (<ul>´s)
\t \t this.menus = [].slice.call(this.el.querySelectorAll('.menu__level'));
\t \t // index of current menu
\t \t this.current = 0;
\t \t this._init();
\t }
\t MLMenu.prototype.options = {
\t \t // show breadcrumbs
\t \t breadcrumbsCtrl : true,
\t \t // initial breadcrumb text
\t \t initialBreadcrumb : 'all',
\t \t // show back button
\t \t backCtrl : true,
\t \t // delay between each menu item sliding animation
\t \t itemsDelayInterval : 60,
\t \t // direction
\t \t direction : 'r2l',
\t \t // callback: item that doesn´t have a submenu gets clicked
\t \t // onItemClick([event], [inner HTML of the clicked item])
\t \t onItemClick : function(ev, itemName) { return false; }
\t };
\t MLMenu.prototype._init = function() {
\t \t // iterate the existing menus and create an array of menus, more specifically an array of objects where each one holds the info of each menu element and its menu items
\t \t this.menusArr = [];
\t \t var self = this;
\t \t this.menus.forEach(function(menuEl, pos) {
\t \t \t var menu = {menuEl : menuEl, menuItems : [].slice.call(menuEl.querySelectorAll('.menu__item'))};
\t \t \t self.menusArr.push(menu);
\t \t \t // set current menu class
\t \t \t if(pos === self.current) {
\t \t \t \t classie.add(menuEl, 'menu__level--current');
\t \t \t }
\t \t });
\t \t // create back button
\t \t if(this.options.backCtrl) {
\t \t \t this.backCtrl = document.createElement('button');
\t \t \t this.backCtrl.className = 'menu__back menu__back--hidden';
\t \t \t this.backCtrl.setAttribute('aria-label', 'Go back');
\t \t \t this.backCtrl.innerHTML = '<span class="icon icon--arrow-left"></span>';
\t \t \t this.el.insertBefore(this.backCtrl, this.el.firstChild);
\t \t }
\t \t
\t \t
\t \t // create breadcrumbs
\t \t if(self.options.breadcrumbsCtrl) {
\t \t \t this.breadcrumbsCtrl = document.createElement('nav');
\t \t \t this.breadcrumbsCtrl.className = 'menu__breadcrumbs';
\t \t \t this.el.insertBefore(this.breadcrumbsCtrl, this.el.firstChild);
\t \t \t // add initial breadcrumb
\t \t \t this._addBreadcrumb(0);
\t \t }
\t \t // event binding
\t \t this._initEvents();
\t };
\t MLMenu.prototype._initEvents = function() {
\t \t var self = this;
\t \t for(var i = 0, len = this.menusArr.length; i < len; ++i) {
\t \t \t this.menusArr[i].menuItems.forEach(function(item, pos) {
\t \t \t \t item.querySelector('a').addEventListener('click', function(ev) {
\t \t \t \t \t var submenu = ev.target.getAttribute('data-submenu'),
\t \t \t \t \t \t itemName = ev.target.innerHTML,
\t \t \t \t \t \t subMenuEl = self.el.querySelector('ul[data-menu="' + submenu + '"]');
\t \t \t \t \t // check if there's a sub menu for this item
\t \t \t \t \t if(submenu && subMenuEl) {
\t \t \t \t \t \t ev.preventDefault();
\t \t \t \t \t \t // open it
\t \t \t \t \t \t self._openSubMenu(subMenuEl, pos, itemName);
\t \t \t \t \t }
\t \t \t \t \t else {
\t \t \t \t \t \t // add class current
\t \t \t \t \t \t var currentlink = self.el.querySelector('.menu__link--current');
\t \t \t \t \t \t if(currentlink) {
\t \t \t \t \t \t \t classie.remove(self.el.querySelector('.menu__link--current'), 'menu__link--current');
\t \t \t \t \t \t }
\t \t \t \t \t \t classie.add(ev.target, 'menu__link--current');
\t \t \t \t \t \t
\t \t \t \t \t \t // callback
\t \t \t \t \t \t self.options.onItemClick(ev, itemName);
\t \t \t \t \t }
\t \t \t \t });
\t \t \t });
\t \t }
\t \t
\t \t // back navigation
\t \t if(this.options.backCtrl) {
\t \t \t this.backCtrl.addEventListener('click', function() {
\t \t \t \t self._back();
\t \t \t });
\t \t }
\t };
\t MLMenu.prototype._openSubMenu = function(subMenuEl, clickPosition, subMenuName) {
\t \t if(this.isAnimating) {
\t \t \t return false;
\t \t }
\t \t this.isAnimating = true;
\t \t
\t \t // save "parent" menu index for back navigation
\t \t this.menusArr[this.menus.indexOf(subMenuEl)].backIdx = this.current;
\t \t // save "parent" menu´s name
\t \t this.menusArr[this.menus.indexOf(subMenuEl)].name = subMenuName;
\t \t // current menu slides out
\t \t this._menuOut(clickPosition);
\t \t // next menu (submenu) slides in
\t \t this._menuIn(subMenuEl, clickPosition);
\t };
\t MLMenu.prototype._back = function() {
\t \t if(this.isAnimating) {
\t \t \t return false;
\t \t }
\t \t this.isAnimating = true;
\t \t // current menu slides out
\t \t this._menuOut();
\t \t // next menu (previous menu) slides in
\t \t var backMenu = this.menusArr[this.menusArr[this.current].backIdx].menuEl;
\t \t this._menuIn(backMenu);
\t \t // remove last breadcrumb
\t \t if(this.options.breadcrumbsCtrl) {
\t \t \t this.breadcrumbsCtrl.removeChild(this.breadcrumbsCtrl.lastElementChild);
\t \t }
\t };
\t MLMenu.prototype._menuOut = function(clickPosition) {
\t \t // the current menu
\t \t var self = this,
\t \t \t currentMenu = this.menusArr[this.current].menuEl,
\t \t \t isBackNavigation = typeof clickPosition == 'undefined' ? true : false;
\t \t // slide out current menu items - first, set the delays for the items
\t \t this.menusArr[this.current].menuItems.forEach(function(item, pos) {
\t \t \t item.style.WebkitAnimationDelay = item.style.animationDelay = isBackNavigation ? parseInt(pos * self.options.itemsDelayInterval) + 'ms' : parseInt(Math.abs(clickPosition - pos) * self.options.itemsDelayInterval) + 'ms';
\t \t });
\t \t // animation class
\t \t if(this.options.direction === 'r2l') {
\t \t \t classie.add(currentMenu, !isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight');
\t \t }
\t \t else {
\t \t \t classie.add(currentMenu, isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight'); \t
\t \t }
\t };
\t MLMenu.prototype._menuIn = function(nextMenuEl, clickPosition) {
\t \t var self = this,
\t \t \t // the current menu
\t \t \t currentMenu = this.menusArr[this.current].menuEl,
\t \t \t isBackNavigation = typeof clickPosition == 'undefined' ? true : false,
\t \t \t // index of the nextMenuEl
\t \t \t nextMenuIdx = this.menus.indexOf(nextMenuEl),
\t \t \t nextMenuItems = this.menusArr[nextMenuIdx].menuItems,
\t \t \t nextMenuItemsTotal = nextMenuItems.length;
\t \t // slide in next menu items - first, set the delays for the items
\t \t nextMenuItems.forEach(function(item, pos) {
\t \t \t item.style.WebkitAnimationDelay = item.style.animationDelay = isBackNavigation ? parseInt(pos * self.options.itemsDelayInterval) + 'ms' : parseInt(Math.abs(clickPosition - pos) * self.options.itemsDelayInterval) + 'ms';
\t \t \t // we need to reset the classes once the last item animates in
\t \t \t // the "last item" is the farthest from the clicked item
\t \t \t // let's calculate the index of the farthest item
\t \t \t var farthestIdx = clickPosition <= nextMenuItemsTotal/2 || isBackNavigation ? nextMenuItemsTotal - 1 : 0;
\t \t \t if(pos === farthestIdx) {
\t \t \t \t onEndAnimation(item, function() {
\t \t \t \t \t // reset classes
\t \t \t \t \t if(self.options.direction === 'r2l') {
\t \t \t \t \t \t classie.remove(currentMenu, !isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight');
\t \t \t \t \t \t classie.remove(nextMenuEl, !isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
\t \t \t \t \t }
\t \t \t \t \t else {
\t \t \t \t \t \t classie.remove(currentMenu, isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight');
\t \t \t \t \t \t classie.remove(nextMenuEl, isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
\t \t \t \t \t }
\t \t \t \t \t classie.remove(currentMenu, 'menu__level--current');
\t \t \t \t \t classie.add(nextMenuEl, 'menu__level--current');
\t \t \t \t \t //reset current
\t \t \t \t \t self.current = nextMenuIdx;
\t \t \t \t \t // control back button and breadcrumbs navigation elements
\t \t \t \t \t if(!isBackNavigation) {
\t \t \t \t \t \t // show back button
\t \t \t \t \t \t if(self.options.backCtrl) {
\t \t \t \t \t \t \t classie.remove(self.backCtrl, 'menu__back--hidden');
\t \t \t \t \t \t }
\t \t \t \t \t \t
\t \t \t \t \t \t // add breadcrumb
\t \t \t \t \t \t self._addBreadcrumb(nextMenuIdx);
\t \t \t \t \t }
\t \t \t \t \t else if(self.current === 0 && self.options.backCtrl) {
\t \t \t \t \t \t // hide back button
\t \t \t \t \t \t classie.add(self.backCtrl, 'menu__back--hidden');
\t \t \t \t \t }
\t \t \t \t \t // we can navigate again..
\t \t \t \t \t self.isAnimating = false;
\t \t \t \t });
\t \t \t }
\t \t }); \t
\t \t
\t \t // animation class
\t \t if(this.options.direction === 'r2l') {
\t \t \t classie.add(nextMenuEl, !isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
\t \t }
\t \t else {
\t \t \t classie.add(nextMenuEl, isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
\t \t }
\t };
\t MLMenu.prototype._addBreadcrumb = function(idx) {
\t \t if(!this.options.breadcrumbsCtrl) {
\t \t \t return false;
\t \t }
\t \t var bc = document.createElement('a');
\t \t bc.innerHTML = idx ? this.menusArr[idx].name : this.options.initialBreadcrumb;
\t \t this.breadcrumbsCtrl.appendChild(bc);
\t \t var self = this;
\t \t bc.addEventListener('click', function(ev) {
\t \t \t ev.preventDefault();
\t \t \t // do nothing if this breadcrumb is the last one in the list of breadcrumbs
\t \t \t if(!bc.nextSibling || self.isAnimating) {
\t \t \t \t return false;
\t \t \t }
\t \t \t self.isAnimating = true;
\t \t \t
\t \t \t // current menu slides out
\t \t \t self._menuOut();
\t \t \t // next menu slides in
\t \t \t var nextMenu = self.menusArr[idx].menuEl;
\t \t \t self._menuIn(nextMenu);
\t \t \t // remove breadcrumbs that are ahead
\t \t \t var siblingNode;
\t \t \t while (siblingNode = bc.nextSibling) {
\t \t \t \t self.breadcrumbsCtrl.removeChild(siblingNode);
\t \t \t }
\t \t });
\t };
\t window.MLMenu = MLMenu;
})(window);
和定製的Java腳本:
(function() {
\t var menuEl = document.getElementById('ml-menu');
\t \t \t mlmenu = new MLMenu(menuEl, {
\t \t \t \t // breadcrumbsCtrl : true, // show breadcrumbs
\t \t \t \t // initialBreadcrumb : 'all', // initial breadcrumb text
\t \t \t \t backCtrl : false, // show back button
\t \t \t \t // itemsDelayInterval : 60, // delay between each menu item sliding animation
\t \t \t \t onItemClick: loadDummyData // callback: item that doesn´t have a submenu gets clicked - onItemClick([event], [inner HTML of the clicked item])
\t \t \t });
\t \t //mobile menu toggle
\t \t var openMenuCtrl = document.querySelector('.action--open'),
\t \t \t closeMenuCtrl = document.querySelector('.action--close');
\t \t openMenuCtrl.addEventListener('click', openMenu);
\t \t closeMenuCtrl.addEventListener('click', closeMenu);
\t \t function openMenu() {
\t \t \t classie.add(menuEl, 'menu--open');
\t \t }
\t \t function closeMenu() {
\t \t \t classie.remove(menuEl, 'menu--open');
\t \t }
\t \t // simulate grid content loading
\t \t var gridWrapper = document.querySelector('.content');
\t \t function loadDummyData(ev, itemName) {
\t \t \t ev.preventDefault();
\t \t \t closeMenu();
\t \t \t gridWrapper.innerHTML = '';
\t \t \t classie.add(gridWrapper, 'content--loading');
\t \t \t setTimeout(function() {
\t \t \t \t classie.remove(gridWrapper, 'content--loading');
\t \t \t \t gridWrapper.innerHTML = '<ul class="products">' + dummyData[itemName] + '<ul>';
\t \t \t }, 700);
\t \t }
\t })();
我想下面這個自定義腳本的一部分轉變爲角JS。
mlmenu = new MLMenu(menuEl, {
\t \t \t \t // breadcrumbsCtrl : true, // show breadcrumbs
\t \t \t \t // initialBreadcrumb : 'all', // initial breadcrumb text
\t \t \t \t backCtrl : false, // show back button
\t \t \t \t // itemsDelayInterval : 60, // delay between each menu item sliding animation
\t \t \t \t onItemClick: loadDummyData // callback: item that doesn´t have a submenu gets clicked - onItemClick([event], [inner HTML of the clicked item])
\t \t \t });
我使用它,因爲這在角,但有錯誤。
$scope.menuEl = document.getElementById('ml-menu');
var menuEl = document.getElementById('ml-menu'),
mlmenu = new MLMenu(menuEl, {
// breadcrumbsCtrl : true, // show breadcrumbs
// initialBreadcrumb : 'all', // initial breadcrumb text
backCtrl: false, // show back button
// itemsDelayInterval : 60, // delay between each menu item sliding animation
onItemClick: $scope.loadDummyData // callback: item that doesn´t have a submenu gets clicked - onItemClick([event], [inner HTML of the clicked item])
});
我該怎麼辦呢?