日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【译】Using Objects to Organize Your Code

發(fā)布時(shí)間:2024/4/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【译】Using Objects to Organize Your Code 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

耗了一個(gè)晚上吐血翻譯不過(guò)也學(xué)到了不少...《使用對(duì)象來(lái)組織你的代碼》,翻譯中發(fā)現(xiàn)原作者在原文中有部分代碼有誤或不全,本文已修改和添加~

麗貝卡·墨菲原文鏈接:http://rmurphey.com/blog/2009/10/15/using-objects-to-organize-your-code?

?

當(dāng)你不只是使用jQuery的簡(jiǎn)單片段而是開(kāi)始開(kāi)發(fā)更復(fù)雜的用戶交互,你的代碼會(huì)變得笨重和難以調(diào)試,這篇文章通過(guò)使用對(duì)象字面量的形式向你展示如何在行為特征的角度思考這些交互。

在過(guò)去幾年,JavaScript庫(kù)讓初級(jí)開(kāi)發(fā)者有能力為他們的站點(diǎn)制作炫酷的交互,就像jQuery,有著非常簡(jiǎn)單的語(yǔ)法得以讓零編程經(jīng)驗(yàn)的人裝飾他們的網(wǎng)頁(yè),一個(gè)插件或自定義的幾十行代碼運(yùn)行出的效果就能給人留下深刻印象。

但是等等,現(xiàn)今的需求早已改變了,現(xiàn)在你的代碼可能需要根據(jù)ID的不同而被重用,這樣的話用jQuery(或其他庫(kù))的編寫(xiě)的代碼片段看似用處不大了,它們只是代碼片段不是嗎?當(dāng)你不使用插件而實(shí)現(xiàn)?show()?或?hide()?的功能應(yīng)該怎么設(shè)計(jì)你的代碼呢?

?

Introducing the Object Literal Pattern 對(duì)象字面量的介紹

對(duì)象字面量提供了一個(gè)包括行為的方式去組織代碼,這也意味著避免污染全局命名空間,這是對(duì)于一個(gè)較大項(xiàng)目的很好做法,它迫使你去思考你的代碼在一開(kāi)始就應(yīng)該做什么以及哪些部分需要放置在合適的位置。對(duì)象字面量是封裝相關(guān)行為的方式,如下所示:

var myObjectLiteral = {myBehavior1 : function() {/* do something */ },myBehavior2 : function() {/* do something else*/} };

假設(shè)你使用jQuery完成一個(gè)點(diǎn)擊list項(xiàng)顯示和隱藏的功能:

$(document).ready(function() {$('#myFeature li').append('<div/>').each(function(){$(this).find('div').load('foo.php?item=' + $(this).attr('id'));}).click(function() {$(this).find('div').show();$(this).siblings().find('div').hide();}); });

就是這么簡(jiǎn)單,但是當(dāng)你想在這個(gè)例子中改變一些需求,例如加載內(nèi)容的URL的方式,以及加載內(nèi)容的URL,或者是顯示和隱藏的行為等等,對(duì)象字面量清晰地劃分了這些功能特征,看起來(lái)如下:

var myFeature = {config : {wrapper : '#myFeature',container : 'div',urlBase : 'foo.php?item='},init : function(config){$.extend(myFeature.config, config);$(myFeature.config.wrapper).find('li').each(function(){myFeature.getContent($(this));}).click(function(){myFeature.showContent($(this));});},buildUrl : function($li){return myFeature.config.urlBase + $li.attr('id');},getContent : function($li){$li.append('<' + myFeature.config.container + '/>');var url = myFeature.buildUrl($li);$li.find(myFeature.config.container).load(url);},showContent : function($li){$li.find(myFeature.config.container).show();myFeature.hideContent($li.siblings());},hideContent : function($elements){$elements.find(myFeature.config.container).hide();} };$(document).ready(function() { myFeature.init(); });

最初的例子是很簡(jiǎn)單的,用對(duì)象字面量形式卻讓代碼變得更長(zhǎng),說(shuō)實(shí)話,對(duì)象字面量形式一般是不會(huì)節(jié)省你的代碼量的。使用對(duì)象字面量我們將代碼的邏輯部分分割開(kāi)來(lái),因此很容易找到我們想要改變的部分,我們已經(jīng)取得我們的功能擴(kuò)展,提供了覆寫(xiě)默認(rèn)配置的功能。并且做了文檔上的限制,很容易一眼看出該部分做什么功能。拋開(kāi)這個(gè)例子的簡(jiǎn)單結(jié)構(gòu),隨著需求的增長(zhǎng)我們的代碼結(jié)構(gòu)將變得愈來(lái)愈清晰。

