请教面向对象(oo)的问题(回帖都有分) 本帖最后由 hejunheng 于 2011-12-13 14:05:04 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 自己修改了,但觉得不对,还请帮助,指出function Tip(contents,titleA,slef){ this.contents = contents, this.titleA=titleA, this.body=$('body'); this.show=function(){ this.contents.hide(); this.titleA.removeClass("on"); var htmlHidth=document.documentElement.clientHeight, scrollTop = document.body.scrollTop || document.documentElement.scrollTop, me = slef, width = me.outerWidth(true), height = me.outerHeight(true), layer = me.parent().parent().find(this.contents), layerHeight=0, position = me.position(); me.addClass('on'); layer.css({ display: 'block', visibility: 'hidden' }); layerHeight=layer.outerHeight(true); if(((htmlHidth+scrollTop-position.top)-20)>layerHeight) { layer.css({ "top": position.top - 5 + "px", "left": (position.left + width + 10) + "px", visibility: 'visible' }); } else { layer.css({ "top": position.top-layerHeight+height+5 + "px", "left": (position.left + width+10) + "px", visibility: 'visible' }); } }; }调用方式$(function(){ var contents=$('.tipsContent'),titleA=$('.title a'); $('.title a').click(function(e){ var tip=new Tip(contents,titleA,$(this)); e.stopPropagation(); tip.show(); }) $('body').click(function(){ contents.hide(); titleA.removeClass('on'); }); $('.tipsContent').click(function(e) { e.stopPropagation(); })}) 要是将show写到prototype中就更完美了 function Tip(contents,titleA,slef){ this.contents = contents, this.titleA=titleA, this.me=slef; this.show=function(){ this.contents.hide(); this.titleA.removeClass("on"); var htmlHeight=document.documentElement.clientHeight, scrollTop = document.body.scrollTop || document.documentElement.scrollTop, width = this.me.outerWidth(true), height = this.me.outerHeight(true), layer = this.me.parent().parent().find(this.contents), layerHeight=0, position = this.me.position(); this.me.addClass('on'); layer.css({ display: 'block', visibility: 'hidden' }); layerHeight=layer.outerHeight(true); if(((htmlHeight+scrollTop-position.top)-20)>layerHeight) { layer.css({ "top": position.top - 5 + "px", "left": (position.left + width + 10) + "px", visibility: 'visible' }); } else { layer.css({ "top": position.top-layerHeight+height+5 + "px", "left": (position.left + width+10) + "px", visibility: 'visible' }); } }; }看起来是构造函数模式,但内部看起来有点糟,有没有优化的余地,拜托了~~~我又修改了一下我解释下下:这个函数的作用是点击列表标题,显示浮动的弹出框.让我特别纠结的是在调用时函数时的这两个事件,应该放在Tip里面吗?$(function(){ var contents=$('.tipsContent'),titleA=$('.title a'); $('.title a').click(function(e){ var tip=new Tip(contents,titleA,$(this)); e.stopPropagation(); tip.show(); }) $('body').click(function(){ contents.hide(); titleA.removeClass('on'); }); $('.tipsContent').click(function(e) { e.stopPropagation(); })}) function Tip(contents,titleA,slef){ this.contents = contents, this.titleA=titleA, this.me=slef; }Tip.prototype={ constructor:Tip, show:function(){ this.contents.hide(); this.titleA.removeClass("on"); var htmlHeight=document.documentElement.clientHeight, scrollTop = document.body.scrollTop || document.documentElement.scrollTop, width = this.me.outerWidth(true), height = this.me.outerHeight(true), layer = this.me.parent().parent().find(this.contents), layerHeight=0, position = this.me.position(); this.me.addClass('on'); layer.css({ display: 'block', visibility: 'hidden' }); layerHeight=layer.outerHeight(true); if(((htmlHeight+scrollTop-position.top)-20)>layerHeight) { layer.css({ "top": position.top - 5 + "px", "left": (position.left + width + 10) + "px", visibility: 'visible' }); } else { layer.css({ "top": position.top-layerHeight+height+5 + "px", "left": (position.left + width+10) + "px", visibility: 'visible' }); } }}调用方式$(function(){ var contents=$('.tipsContent'),titleA=$('.title a'); $('.title a').click(function(e){ var tip=new Tip(contents,titleA,$(this)); e.stopPropagation(); tip.show(); }) $('body').click(function(){ contents.hide(); titleA.removeClass('on'); }); $('.tipsContent').click(function(e) { e.stopPropagation(); })})同楼上,我觉得有结构问题,有优化的方法吗? 如果做成oo形式,个人意见:1、构造函数参数用对象形式比较好。2、可为这个类写个放置全局变量的沙盒,采用set和get方法来存取全局变量。可以避免采用this.xxx来取全局变量。3、这个类在一个页面里可能不止被实例化一次,所以尽可能把共用方法抽象出来放到prototype里面去。以免实例化时存在多分方法的拷贝。4、如果要封装,调用方法我觉得过于复杂了。尽量只要new一次,或者new一次后调用一个对象专属的方法例如,tipOBJ.init()。5、个人浅见,共同学习,呵呵。 首先谢谢这位大哥不吝赐教,但大哥,可以OPEN一点,不要那么保守,我1、2两点不是很明白我又做了一下修改,但把body和content事件放在init里后,我觉得很不舒服,想请问,如果是你,来写,你会怎么写var body=$('body'),contents=$('.tipsContent'),titleA=$('.title a');function Tip(contents,titleA,slef){ this.contents = contents; this.titleA=titleA; this.me=slef;}Tip.prototype={ constructor:Tip, init:function(){ this.contents.hide(); this.titleA.removeClass('on'); var htmlHeight=document.documentElement.clientHeight, scrollTop = document.body.scrollTop || document.documentElement.scrollTop, width = this.me.outerWidth(true), height = this.me.outerHeight(true), layer = this.me.parent().parent().find(this.contents), layerHeight=0, position = this.me.position(); this.me.addClass('on'); layer.css({ display: 'block', visibility: 'hidden' }); layerHeight=layer.outerHeight(true); //判断标题a到窗口的底部是否能放下Tip的高度 if(((htmlHeight+scrollTop-position.top)-20)>layerHeight) { layer.css({ "top": position.top - 5 + "px", "left": (position.left + width + 10) + "px", visibility: 'visible' }); } else { layer.css({ "top": position.top-layerHeight+height+5 + "px", "left": (position.left + width+10) + "px", visibility: 'visible' }); } //点击body的时候隐藏所有tip和移除所有标题样式 body.click(function(){ contents.hide(); titleA.removeClass('on'); }); //点击tip内容的时候防止冒泡 contents.click(function(e) { e.stopPropagation(); }) }} 还是没理解什么是OO,什么是XX this.titleA.removeClass("on");this.me.addClass('on');样式写死了。不灵活。尤其是当CSS有冲突时。 layer.css({ "top": position.top - 5 + "px", "left": (position.left + width + 10) + "px",位置写死了。布局设计有变化时还需要改。把这些能抽象的抽象出来,整个结构的修改就会明确一些了。 //options 用对象的方式进行传参,扩张性要好点。格式:{contents:'',titleA:'',slef:''} //设想你要现在有3个参数,需求改变了,要传四个参数,方法要改成四个参数,调用的方法也要改成四个参数。用对象传参就可以避免这样的情况,一个参数就够了,看着也更好看点。 function Tip(options) { this.content=... //改成 var contents = ...; 私有变量(private),对外封闭,体现对象的封装性,这样要好点吧。 //var build_1=function(){}//构建步骤1,私有 //var build_2=function(){}//构建步骤2,私有 this.show= function () {//公有(public),楼主 要体现build模式的话,应该要把构造的步骤再抽象出来。 build_1(); build_2(); } } //这样对外看来,Tip只暴露了我们需要的show()方法。。楼主原来的把属性都暴露出来了,事实上,调用者可能不关心你的属性。 //实际上调用者只关心:我给你参数,你给我个方法,能让我show()就行了,其他的我什么都不关心。 $(function () { //调用 $('.title a').click(function(e){ //这里每次click都要new 一个Tip实例,如果这个浮动弹出窗口是一样的话。这里可以考虑用单件模式(Singleton)。 //创建一个后,下次创建就用上次创建好的,只是改变一下内容。而不是重新创建一个实例。 var tip=new Tip(contents,titleA,$(this)); e.stopPropagation(); tip.show(); })//仅供参考 跟楼主推荐一本书:JavaScript高级程序设计(第2版)[www.TopSage.com].pdf 里面就详细讲解了js的 oo.总体一个原则在默认构造函数里面放常用公有属性,如动态方法,用obj.prototype 周五啦,大家该放松放松下啦,求教JS面向对象编程 这种图片变换效果怎么做? 对象如何连接? 判断只能输入12~15的数字 请问<SCRIPT ID=clientEventHandlersVBS LANGUAGE=vbscript>中的ID=clientEventHandlersVBS 是什么意思? 关于multiple select 通用数据校验函数 超基础问题 想用这段代码历遍所有的节点,但是…… JS调用URL页面转向,控制器方法,点击按钮后报错 正则表达式如何匹配字符前的所有空格? 怎样利用jquery为radio的value赋值
{
this.contents = contents,
this.titleA=titleA,
this.body=$('body');
this.show=function(){
this.contents.hide();
this.titleA.removeClass("on");
var htmlHidth=document.documentElement.clientHeight,
scrollTop = document.body.scrollTop || document.documentElement.scrollTop,
me = slef,
width = me.outerWidth(true),
height = me.outerHeight(true),
layer = me.parent().parent().find(this.contents),
layerHeight=0,
position = me.position(); me.addClass('on');
layer.css({
display: 'block',
visibility: 'hidden'
});
layerHeight=layer.outerHeight(true);
if(((htmlHidth+scrollTop-position.top)-20)>layerHeight)
{
layer.css({
"top": position.top - 5 + "px",
"left": (position.left + width + 10) + "px",
visibility: 'visible'
});
}
else
{
layer.css({
"top": position.top-layerHeight+height+5 + "px",
"left": (position.left + width+10) + "px",
visibility: 'visible'
});
}
};
}调用方式$(function(){
var contents=$('.tipsContent'),titleA=$('.title a');
$('.title a').click(function(e){
var tip=new Tip(contents,titleA,$(this));
e.stopPropagation();
tip.show();
})
$('body').click(function(){
contents.hide();
titleA.removeClass('on');
});
$('.tipsContent').click(function(e)
{
e.stopPropagation();
})
})
{
this.contents = contents,
this.titleA=titleA,
this.me=slef;
this.show=function(){
this.contents.hide();
this.titleA.removeClass("on");
var htmlHeight=document.documentElement.clientHeight,
scrollTop = document.body.scrollTop || document.documentElement.scrollTop,
width = this.me.outerWidth(true),
height = this.me.outerHeight(true),
layer = this.me.parent().parent().find(this.contents),
layerHeight=0,
position = this.me.position(); this.me.addClass('on');
layer.css({
display: 'block',
visibility: 'hidden'
});
layerHeight=layer.outerHeight(true);
if(((htmlHeight+scrollTop-position.top)-20)>layerHeight)
{
layer.css({
"top": position.top - 5 + "px",
"left": (position.left + width + 10) + "px",
visibility: 'visible'
});
}
else
{
layer.css({
"top": position.top-layerHeight+height+5 + "px",
"left": (position.left + width+10) + "px",
visibility: 'visible'
});
}
};
}看起来是构造函数模式,但内部看起来有点糟,有没有优化的余地,拜托了~~~
我又修改了一下我解释下下:这个函数的作用是点击列表标题,显示浮动的弹出框.
让我特别纠结的是在调用时函数时的这两个事件,应该放在Tip里面吗?$(function(){
var contents=$('.tipsContent'),titleA=$('.title a');
$('.title a').click(function(e){
var tip=new Tip(contents,titleA,$(this));
e.stopPropagation();
tip.show();
})
$('body').click(function(){
contents.hide();
titleA.removeClass('on');
});
$('.tipsContent').click(function(e)
{
e.stopPropagation();
})
})
function Tip(contents,titleA,slef)
{
this.contents = contents,
this.titleA=titleA,
this.me=slef;
}Tip.prototype={
constructor:Tip,
show:function(){
this.contents.hide();
this.titleA.removeClass("on");
var htmlHeight=document.documentElement.clientHeight,
scrollTop = document.body.scrollTop || document.documentElement.scrollTop,
width = this.me.outerWidth(true),
height = this.me.outerHeight(true),
layer = this.me.parent().parent().find(this.contents),
layerHeight=0,
position = this.me.position(); this.me.addClass('on');
layer.css({
display: 'block',
visibility: 'hidden'
});
layerHeight=layer.outerHeight(true);
if(((htmlHeight+scrollTop-position.top)-20)>layerHeight)
{
layer.css({
"top": position.top - 5 + "px",
"left": (position.left + width + 10) + "px",
visibility: 'visible'
});
}
else
{
layer.css({
"top": position.top-layerHeight+height+5 + "px",
"left": (position.left + width+10) + "px",
visibility: 'visible'
});
}
}
}调用方式$(function(){
var contents=$('.tipsContent'),titleA=$('.title a');
$('.title a').click(function(e){
var tip=new Tip(contents,titleA,$(this));
e.stopPropagation();
tip.show();
})
$('body').click(function(){
contents.hide();
titleA.removeClass('on');
});
$('.tipsContent').click(function(e)
{
e.stopPropagation();
})
})同楼上,我觉得有结构问题,有优化的方法吗?
1、构造函数参数用对象形式比较好。
2、可为这个类写个放置全局变量的沙盒,采用set和get方法来存取全局变量。可以避免采用this.xxx来取全局变量。
3、这个类在一个页面里可能不止被实例化一次,所以尽可能把共用方法抽象出来放到prototype里面去。以免实例化时存在多分方法的拷贝。
4、如果要封装,调用方法我觉得过于复杂了。尽量只要new一次,或者new一次后调用一个对象专属的方法例如,tipOBJ.init()。
5、个人浅见,共同学习,呵呵。
我又做了一下修改,但把body和content事件放在init里后,我觉得很不舒服,想请问,如果是你,来写,你会怎么写var body=$('body'),contents=$('.tipsContent'),titleA=$('.title a');function Tip(contents,titleA,slef)
{
this.contents = contents;
this.titleA=titleA;
this.me=slef;
}Tip.prototype={
constructor:Tip,
init:function(){
this.contents.hide();
this.titleA.removeClass('on');
var htmlHeight=document.documentElement.clientHeight,
scrollTop = document.body.scrollTop || document.documentElement.scrollTop,
width = this.me.outerWidth(true),
height = this.me.outerHeight(true),
layer = this.me.parent().parent().find(this.contents),
layerHeight=0,
position = this.me.position(); this.me.addClass('on');
layer.css({
display: 'block',
visibility: 'hidden'
});
layerHeight=layer.outerHeight(true);
//判断标题a到窗口的底部是否能放下Tip的高度
if(((htmlHeight+scrollTop-position.top)-20)>layerHeight)
{
layer.css({
"top": position.top - 5 + "px",
"left": (position.left + width + 10) + "px",
visibility: 'visible'
});
}
else
{
layer.css({
"top": position.top-layerHeight+height+5 + "px",
"left": (position.left + width+10) + "px",
visibility: 'visible'
});
}
//点击body的时候隐藏所有tip和移除所有标题样式
body.click(function(){
contents.hide();
titleA.removeClass('on');
});
//点击tip内容的时候防止冒泡
contents.click(function(e)
{
e.stopPropagation();
})
}
}
this.me.addClass('on');
样式写死了。不灵活。尤其是当CSS有冲突时。 layer.css({
"top": position.top - 5 + "px",
"left": (position.left + width + 10) + "px",
位置写死了。布局设计有变化时还需要改。把这些能抽象的抽象出来,整个结构的修改就会明确一些了。
//options 用对象的方式进行传参,扩张性要好点。格式:{contents:'',titleA:'',slef:''}
//设想你要现在有3个参数,需求改变了,要传四个参数,方法要改成四个参数,调用的方法也要改成四个参数。用对象传参就可以避免这样的情况,一个参数就够了,看着也更好看点。
function Tip(options) {
this.content=... //改成 var contents = ...; 私有变量(private),对外封闭,体现对象的封装性,这样要好点吧。
//var build_1=function(){}//构建步骤1,私有
//var build_2=function(){}//构建步骤2,私有
this.show= function () {//公有(public),楼主 要体现build模式的话,应该要把构造的步骤再抽象出来。
build_1();
build_2();
}
}
//这样对外看来,Tip只暴露了我们需要的show()方法。。楼主原来的把属性都暴露出来了,事实上,调用者可能不关心你的属性。
//实际上调用者只关心:我给你参数,你给我个方法,能让我show()就行了,其他的我什么都不关心。
$(function () { //调用
$('.title a').click(function(e){
//这里每次click都要new 一个Tip实例,如果这个浮动弹出窗口是一样的话。这里可以考虑用单件模式(Singleton)。
//创建一个后,下次创建就用上次创建好的,只是改变一下内容。而不是重新创建一个实例。
var tip=new Tip(contents,titleA,$(this));
e.stopPropagation();
tip.show();
})//仅供参考