【发布时间】:2016-04-07 22:58:50
【问题描述】:
我正在制作的个人网站的首页有这样的设计:
您单击相应的图标,它会展开以显示信息。我经历了另外两个没有成功的设计,但包含了类似的动画。在每次迭代后修改 JS 后,我意识到我是:
- 遇到冗余代码位
- 开始考虑将来添加更多选项卡/部分的可能性(我可能需要扩展代码)
这引导我开始'通用化'我的代码。所以制作像'handleHorizontalTabs'或'handleVerticalTabs'这样的功能而不是'handleGamesTab'或'handlePhotographyTab'这样可以避免我为摄影选项卡编写一个全新的功能,它与游戏选项卡只有一个css属性不同。所以我在想,那么我需要传入一个对象而不是一个确切的 ID。然后我创建了一些对象文字来存储它们各自的属性。创建像这样的中性动画函数(至少在我的情况下)的问题是我必须定义函数中可以使用的每个属性即使它没有被使用。 在滚动到完整代码之前考虑一下这个 sn-p:
if (active){
// Only animate horizontally
$(elemToAnimate.ID).animate({
width: elemToAnimate.ExpandedWidth,
left: elemToAnimate.ExpandedLeft,
right: elemToAnimate.ExpandedRight
}, animateDuration)
}
我可能不需要在制作动画时更改 say,'left' 属性。但是因为这是一个通用功能,所以它不知道。所以,在我的对象文字中,我仍然必须定义它(它只是原始值)。我确实注意到(我没有改变游戏部分,所以你可以看到这一点)如果我只是把它从文字中去掉,它就会被标记为 undefined 并且对动画没有影响。我可以这样做,但我认为这不是一个好习惯。另外,任何阅读我的代码的人都会问该属性在哪里。
我的问题有两个:
- 在考虑应用的可扩展性时,我应该以编程方式考虑什么?
- 如何清理/优化此代码?
代码:
https://jsfiddle.net/rc6wnsst/ (PS 未优化浏览器;如果可以,请使用 Mozilla)
$(document).ready(function() {
// Definitions
//Define object literals
var aboutmeSection = {id: '#aboutme-section', get ID() {return this.id;},
selector: '#person-icon', get Selector() {return this.selector;},
origWidth: $('#aboutme-section').css('width'), get OrigWidth() {return this.origWidth;},
origLeft: $('#aboutme-section').css('left'), get OrigLeft() {return this.origLeft;},
origRight: 'auto', get OrigRight() {return this.origRight;},
origHeight: $('#aboutme-section').css('height'), get OrigHeight() {return this.origHeight;},
origTop: $('#aboutme-section').css('top'), get OrigTop() {return this.origTop;},
origBottom: $('#aboutme-section').css('bottom'), get OrigBottom() {return this.origBottom;},
expandedWidth: '65%', get ExpandedWidth() {return this.expandedWidth;},
expandedLeft: $('#aboutme-section').css('left'), get ExpandedLeft() {return this.expandedLef;},
expandedRight: $('#aboutme-section').css('right'), get ExpandedRight() {return this.expandedRight;},
expandedHeight: '450px', get ExpandedHeight() {return this.expandedHeight;},
expandedTop: '65%', get ExpandedTop() {return this.expandedTop;},
expandedBottom: $('#aboutme-section').css('bottom'), get ExpandedBottom() {return this.expandedBottom;}};
var photographySection = {id: '#photography-tab', get ID() {return this.id;},
selector: '#camera-icon', get Selector() {return this.selector;},
origWidth: $('#photography-tab').css('width'), get OrigWidth() {return this.origWidth;},
origLeft: 'auto', get OrigLeft() {return this.origLeft;},
origRight: $('#photography-tab').css('right'), get OrigRight() {return this.origRight;},
expandedWidth: '40%', get ExpandedWidth() {return this.expandedWidth;},
expandedLeft: 'auto', get ExpandedLeft() {return this.expandedLeft;},
expandedRight: $('#photography-tab').css('right'), get ExpandedRight() {return this.expandedRight;}};
var gamesSection = {id: '#games-tab', get ID() {return this.id;},
selector: '#gamepad-icon', get Selector() {return this.selector;},
origWidth: $('#games-tab').css('width'), get OrigWidth() {return this.origWidth;},
origLeft: $('#games-tab').css('left'), get OrigLeft() {return this.origLeft;},
expandedWidth: '40%', get ExpandedWidth() {return this.expandedWidth;}};
处理程序
// Handles aboutme section functionality
function handleAboutMeSection(elemToAnimate, selectedElem, active, animateDuration=500, fadeInDuration=500, fadeOutDuration=250){
// First click
if (active){
// Animate vertically first
$(elemToAnimate.ID).animate({height: elemToAnimate.ExpandedHeight,
top: elemToAnimate.ExpandedTop,
bottom: elemToAnimate.OrigBottom}, animateDuration);
// Animate horizontally second
$(elemToAnimate.ID).animate({width: elemToAnimate.ExpandedWidth,
left: elemToAnimate.ExpandedLeft,
right: elemToAnimate.ExpandedRight}, animateDuration)
// Fade in content and remove active class
$(elemToAnimate.ID).find(".content").fadeIn(fadeInDuration);
$(selectedElem).removeClass('active');
// Second click
} else {
// Fade out content
$(elemToAnimate.ID).find(".content").fadeOut(fadeOutDuration, function(){
// Animate horizontally first
$(elemToAnimate.ID).animate({width: elemToAnimate.OrigWidth,
left: elemToAnimate.OrigLeft,
right: elemToAnimate.OrigRight}, animateDuration);
// Animate vertically second
$(elemToAnimate.ID).animate({height: elemToAnimate.OrigHeight,
top: elemToAnimate.OrigTop,
bottom: elemToAnimate.OrigBottom}, animateDuration)
});
// Add active class back in
$(selectedElem).addClass('active');
}
}
//Handles photography tab functionality
function handleTabs(elemToAnimate, selectedElem, active, animateDuration=500, fadeInDuration=500, fadeOutDuration=250){
// First click
if (active){
// Only animate horizontally
$(elemToAnimate.ID).animate({width: elemToAnimate.ExpandedWidth,
left: elemToAnimate.ExpandedLeft,
right: elemToAnimate.ExpandedRight}, animateDuration)
// Fade in content and remove active class
$(elemToAnimate.ID).find(".content").fadeIn(fadeInDuration);
$(selectedElem).removeClass('active');
// Second click
} else {
// Fade out content and only animate horizontally
$(elemToAnimate.ID).find(".content").fadeOut(fadeOutDuration, function(){
$(elemToAnimate.ID).animate({width: elemToAnimate.OrigWidth,
left: elemToAnimate.OrigLeft,
right: elemToAnimate.OrigRight}, animateDuration);
});
// Add active class back in
$(selectedElem).addClass('active');
}
}
主要
//Hide content initially
$(".content").hide();
//Handle click events
$(".image").click(function() {
//On first click
if ($(this).hasClass("active")) {
switch($(this).attr('id')) {
case 'person-icon':
handleAboutMeSection(aboutmeSection, aboutmeSection.Selector, true);
break;
case 'gamepad-icon':
handleTabs(gamesSection, gamesSection.Selector, true);
break;
case 'camera-icon':
handleTabs(photographySection, photographySection.Selector, true);
break;
default:
break;
}
// On second click
} else {
switch($(this).attr('id')) {
case 'person-icon':
handleAboutMeSection(aboutmeSection, aboutmeSection.Selector, false);
break;
case 'gamepad-icon':
handleTabs(gamesSection, gamesSection.Selector, false);
break;
case 'camera-icon':
handleTabs(photographySection, photographySection.Selector, false);
break;
default:
break;
}
}
});
});
【问题讨论】:
-
听起来像是一个属于Code Review的问题
标签: javascript jquery performance animation optimization