?

An in-depth example 一個(gè)更深層次的示例

我們的任務(wù)是創(chuàng)建每個(gè)部分含有多項(xiàng)內(nèi)容的UI元素,點(diǎn)擊一個(gè)區(qū)塊將顯示區(qū)塊中項(xiàng)目的列表,點(diǎn)擊項(xiàng)目列表中的項(xiàng)目,項(xiàng)目?jī)?nèi)容將顯示在內(nèi)容區(qū)域。每當(dāng)區(qū)塊被顯示時(shí),第一個(gè)項(xiàng)目列表應(yīng)該也被顯示。第一部分應(yīng)該在頁(yè)面加載時(shí)被顯示。

作者想表達(dá)的效果圖應(yīng)該是這樣的:

Step 1: HTML結(jié)構(gòu)

編寫(xiě)良好語(yǔ)義化的HTML是編寫(xiě)好的JavaScript的先決條件,所以我們思考一下HTML應(yīng)該長(zhǎng)什么樣子呢,HTML應(yīng)該是:

  • 當(dāng)JavaScript不可用時(shí)HTML仍然有意義并且很好的工作
  • 提供可預(yù)測(cè)的DOM結(jié)構(gòu)方便附加在JavaScript上
  • 避免不必要的IDs和classes(你可能會(huì)感到驚訝)

考慮到這些策略,我們開(kāi)始編寫(xiě)html吧:

<h1>This is My Nifty Feature</h1><div id="myFeature"><ul class="sections"><li><h2><a href="/section/1">Section 1</a></h2><ul><li><h3><a href="/section/1/content/1">Section 1 Title 1</a></h3><p>The excerpt content for Content Item 1</p></li><li><h3><a href="/section/1/content/2">Section 1 Title 2</a></h3><p>The expert content for Content Item 2</p></li><li><h3><a href="/section/1/content/3">Section 1 Title 3</a></h3><p>The expert content for Content Item 3</p></li></ul></li><li><h2><a href="/section/2">Section 2</a></h2><ul><li><h3><a href="/section/2/content/1">Section 2 Title 1</a></h3><p>The excerpt content for Content Item 1</p></li><li><h3><a href="/section/2/content/2">Section 2 Title 2</a></h3><p>The expert content for Content Item 2</p></li><li><h3><a href="/section/2/content/3">Section 2 Title 3</a></h3><p>The expert content for Content Item 3</p></li></ul></li><li><h2><a href="/section/3">Section 3</a></h2><ul><li><h3><a href="/section/3/content/1">Section 3 Title 1</a></h3><p>The excerpt content for Content Item 1</p></li><li><h3><a href="/section/3/content/2">Section 3 Title 2</a></h3><p>The expert content for Content Item 2</p></li><li><h3><a href="/section/3/content/3">Section 3 Title 3</a></h3><p>The expert content for Content Item 3</p></li></ul></li></ul> </div>

注意此時(shí)沒(méi)有任何標(biāo)記顯示一級(jí)導(dǎo)航或二級(jí)(項(xiàng)目)導(dǎo)航,通過(guò)加入Jquery讓它們工作;不支持JavaScript的用戶將會(huì)得到很好的語(yǔ)義HTML(如果HTML表達(dá)語(yǔ)義不清,應(yīng)該是時(shí)候替換舊的語(yǔ)義和實(shí)現(xiàn)漸進(jìn)增強(qiáng)了)。

Step 2: Scaffolding the Object Object的腳手架

