js中繼承跟java中的繼承不太一樣,一般通過call()和apply()兩種方式完成,js中的繼承是以復(fù)制的形式完成的,復(fù)制一個父對象,而不像java中直接繼承父對象,還有通過原型的方式完成繼承,也有弊端,總之js中的繼承只是形式上的對面向?qū)ο笳Z言的一種模仿,本質(zhì)上不是繼承,但用起來效果是一樣的
10余年的金林網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整金林建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“金林網(wǎng)站設(shè)計(jì)”,“金林網(wǎng)站推廣”以來,每個客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
至于為什么要繼承:通常在一般的項(xiàng)目里不需要,因?yàn)閼?yīng)用簡單,但你要用純js做一些復(fù)雜的工具或框架系統(tǒng)就要用到了,比如webgis、或者js框架如jquery、ext什么的,不然一個幾千行代碼的框架不用繼承得寫幾萬行,甚至還無法維護(hù)
Base做的事情包括:
給模塊增加自定義事件支持
給模塊增加set和get方法
設(shè)置一些默認(rèn)執(zhí)行的方法,比如_init
提供模塊的構(gòu)建功能
提供模塊的擴(kuò)展功能
自定義事件
自定義事件模式是非常實(shí)用的,自定義事件用比較專業(yè)的詞語描述的話,可以稱為觀察者模式,這種模式背后的主要動機(jī)就是促進(jìn)形成松散耦合。在這種模式中,并不是一個對象調(diào)用另外一個對象的方法,而是一個對象訂閱另外一個對象的特定活動并在狀態(tài)改變后等到通知。這意味著我們在做一些事情的時(shí)候,不需要關(guān)注另外事情的進(jìn)展,讓另外一件事情來監(jiān)聽進(jìn)展,然后做出對應(yīng)的處理即可。這樣的話,不同的事情之間就不會存在太多的關(guān)聯(lián),從而降低開發(fā)的復(fù)雜度。
set和get方法
為了保護(hù)和更好地穩(wěn)定模塊的執(zhí)行,需要對模塊參數(shù)的修改做一些限制和處理。所以需要提供set和get方法(現(xiàn)在的Base還沒有在get的時(shí)候做一些處理),set可以用于在設(shè)置模塊屬性的時(shí)候,做一些過濾和處理,保證設(shè)置值的正確性,而且更重要的是,可以在set中觸發(fā)一個屬性修改的事件,從而可以做到修改屬性的時(shí)候觸發(fā)一些其他的變化。get則可以用于在訪問屬性的時(shí)候,對返回的屬性做一些處理。對于模塊內(nèi)部而言,還需要有一個私有的_set和_get屬性,從而可以和外部對模塊的訪問進(jìn)行區(qū)分。
一些默認(rèn)執(zhí)行的方法
默認(rèn)執(zhí)行的方法會在兩個地方存放,一個是在構(gòu)造函數(shù)中,還有一個是在模塊原型上的initliazer方法中。構(gòu)造函數(shù)內(nèi)主要處理模塊間和實(shí)例的關(guān)系,這些處理是會繼承到子模塊中的,而在initliazer中主要處理模塊真正相關(guān)的要執(zhí)行的一些實(shí)例化方法,這樣能保證模塊在被繼承的時(shí)候,自有的一些初始化方法不會被繼承下去。而initliazer方法是由_init方法調(diào)用的,_init方法是模塊實(shí)例化的時(shí)候必定會執(zhí)行的方法,而initliazer是一個可選的初始化方法。
模塊的構(gòu)建和擴(kuò)展
Base核心部分就是對模塊的構(gòu)建和擴(kuò)展。先上代碼
Base._build = function (moduleName, superModule, prototypeMethod, attrMember, staticMember, curConstructor) {
//使用prototype方式繼承
var Module = function () {
Module.superclass.constructor.apply(this, arguments);
//保存對實(shí)例的引用
Module._instances[$.zid(this)] = this;
};
if(curConstructor){
Module = curConstructor;
}
//如果給定了構(gòu)造函數(shù),就在給定的構(gòu)造函數(shù)上進(jìn)行擴(kuò)展,否則試用默認(rèn)的構(gòu)造函數(shù)
return Base._handlerClass(moduleName, Module, superModule, prototypeMethod, attrMember, staticMember)
};
Base._handlerClass = function (moduleName, module, superModule, prototypeMethod, attrMember, staticMember) {
var tempFn = function () {
},
o = {
name:moduleName,
value:module
};
//創(chuàng)建對象來保存實(shí)例的引用
module._instances = {};
//模塊NAME
if (moduleName) {
module.NAME = moduleName;
}
/*Module.toString = function(){
return moduleName;
};*/
//如果沒有傳入要繼承的對象,則默認(rèn)為Base
superModule = superModule || Base;
attrMember = attrMember || {};
staticMember = staticMember || {};
prototypeMethod = prototypeMethod || {};
//掛載ATTRS屬性
//如果是繼承于另外一個模塊,則需要將ATTRS進(jìn)行合并處理
if (superModule.NAME !== BASE) {
$.extend(attrMember, superModule.ATTRS);
}
//@20120830修復(fù)構(gòu)造函數(shù)自帶ATTRS時(shí)對應(yīng)的處理方式
module.ATTRS = module.ATTRS || {};
$.extend(module.ATTRS, attrMember);
//掛在靜態(tài)屬性
$.extend(module, staticMember);
//拷貝一份prototype,防止構(gòu)造函數(shù)直接執(zhí)行
tempFn.prototype = superModule.prototype;
module.prototype = new tempFn();
//把方法添加到Module的原型上
$.extend(module.prototype, prototypeMethod);
//修改構(gòu)造器,防止回溯失敗
module.prototype.constructor = module;
//保存對超類的引用
module.superclass = superModule.prototype;
if (superModule.prototype.constructor == Object.prototype.constructor) {
superModule.prototype.constructor = superModule;
}
//保存生成的對象
Base.classList.push(o);
return module;
};
代碼細(xì)節(jié)都有注釋,就不多說,主要還是把具體做的事情描述下
確定構(gòu)造函數(shù)。
創(chuàng)建一個空對象來保存實(shí)例的引用。
確定模塊名。
確定是否繼承于其他模塊。
拷貝參數(shù)的策略(ATTRS)和靜態(tài)成員
創(chuàng)建原型并拷貝實(shí)例成員(原型上的成員)
修復(fù)創(chuàng)建原型后構(gòu)造器指向不對的問題
創(chuàng)建對超類的引用,從而可以手動訪問超類
保存生存的對象引用
返回改造完成后的模塊
注:以上構(gòu)造模塊的思路主要參考自YUI3的Base模塊。
在下一篇中,將用這個Base模塊來構(gòu)建一個tab組件
動態(tài)加入到DOM中的對象無法繼承原有的事件,所以無效,舉例:
//?$.ajax...?ajax部分省略
var?tr?=?"";
if(data.length){
for(var?i=0;?idata.length;?i++){
tr?=?'tr';
tr?+=?'td'?+?data.status?==?0???"正常"?:?"報(bào)警"?+?'td';
tr?+=?'/tr';
$("#table1").find("tbody").append(tr);
}??
}
//?tr的點(diǎn)擊事件
$("#table1?tbody").find("tr").click(function(){
//?do?something
});
上面的例子中,table1中原有的tr標(biāo)簽有點(diǎn)擊事件,而通過ajax獲取數(shù)據(jù)動態(tài)創(chuàng)建添加到DOM中的tr標(biāo)簽并沒有繼承點(diǎn)擊事件,點(diǎn)擊無任何反應(yīng)。解決辦法有兩種:
純js方法:將tr的點(diǎn)擊事件寫成函數(shù),然后為動態(tài)創(chuàng)建的tr標(biāo)簽添加該函數(shù)的onclick事件:
for(var?i=0;?idata.length;?i++){
tr?=?'tr?onclick="OnTrClick()"';?//?創(chuàng)建時(shí)為tr指定click事件
tr?+=?'td'?+?data.status?==?0???"正常"?:?"報(bào)警"?+?'td';
tr?+=?'/tr';
$("#table1").find("tbody").append(tr);
}
jquery方法:jquery中可使用live()、on()兩個方法來完成類似效果,其原理是利用事件委派機(jī)制,需要注意的是jquery 1.9版本已不再支持live()方法。
//?tr的點(diǎn)擊事件?(jquery?1.9以下)
$("#table1?tbody").find("tr").live("click",?function(){
//?do?something
});
//?tr的點(diǎn)擊事件【推薦】?(jquery?1.7以上)
$("#table1?tbody").find("tr").on("click",?function(){
//?do?something
});
1、活版印刷
一個成功的網(wǎng)站只有很少的字體是類似的款式,而不是使用的字體。最好的網(wǎng)站應(yīng)該使用無襯線和無襯線字體,而不是兩者的結(jié)合。
印刷術(shù)的網(wǎng)站也應(yīng)該小心使用的字體,好的設(shè)計(jì)會加入一些類似的字體,而不是一個范圍內(nèi)型面。大多數(shù)瀏覽器都能識別特定數(shù)量的安全字體,這樣設(shè)計(jì)主要是利用以避免并發(fā)癥的發(fā)生。
2、代碼質(zhì)量
當(dāng)創(chuàng)建一個網(wǎng)站,它是很好的做法,以符合標(biāo)準(zhǔn)。這包括代碼中的錯誤,代碼為更好的布局,以及確保你的ID和類的正確識別。這通常是通過描述指定元件做什么。
不符合標(biāo)準(zhǔn)的網(wǎng)站無法使用或容易出錯的,標(biāo)準(zhǔn)可以涉及到正確的頁面布局的可讀性,以及確保適當(dāng)?shù)仃P(guān)閉了編碼元素。DOCTYPE聲明,這是用來突出顯示代碼中的錯誤。系統(tǒng)識別錯誤和不符合網(wǎng)頁設(shè)計(jì)標(biāo)準(zhǔn)。
3、視覺設(shè)計(jì)
良好的視覺設(shè)計(jì)網(wǎng)站上的標(biāo)識,其目標(biāo)市場。這可以是一個年齡組或特定的文化鏈,因此,設(shè)計(jì)人員應(yīng)了解其受眾的趨勢。設(shè)計(jì)人員也應(yīng)該明白他們設(shè)計(jì)的,這意味著一個企業(yè)網(wǎng)站不應(yīng)該被設(shè)計(jì)成一個社交媒體網(wǎng)站,例如相同類型的網(wǎng)站。
4、交互設(shè)計(jì)
對于網(wǎng)站來說,好的交互設(shè)計(jì)對網(wǎng)頁設(shè)計(jì)的整體起著至關(guān)重要的作用,一個好的交互不僅能大大提升頁面整體的設(shè)計(jì)效果,增強(qiáng)頁面的“活躍度”,還能有效提高用戶體驗(yàn),“屏蔽”單調(diào)的操作流程,使得產(chǎn)品、文化的表現(xiàn)都能最大化的呈現(xiàn)并傳達(dá)到相關(guān)的受眾。
5、內(nèi)容更新
企業(yè)Web站點(diǎn)建立后,要不斷更新網(wǎng)頁內(nèi)容。站點(diǎn)信息的不斷更新,讓瀏覽者了解企業(yè)的發(fā)展動態(tài)和網(wǎng)上職務(wù)等,同時(shí)也會幫助企業(yè)建立良好的形象。
參考資料來源:百度百科-網(wǎng)頁設(shè)計(jì)
什么是backbone
backbone不是脊椎骨,而是幫助開發(fā)重量級的javascript應(yīng)用的框架。
主要提供了3個東西:1、models(模型) 2、collections(集合) 3、views(視圖)
backbone.js文件本身很小,壓縮后只有5.3KB,作為一個框架級別的核心JS文件,這個數(shù)字很可怕。
除此之外,這個JS還必須依賴于另一個JS文件:underscore.js(包含許多工具方法,集合操作,js模板等等)。
簡介
用Backbone.Model表示應(yīng)用中所有數(shù)據(jù),models中的數(shù)據(jù)可以創(chuàng)建、校驗(yàn)、銷毀和保存到服務(wù)端。
當(dāng)models中值被改變時(shí)自動觸發(fā)一個"change"事件、所有用于展示models數(shù)據(jù)的views都會偵聽到這個事件,然后進(jìn)行重新渲染。
Backbone.Collection和我們平時(shí)接觸的JAVA集合類相似,具有增加元素,刪除元素,獲取長度,排序,比較等一系列工具方法,說白了就是一個保存models的集合類。
Backbone.View中可以綁定dom el和客戶端事件。頁面中的html就是通過views的render方法渲染出來的,當(dāng)新建一個view的時(shí)候通過要傳進(jìn)一個model作為數(shù)據(jù),例如:
Js代碼 ?
var?view?=?new?EmployeeView({model:employee});??
也就是說model就是以這種方式和view進(jìn)行關(guān)聯(lián)的。
特點(diǎn)
創(chuàng)建models或者views的語法:extends,相當(dāng)于類繼承
models的創(chuàng)建,銷毀,校驗(yàn)等一系列改變都會觸發(fā)相應(yīng)的事件
示例
需求:用backbone.js和jquery實(shí)現(xiàn)一個可編輯的員工信息表格。
功能:1、錄入員工信息。2、刪除員工信息。3、雙擊表格可對員工信息進(jìn)行修改。4、能對員工信息進(jìn)行有效性校驗(yàn)。5、能對員工信息進(jìn)行持久化。
設(shè)計(jì):
用Employee類(繼承自Backbone.Model)表示員工信息,包含ID、姓名、性別、年齡和職位字段。
Js代碼 ?
window.Employee?=?Backbone.Model.extend({??
//?模型值校驗(yàn)??
validate:function(attrs){??
for(var?key?in?attrs){??
if(attrs[key]?==?''){??
return?key?+?"不能為空";??
}??
if(key?==?'age'??isNaN(attrs.age)){??
return?"年齡必須是數(shù)字";??
}??
}??
}??
});??
聲明Employee類之后就可以新增一個Employee的示例對象了:
Js代碼 ?
var?employee?=?new?Employee();??
Employee類中不必聲明ID、姓名等業(yè)務(wù)字段。當(dāng)需要給employee設(shè)置這些信息時(shí)候,只需要調(diào)用
Js代碼 ?
employee.set({'id':1,'name':'Jason'});??
當(dāng)然,如果需要對employee的信息進(jìn)行校驗(yàn),需要給Employee類配置一個validate方法,這個方法的參數(shù)attrs就是set進(jìn)去的json數(shù)據(jù)。這樣,當(dāng)employee里面的數(shù)據(jù)每次發(fā)生改變的時(shí)候都會先調(diào)用這個validate方法。
Model類定義好之后就可以開始定義集合類了,在集合類里面可以對里面的每個Model進(jìn)行增加,刪除等一系列操作,還可以調(diào)用fetch方法從server端獲取集合的初始值。
Js代碼 ?
window.EmployeeList?=?Backbone.Collection.extend({??
model?:?Employee,??
//?持久化到本地?cái)?shù)據(jù)庫??
localStorage:?new?Store("employees"),??
});??
window.Employees?=?new?EmployeeList();??
設(shè)置 localStorage屬性后Employees里面的數(shù)據(jù)自動會同步保存到本地?cái)?shù)據(jù)庫里面,每當(dāng)調(diào)用Employees.fetch()后又會從localStorage里面恢復(fù)數(shù)據(jù)。
View類主要負(fù)責(zé)一切和界面相關(guān)的工作,比如綁定html模板,綁定界面元素的事件,初始的渲染,模型值改變后的重新渲染和界面元素的銷毀等:
Js代碼 ?
window.EmployeeView?=?Backbone.View.extend({??
tagName?:?'tr',??
template?:?_.template($('#item-template').html()),??
events?:?{??
"dblclick?td"?:?"edit",??
"blur?input,select"?:?"close",??
"click?.del"?:?"clear",??
},??
initialize?:?function(){??
//?每次更新模型后重新渲染??
this.model.bind('change',?this.render,?this);??
//?每次刪除模型之后自動移除UI??
this.model.bind('destroy',?this.remove,?this);??
},??
setText?:?function(){??
var?model?=?this.model;??
this.input?=?$(this.el).find('input,select');???
this.input.each(function(){??
var?input?=?$(this);??
input.val(model.get(input.attr("name")));??
});??
},??
close:?function(e)?{??
var?input?=?$(e.currentTarget);??
var?obj?=?{};??
obj[input.attr('name')]?=?input.val();??
this.model.save(obj);??
$(e.currentTarget).parent().parent().removeClass("editing");??
},??
edit?:?function(e){??
//?給td加上editing樣式??
$(e.currentTarget).addClass('editing').find('input,select').focus();??
},??
render:?function()?{??
$(this.el).html(this.template(this.model.toJSON()));??
//?把每個單元格的值賦予隱藏的輸入框??
this.setText();??
return?this;??
},??
remove:?function()?{??
$(this.el).remove();??
},??
clear:?function()?{??
this.model.destroy();??
}??
});??
這個類里面的代碼比較多,但主要和界面的渲染有關(guān)。一個EmployeeView對象對應(yīng)table里面的一個tr元素。每次new一個EmployeeView對象的時(shí)候都會先調(diào)用initialize方法,這個方法里面綁定的事件確保了tr元素對應(yīng)的model值每次發(fā)生改變或者被刪除時(shí)都會同步到界面。也就是說當(dāng)每次操作界面對數(shù)據(jù)進(jìn)行修改后都是先把當(dāng)前的變更保存到view綁定的model對象里面,然后model里面的事件機(jī)制會自動觸發(fā)一個"change"事件對界面進(jìn)行修改。
template中使用的方法_.template($('#item-template').html())是前面提到的underscore.js中提供一個工具方法,可以通過界面的HTML模板和一個JSON生成動態(tài)的HTML,說白了就是把JSON里面的值填充到HTML模板中對應(yīng)的占位符里面去,牛X的是HTML模板里面支持一些常用的邏輯表達(dá)式如if,else,foreach等:
Html代碼 ?
script?type="text/template"?id="item-template"??
td%=?eid?%/td??
td?class="username"??
div?class="display"%=?username?%/div??
div?class="edit"input?class="username"?name="username"/input/div??
/td??
td?class="sex"??
div?class="display"%=?sex=="1"???"女":"男"?%/div??
div?class="edit"??
select?name="sex"?class="sex"?style="width:45px"??
option?value="0"男/optionoption?value="1"女/option??
/select??
/div??
/td??
td?class="age"??
div?class="display"%=?age?%/div??
div?class="edit"??
input?class="age"?name="age"/input??
/div??
/td??
td?class="position"??
div?class="display"%=?position?%/div??
div?class="edit"??
input?class="position"?name="position"/input??
/div??
/td??
td??
a?href="#"?class="del"刪除/a??
/td??
/script??
setText方法主要負(fù)責(zé)把model里面的數(shù)據(jù)設(shè)置到每個tr里面的隱藏輸入域里面。
close方法被綁定到了input和select元素的blur事件中。當(dāng)用戶對單元格數(shù)據(jù)進(jìn)行修改后都會把鼠標(biāo)點(diǎn)擊到界面其他地方然后輸入框會自動隱藏并且把修改的數(shù)據(jù)顯示在表格上面。close方法首先從當(dāng)前被編輯的元素中拿到最新值,然后封裝成一個對象,調(diào)用model的save方法后首先執(zhí)行model的validate方法,如果校驗(yàn)通過則保存到本地存儲并觸發(fā)"change"事件。
最后還需要一個主界面View,這個View主要綁定了界面中的錄入表單的“增加”按鈕事件,Employees的相關(guān)事件以及頁面初始化時(shí)從本地存儲中恢復(fù)數(shù)據(jù):
Js代碼 ?
window.AppView?=?Backbone.View.extend({??
el?:?$("#app"),??
events?:?{??
"click?.#add-btn"?:?"createOnEnter"??
},??
//?綁定collection的相關(guān)事件??
initialize:?function()?{??
Employees.bind('add',?this.addOne,?this);??
//?調(diào)用fetch的時(shí)候觸發(fā)reset??
Employees.bind('reset',?this.addAll,?this);??
Employees.fetch();??
},??
createOnEnter?:?function(e)?{??
var?employee?=?new?Employee();??
var?attr?=?{};??
$('#emp-form?input,#emp-form?select').each(function(){??
var?input?=?$(this);??
attr[input.attr('name')]?=?input.val();??
});??
employee.bind('error',function(model,error){??
alert(error);??
});??
//?set方法中會自動調(diào)用model的validate方法進(jìn)行校驗(yàn),如果不通過則返回false??
if(employee.set(attr)){??
Employees.create(employee);??
}??
},??
addOne?:?function(employee){??
employee.set({"eid":employee.get("eid")||Employees.length});??
employee.bind('error',function(model,error){??
alert(error);??
});??
var?view?=?new?EmployeeView({model:employee});??
$(".emp-table?tbody").append(view.render().el);??
},??
addAll?:?function(){??
Employees.each(this.addOne);??
}??
});??
initialize方法中綁定了Employees的add和reset事件,也就是說每當(dāng)往Employees中添加一個model的時(shí)候都會調(diào)用AppView的addOne方法,這個方法主要綁定了model的error事件以及把EmployeeView生成的html插入到界面中的合適位置。
OK,萬事俱備,只欠啟動,整個應(yīng)用的初始化方法就是AppView的initialize方法,因此只需要新建一個AppView就可以了:
Js代碼 ?
window.App?=?new?AppView();??
整個示例的JS代碼很少,加上注釋只有100行左右,感興趣的
應(yīng)該不存在jq對象這一概念的吧,jq是用JS寫的,所以應(yīng)該是指JS的繼承吧,JS是通過原型鏈實(shí)現(xiàn)繼承的。首先所有的函數(shù)類都是繼承自obejct,object繼承自null(即object的__proto__指向null,你定義的函數(shù)類的__proto__指向object的prototype),然后你new出來的函數(shù)類對象上的__proto__就指向函數(shù)類的prototype。當(dāng)需要訪問對象的某個屬性或函數(shù)的時(shí)候就會沿著this和__proto__一直往上找。這樣實(shí)現(xiàn)繼承。
本文標(biāo)題:jquery繼承,jquery繼承類
鏈接分享:http://chinadenli.net/article6/dsdchig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、網(wǎng)站改版、小程序開發(fā)、手機(jī)網(wǎng)站建設(shè)、定制網(wǎng)站、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)