創(chuàng)建對(duì)象第一步是為對(duì)象創(chuàng)建"存根",可以把"存根"想象成占位符;它們是我們要構(gòu)建的功能大綱,我們的對(duì)象將有如下方法:

  • ?myFeature.init()?將會(huì)運(yùn)行在?$(document).ready()?中。通過(guò)語(yǔ)義化的HTML標(biāo)簽,讓我們很快進(jìn)入到JavaScript的用戶界面。
  • ?myFeature.buildSectionNav()??將被?myFeature.init()?調(diào)用。這將需要一個(gè)jQuery對(duì)象包含所有section語(yǔ)義的HTML標(biāo)簽來(lái)構(gòu)建一級(jí)導(dǎo)航,每項(xiàng)一級(jí)導(dǎo)航而且會(huì)被綁定點(diǎn)擊事件,點(diǎn)擊它們將會(huì)顯示相應(yīng)的部分(二級(jí)導(dǎo)航)
  • ?myFeature.buildItemNav()?將被?myFeature.showSection()?調(diào)用,這需要jQuery對(duì)象包含所有和section相關(guān)的具有語(yǔ)義HTML的item項(xiàng),用它們來(lái)建立二級(jí)導(dǎo)航。它們(二級(jí)導(dǎo)航)也將會(huì)被綁定點(diǎn)擊事件所以點(diǎn)擊后將顯示相關(guān)內(nèi)容。
  • ?myFeature.showSection()?當(dāng)用戶點(diǎn)擊一級(jí)導(dǎo)航的項(xiàng)時(shí)將被調(diào)用。通過(guò)一級(jí)導(dǎo)航的點(diǎn)擊項(xiàng)判斷哪部分語(yǔ)義內(nèi)容將被顯示。
  • ?myFeature.showContentItem()??當(dāng)用戶點(diǎn)擊二級(jí)導(dǎo)航時(shí)將被調(diào)用。通過(guò)二級(jí)導(dǎo)航的點(diǎn)擊判斷那部分語(yǔ)義內(nèi)容將被顯示。

首先配置屬性,通過(guò)?myFeature.config?將各個(gè)屬性設(shè)置到一起而不是在代碼中各個(gè)部分定義。我們將在?myFeature.init()?中提供默認(rèn)屬性覆寫(xiě)的功能。

var myFeature = {'config' : {},'init' : function() {},'buildSectionNav' : function() {},'buildItemNav' : function() {},'showSection' : function() {},'showContentItem' : function() {} };

Step 3: The Code 代碼

一旦我們建立起了骨架,是時(shí)候開(kāi)始編寫(xiě)后面的代碼了。首先編寫(xiě)?myFeature.config?對(duì)象和?myFeature.init()?方法:

'config' : {//default container is #myFeature'container' : $('#myFeature') },'init' : function(config){//provide for custom configuration via init()if(config && typeof(config) == 'object' ){$.extend(myFeature.config, config);}//create and/or cache some DOM elements//we'll want to use throughout the codemyFeature.$container = myFeature.config.container;myFeature.$sections = myFeature.$container.// only select immediate children!find('ul.sections > li');
myFeature.$items = myFeature.$sections.
find('ul > li');myFeature.$section_nav
= $('<p/>').attr('id', 'section_nav').prependTo(myFeature.$container);myFeature.$item_nav = $('<p/>').attr('id', 'item_nav').insertAfter(myFeature.section_nav);myFeature.$content = $('<p/>').attr('id', 'content').insertAfter(myFeature.$item_nav);//build the section-level nav and //"click" the first item myFeature.buildSectionNav(myFeature.$sections);myFeature.$section_nav.find('li:first').click();//hide the plain HTML from sightmyFeature.$container.find('ul.sections').hide();//make a note that the initialization//is complete; we don't strictly need this //for this iteration, but it can come in handy myFeature.initialized = true; }

接下來(lái)編寫(xiě)?myFeature.buildSectionNav()?方法:

'buildSectionNav' : function($sections){//iterate over the provided list of sections$sections.each(function(){//get the sectionvar $section = $(this);//create a list item for the section navigation$('<li/>')//use the text of the first h2//in the section as the text for//the section navigation.text($section.find('h2:first').text())//add the list item to the section navigation .appendTo(myFeature.$section_nav)//use data() to store a reference//to the original section on the //newly-created list item.data('section', $section)//bind the click behavior//to the newly created list item//so it will show the section .click(myFeature.showSection); }); }

接下來(lái)編寫(xiě)?myFeature.buildItemNav()?方法:

'buildItemNav' : function($items){//iterate over the provided list of items$items.each(function(){//get the itemvar $item = $(this);//create a list item element for the //item navigation$('<li/>')//use the text of the first h3//in the item as the text for the //item navigation.text($item.find('h3:first').text())//add the list item to item navigation .appendTo(myFeature.$item_nav)//use data to store a reference //to the original item on the //newly created list item.data('item', $item)//bind the click behavior to the //newly created list item so it will //show the content item .click(myFeature.showContentItem);}) }

最后,我們將編寫(xiě)?showSection()?和?showContentItem()?方法:

'showSection' : function(){// capture the list item that was clicked onvar $li = $(this);//clear out the left nav and content area myFeature.$item_nav.empty();myFeature.$content.empty();//get the jQuery section object from original HTML,//which we stored using data() during buildSectionNavvar $section = $li.data('section');//mark the clicked list item as current//and remove the current marker from its siblings$li.addClass('current').siblings().removeClass('current');//find all of items related to the sectionvar $items = $section.find('ul li');//build the item nav for the section myFeature.buildItemsNav($items);//"click" on the first list item in the section's item nav myFeature.$item_nav.find('li:first').click(); },'showContentItem' : function(){var $li = $(this);//mark the clicked list item as current//and remove the current marker form its siblidngs$li.addClass('current').siblings().removeClass('current');//get the jQuery item object from the original HTML,//which we stored using data during buildContentNavvar $item = $li.data('item');myFeature.$content.html($item.html()); }

所有準(zhǔn)備完后,我們開(kāi)始調(diào)用?myFeature.init()?方法:

$(document).ready(myFeature.init())

Step 4: Changing Requirements

沒(méi)有項(xiàng)目是不提需求的,隨時(shí)變更是特點(diǎn)不是嗎?對(duì)象字面量的方式使開(kāi)發(fā)快速并且相當(dāng)容易實(shí)現(xiàn)變更需求。如果我們需要獲取內(nèi)容片段是從AJAX得來(lái)的而不是HTML?假設(shè)這里添加了前后端交互的功能,嘗試一下:

var myFeature = {'config' : {'container' : $('#myFeature'),// configurable function for getting// a URL for loading item content'getItemURL' : function($item){return $item.find('a:first').attr('href');}},'init' : function (config) {// stays the same },'buildSectionNav' : function($sections){// stays the same },'buildItemNav' : function($items) {// stays the same },'showSection' : function(){//stays the same },'showContentItem' : function(){var $li = $(this);$li.addClass('current').$siblings().removeClass('current');var $item = $li.data('item');var url = myFeature.config.getItemURL($item);// myFeature.$content.html($item.html()) myFeature.$content.load(url);}}

想要更加靈活嗎?有許多你能配置的(覆寫(xiě))如果你真的想使代碼功能變得靈活。例如,你可以通過(guò)配置?myFeature.config?自定義地為每個(gè)item找到對(duì)應(yīng)的文本:

var myFeature = {'configure' : {' container' : $('#myFeature'),//specify the default selector// for finding the text to use// for each item in the item nav'itemNavSelector' : 'h3',//specify a default callback//for "processing" the jQuery object//returned by the itemNavText selector'itemNavProcessor' : function($selection){return 'Preview of ' + $selection.eq(0).text();}},'init' : function(config){// stays the same },'buildSectionNav' : function($sections){// stays the same },'buildItemNav' : function($items){$.items.each(function(){var $item = $(this);//use the selector and processor//from the config//to get the text for each item navvar myText = myFeature.config.itemNavProcessor($item.find(myFeature.config.itemNavSelector));$('<li/>')//use the new variable//as the text for the nav item .text(myText).appendTo(myFeature.$item_nav).data('item', $item).click(myFeature.showContentItem);});},'showSection' : function(){// stays the same },'showContentItem' : function (){// stays the same } };

只要你添加配置對(duì)象參數(shù),調(diào)用?myFeature.init()?時(shí)就可以覆寫(xiě)config對(duì)象:

$(document).ready(function(){myFeature.init({ 'itemNavSelector' : 'h2' }); });

OK!有了以上了解和學(xué)習(xí),讀者們可以嘗試實(shí)現(xiàn)jQuery history 插件~

?

Conclusion 總結(jié)

如果你按照代碼例子一步步理解過(guò)來(lái)后,你應(yīng)該對(duì)對(duì)象字面量有了基本了解,它會(huì)對(duì)你開(kāi)發(fā)復(fù)雜功能和交互提供一個(gè)有用的方式,提供給你可以在本代碼上繼續(xù)擴(kuò)展功能,我鼓勵(lì)你在JavaScript中嘗試使用對(duì)象字面量模式去代替短短幾行的代碼——因?yàn)檫@會(huì)迫使你去思考元素的表現(xiàn)和行為去構(gòu)成一個(gè)復(fù)雜的功能或交互。一旦你掌握了它,它為擴(kuò)展和重用你的代碼提供了堅(jiān)實(shí)的基礎(chǔ)。

?

Learn More 了解更多

  • More on the jQuery data() method
  • More praise for the object literal pattern
  • The jQuery History plugin
  • An interseting application of the object literal pattern for architecting code for multiple page types

?

附錄前文中An in-depth example 完整代碼:

<!DOCTYPE html> <html> <head><meta charset="utf-8"><title>An in-depth example 一個(gè)更深層次的示例</title><style type="text/css">.current{background: #f47460;}</style><script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script> </head> <body> <h1>This is My Nifty Feature</h1><div id="myFeature"><ul class="sections"><li><h2><a href="/section/1">Section 1</a></h2><ul><li><h3><a href="/section/1/content/1">Section 1 Title 1</a></h3><p>The excerpt content for Content Item 1</p></li><li><h3><a href="/section/1/content/2">Section 1 Title 2</a></h3><p>The expert content for Content Item 2</p></li><li><h3><a href="/section/1/content/3">Section 1 Title 3</a></h3><p>The expert content for Content Item 3</p></li></ul></li><li><h2><a href="/section/2">Section 2</a></h2><ul><li><h3><a href="/section/2/content/1">Section 2 Title 1</a></h3><p>The excerpt content for Content Item 1</p></li><li><h3><a href="/section/2/content/2">Section 2 Title 2</a></h3><p>The expert content for Content Item 2</p></li><li><h3><a href="/section/2/content/3">Section 2 Title 3</a></h3><p>The expert content for Content Item 3</p></li></ul></li><li><h2><a href="/section/3">Section 3</a></h2><ul><li><h3><a href="/section/3/content/1">Section 3 Title 1</a></h3><p>The excerpt content for Content Item 1</p></li><li><h3><a href="/section/3/content/2">Section 3 Title 2</a></h3><p>The expert content for Content Item 2</p></li><li><h3><a href="/section/3/content/3">Section 3 Title 3</a></h3><p>The expert content for Content Item 3</p></li></ul></li></ul> </div> <script type="text/javascript"> var myFeature = {'config': {'container' : $('#myFeature')},'init': function(config){if(config && typeof config == 'object'){$.extend(myFeature.config, config);}//緩存變量 myFeature.$container = myFeature.config.container;myFeature.$sections = myFeature.$container.find('ul.sections > li');myFeature.$items = myFeature.$sections.find('ul > li');myFeature.$section_nav = $('<p/>').attr('id', 'section_nav').prependTo(myFeature.$container);myFeature.$item_nav = $('<p/>').attr('id', 'item_nav').insertAfter(myFeature.$section_nav);myFeature.$content = $('<p/>').attr('id', 'content').insertAfter(myFeature.$item_nav);//初始化新增的這三層DOM結(jié)構(gòu) myFeature.buildSectionNav(myFeature.$sections);myFeature.$section_nav.find('li:first').click();//隱藏原有的HTML結(jié)構(gòu) myFeature.$container.find('ul.sections').hide();},'buildSectionNav' : function($sections){//綁定事件 $sections.each(function(){var $section = $(this);$('<li>').text($section.find('h2:first').text()).appendTo(myFeature.$section_nav).data('section', $section).click(myFeature.showSection)});},'buildItemNav' : function($items){//綁定事件 $items.each(function(){var $item = $(this);$('<li>').text($item.find('h3:first').text()).appendTo(myFeature.$item_nav).data('item', $item).click(myFeature.showContentItem);});},'showSection' : function(){//事件處理程序var $li = $(this);myFeature.$item_nav.empty();myFeature.$content.empty();var $section = $li.data('section');$li.addClass('current').siblings().removeClass('current');var $items = $section.find('ul li');myFeature.buildItemNav($items);myFeature.$item_nav.find('li:first').click();},'showContentItem' : function(){//事件處理程序var $li = $(this);$li.addClass('current').siblings().removeClass('current');var $item = $li.data('item');myFeature.$content.html($item.html());} }$(document).ready(function(){myFeature.init()}); </script> </body> </html> View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/venoral/p/5639201.html

總結(jié)

以上是生活随笔為你收集整理的【译】Using Objects to Organize Your Code的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。