tangram.js 325 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132
  1. (function(){
  2. // Copyright (c) 2009, Baidu Inc. All rights reserved.
  3. //
  4. // Licensed under the BSD License
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://tangram.baidu.com/license.html
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS-IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. /*
  16. * Tangram
  17. * Copyright 2009 Baidu Inc. All rights reserved.
  18. */
  19. /**
  20. * @namespace T Tangram七巧板
  21. * @name T
  22. * @version 1.3.9
  23. */
  24. /**
  25. * 声明baidu包
  26. * @author: allstar, erik, meizz, berg
  27. */
  28. var T,
  29. baidu = T = baidu || {version: "1.3.9"};
  30. window.TT = T;
  31. //提出guid,防止在与老版本Tangram混用时
  32. //在下一行错误的修改window[undefined]
  33. baidu.guid = "$BAIDU$";
  34. //Tangram可能被放在闭包中
  35. //一些页面级别唯一的属性,需要挂载在window[baidu.guid]上
  36. window[baidu.guid] = window[baidu.guid] || {};
  37. /*
  38. * Tangram
  39. * Copyright 2009 Baidu Inc. All rights reserved.
  40. *
  41. * path: baidu/ajax.js
  42. * author: allstar, erik
  43. * version: 1.1.0
  44. * date: 2009/11/13
  45. */
  46. /**
  47. * @namespace baidu.ajax 对XMLHttpRequest请求的封装。
  48. */
  49. baidu.ajax = baidu.ajax || {};
  50. /*
  51. * Tangram
  52. * Copyright 2009 Baidu Inc. All rights reserved.
  53. *
  54. * path: baidu/fn.js
  55. * author: berg
  56. * version: 1.0.0
  57. * date: 2010/11/02
  58. */
  59. /**
  60. * @namespace baidu.fn 对方法的操作,解决内存泄露问题。
  61. */
  62. baidu.fn = baidu.fn || {};
  63. /*
  64. * Tangram
  65. * Copyright 2011 Baidu Inc. All rights reserved.
  66. */
  67. /**
  68. * 这是一个空函数,用于需要排除函数作用域链干扰的情况.
  69. * @author rocy
  70. * @name baidu.fn.blank
  71. * @function
  72. * @grammar baidu.fn.blank()
  73. * @meta standard
  74. * @version 1.3.3
  75. */
  76. baidu.fn.blank = function () {};
  77. /*
  78. * Tangram
  79. * Copyright 2009 Baidu Inc. All rights reserved.
  80. */
  81. /**
  82. * 发送一个ajax请求
  83. * @author: allstar, erik, berg
  84. * @name baidu.ajax.request
  85. * @function
  86. * @grammar baidu.ajax.request(url[, options])
  87. * @param {string} url 发送请求的url
  88. * @param {Object} opt_options 发送请求的选项参数
  89. * @config {String} [method] 请求发送的类型。默认为GET
  90. * @config {Boolean} [async] 是否异步请求。默认为true(异步)
  91. * @config {String} [data] 需要发送的数据。如果是GET请求的话,不需要这个属性
  92. * @config {Object} [headers] 要设置的http request header
  93. * @config {number} [timeout] 超时时间,单位ms
  94. * @config {String} [username] 用户名
  95. * @config {String} [password] 密码
  96. * @config {Function} [onsuccess] 请求成功时触发,function(XMLHttpRequest xhr, string responseText)。
  97. * @config {Function} [onfailure] 请求失败时触发,function(XMLHttpRequest xhr)。
  98. * @config {Function} [onbeforerequest] 发送请求之前触发,function(XMLHttpRequest xhr)。
  99. * @config {Function} [on{STATUS_CODE}] 当请求为相应状态码时触发的事件,如on302、on404、on500,function(XMLHttpRequest xhr)。3XX的状态码浏览器无法获取,4xx的,可能因为未知问题导致获取失败。
  100. * @config {Boolean} [noCache] 是否需要缓存,默认为false(缓存),1.1.1起支持。
  101. *
  102. * @meta standard
  103. * @see baidu.ajax.get,baidu.ajax.post,baidu.ajax.form
  104. *
  105. * @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象
  106. */
  107. baidu.ajax.request = function (url, opt_options) {
  108. var options = opt_options || {},
  109. data = options.data || "",
  110. async = !(options.async === false),
  111. username = options.username || "",
  112. password = options.password || "",
  113. method = (options.method || "GET").toUpperCase(),
  114. headers = options.headers || {},
  115. // 基本的逻辑来自lili同学提供的patch
  116. timeout = options.timeout || 0,
  117. eventHandlers = {},
  118. tick, key, xhr;
  119. /**
  120. * readyState发生变更时调用
  121. *
  122. * @ignore
  123. */
  124. function stateChangeHandler() {
  125. if (xhr.readyState == 4) {
  126. try {
  127. var stat = xhr.status;
  128. } catch (ex) {
  129. // 在请求时,如果网络中断,Firefox会无法取得status
  130. fire('failure');
  131. return;
  132. }
  133. fire(stat);
  134. // http://www.never-online.net/blog/article.asp?id=261
  135. // case 12002: // Server timeout
  136. // case 12029: // dropped connections
  137. // case 12030: // dropped connections
  138. // case 12031: // dropped connections
  139. // case 12152: // closed by server
  140. // case 13030: // status and statusText are unavailable
  141. // IE error sometimes returns 1223 when it
  142. // should be 204, so treat it as success
  143. if ((stat >= 200 && stat < 300)
  144. || stat == 304
  145. || stat == 1223) {
  146. fire('success');
  147. } else {
  148. fire('failure');
  149. }
  150. /*
  151. * NOTE: Testing discovered that for some bizarre reason, on Mozilla, the
  152. * JavaScript <code>XmlHttpRequest.onreadystatechange</code> handler
  153. * function maybe still be called after it is deleted. The theory is that the
  154. * callback is cached somewhere. Setting it to null or an empty function does
  155. * seem to work properly, though.
  156. *
  157. * On IE, there are two problems: Setting onreadystatechange to null (as
  158. * opposed to an empty function) sometimes throws an exception. With
  159. * particular (rare) versions of jscript.dll, setting onreadystatechange from
  160. * within onreadystatechange causes a crash. Setting it from within a timeout
  161. * fixes this bug (see issue 1610).
  162. *
  163. * End result: *always* set onreadystatechange to an empty function (never to
  164. * null). Never set onreadystatechange from within onreadystatechange (always
  165. * in a setTimeout()).
  166. */
  167. window.setTimeout(
  168. function() {
  169. // 避免内存泄露.
  170. // 由new Function改成不含此作用域链的 baidu.fn.blank 函数,
  171. // 以避免作用域链带来的隐性循环引用导致的IE下内存泄露. By rocy 2011-01-05 .
  172. xhr.onreadystatechange = baidu.fn.blank;
  173. if (async) {
  174. xhr = null;
  175. }
  176. }, 0);
  177. }
  178. }
  179. /**
  180. * 获取XMLHttpRequest对象
  181. *
  182. * @ignore
  183. * @return {XMLHttpRequest} XMLHttpRequest对象
  184. */
  185. function getXHR() {
  186. if (window.ActiveXObject) {
  187. try {
  188. return new ActiveXObject("Msxml2.XMLHTTP");
  189. } catch (e) {
  190. try {
  191. return new ActiveXObject("Microsoft.XMLHTTP");
  192. } catch (e) {}
  193. }
  194. }
  195. if (window.XMLHttpRequest) {
  196. return new XMLHttpRequest();
  197. }
  198. }
  199. /**
  200. * 触发事件
  201. *
  202. * @ignore
  203. * @param {String} type 事件类型
  204. */
  205. function fire(type) {
  206. type = 'on' + type;
  207. var handler = eventHandlers[type],
  208. globelHandler = baidu.ajax[type];
  209. // 不对事件类型进行验证
  210. if (handler) {
  211. if (tick) {
  212. clearTimeout(tick);
  213. }
  214. if (type != 'onsuccess') {
  215. handler(xhr);
  216. } else {
  217. //处理获取xhr.responseText导致出错的情况,比如请求图片地址.
  218. try {
  219. xhr.responseText;
  220. } catch(error) {
  221. return handler(xhr);
  222. }
  223. handler(xhr, xhr.responseText);
  224. }
  225. } else if (globelHandler) {
  226. //onsuccess不支持全局事件
  227. if (type == 'onsuccess') {
  228. return;
  229. }
  230. globelHandler(xhr);
  231. }
  232. }
  233. for (key in options) {
  234. // 将options参数中的事件参数复制到eventHandlers对象中
  235. // 这里复制所有options的成员,eventHandlers有冗余
  236. // 但是不会产生任何影响,并且代码紧凑
  237. eventHandlers[key] = options[key];
  238. }
  239. headers['X-Requested-With'] = 'XMLHttpRequest';
  240. try {
  241. xhr = getXHR();
  242. if (method == 'GET') {
  243. if (data) {
  244. url += (url.indexOf('?') >= 0 ? '&' : '?') + data;
  245. data = null;
  246. }
  247. if(options['noCache'])
  248. url += (url.indexOf('?') >= 0 ? '&' : '?') + 'b' + (+ new Date) + '=1';
  249. }
  250. if (username) {
  251. xhr.open(method, url, async, username, password);
  252. } else {
  253. xhr.open(method, url, async);
  254. }
  255. if (async) {
  256. xhr.onreadystatechange = stateChangeHandler;
  257. }
  258. // 在open之后再进行http请求头设定
  259. // FIXME 是否需要添加; charset=UTF-8呢
  260. if (method == 'POST') {
  261. xhr.setRequestHeader("Content-Type",
  262. (headers['Content-Type'] || "application/x-www-form-urlencoded"));
  263. }
  264. for (key in headers) {
  265. if (headers.hasOwnProperty(key)) {
  266. xhr.setRequestHeader(key, headers[key]);
  267. }
  268. }
  269. fire('beforerequest');
  270. if (timeout) {
  271. tick = setTimeout(function(){
  272. xhr.onreadystatechange = baidu.fn.blank;
  273. xhr.abort();
  274. fire("timeout");
  275. }, timeout);
  276. }
  277. xhr.send(data);
  278. if (!async) {
  279. stateChangeHandler();
  280. }
  281. } catch (ex) {
  282. fire('failure');
  283. }
  284. return xhr;
  285. };
  286. /*
  287. * Tangram
  288. * Copyright 2009 Baidu Inc. All rights reserved.
  289. *
  290. * path: baidu/ajax/form.js
  291. * author: allstar, erik
  292. * version: 1.1.0
  293. * date: 2009/12/02
  294. */
  295. /**
  296. * 将一个表单用ajax方式提交
  297. * @name baidu.ajax.form
  298. * @function
  299. * @grammar baidu.ajax.form(form[, options])
  300. * @param {HTMLFormElement} form 需要提交的表单元素
  301. * @param {Object} [options] 发送请求的选项参数
  302. * @config {Boolean} [async] 是否异步请求。默认为true(异步)
  303. * @config {String} [username] 用户名
  304. * @config {String} [password] 密码
  305. * @config {Object} [headers] 要设置的http request header
  306. * @config {Function} [replacer] 对参数值特殊处理的函数,replacer(string value, string key)
  307. * @config {Function} [onbeforerequest] 发送请求之前触发,function(XMLHttpRequest xhr)。
  308. * @config {Function} [onsuccess] 请求成功时触发,function(XMLHttpRequest xhr, string responseText)。
  309. * @config {Function} [onfailure] 请求失败时触发,function(XMLHttpRequest xhr)。
  310. * @config {Function} [on{STATUS_CODE}] 当请求为相应状态码时触发的事件,如on302、on404、on500,function(XMLHttpRequest xhr)。3XX的状态码浏览器无法获取,4xx的,可能因为未知问题导致获取失败。
  311. * @see baidu.ajax.request
  312. *
  313. * @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象
  314. */
  315. baidu.ajax.form = function (form, options) {
  316. options = options || {};
  317. var elements = form.elements,
  318. len = elements.length,
  319. method = form.getAttribute('method'),
  320. url = form.getAttribute('action'),
  321. replacer = options.replacer || function (value, name) {
  322. return value;
  323. },
  324. sendOptions = {},
  325. data = [],
  326. i, item, itemType, itemName, itemValue,
  327. opts, oi, oLen, oItem;
  328. /**
  329. * 向缓冲区添加参数数据
  330. * @private
  331. */
  332. function addData(name, value) {
  333. data.push(name + '=' + value);
  334. }
  335. // 复制发送参数选项对象
  336. for (i in options) {
  337. if (options.hasOwnProperty(i)) {
  338. sendOptions[i] = options[i];
  339. }
  340. }
  341. for (i = 0; i < len; i++) {
  342. item = elements[i];
  343. itemName = item.name;
  344. // 处理:可用并包含表单name的表单项
  345. if (!item.disabled && itemName) {
  346. itemType = item.type;
  347. itemValue = item.value;
  348. switch (itemType) {
  349. // radio和checkbox被选中时,拼装queryString数据
  350. case 'radio':
  351. case 'checkbox':
  352. if (!item.checked) {
  353. break;
  354. }
  355. // 默认类型,拼装queryString数据
  356. case 'textarea':
  357. case 'text':
  358. case 'password':
  359. case 'hidden':
  360. case 'select-one':
  361. addData(itemName, replacer(itemValue, itemName));
  362. break;
  363. // 多行选中select,拼装所有选中的数据
  364. case 'select-multiple':
  365. opts = item.options;
  366. oLen = opts.length;
  367. for (oi = 0; oi < oLen; oi++) {
  368. oItem = opts[oi];
  369. if (oItem.selected) {
  370. addData(itemName, replacer(oItem.value, itemName));
  371. }
  372. }
  373. break;
  374. }
  375. }
  376. }
  377. // 完善发送请求的参数选项
  378. sendOptions.data = data.join('&');
  379. sendOptions.method = form.getAttribute('method') || 'GET';
  380. // 发送请求
  381. return baidu.ajax.request(url, sendOptions);
  382. };
  383. /*
  384. * Tangram
  385. * Copyright 2009 Baidu Inc. All rights reserved.
  386. *
  387. * path: baidu/ajax/get.js
  388. * author: allstar, erik
  389. * version: 1.1.0
  390. * date: 2009/12/02
  391. */
  392. /**
  393. * 发送一个get请求
  394. * @name baidu.ajax.get
  395. * @function
  396. * @grammar baidu.ajax.get(url[, onsuccess])
  397. * @param {string} url 发送请求的url地址
  398. * @param {Function} [onsuccess] 请求成功之后的回调函数,function(XMLHttpRequest xhr, string responseText)
  399. * @meta standard
  400. * @see baidu.ajax.post,baidu.ajax.request
  401. *
  402. * @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象
  403. */
  404. baidu.ajax.get = function (url, onsuccess) {
  405. return baidu.ajax.request(url, {'onsuccess': onsuccess});
  406. };
  407. /*
  408. * Tangram
  409. * Copyright 2009 Baidu Inc. All rights reserved.
  410. *
  411. * path: baidu/ajax/post.js
  412. * author: allstar, erik
  413. * version: 1.1.0
  414. * date: 2009/12/02
  415. */
  416. /**
  417. * 发送一个post请求
  418. * @name baidu.ajax.post
  419. * @function
  420. * @grammar baidu.ajax.post(url, data[, onsuccess])
  421. * @param {string} url 发送请求的url地址
  422. * @param {string} data 发送的数据
  423. * @param {Function} [onsuccess] 请求成功之后的回调函数,function(XMLHttpRequest xhr, string responseText)
  424. * @meta standard
  425. * @see baidu.ajax.get,baidu.ajax.request
  426. *
  427. * @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象
  428. */
  429. baidu.ajax.post = function (url, data, onsuccess) {
  430. return baidu.ajax.request(
  431. url,
  432. {
  433. 'onsuccess': onsuccess,
  434. 'method': 'POST',
  435. 'data': data
  436. }
  437. );
  438. };
  439. /*
  440. * Tangram
  441. * Copyright 2009 Baidu Inc. All rights reserved.
  442. *
  443. * path: baidu/array.js
  444. * author: erik
  445. * version: 1.1.0
  446. * date: 2009/12/02
  447. */
  448. /**
  449. * @namespace baidu.array 操作数组的方法。
  450. */
  451. baidu.array = baidu.array || {};
  452. /*
  453. * Tangram
  454. * Copyright 2009 Baidu Inc. All rights reserved.
  455. *
  456. * path: baidu/array/indexOf.js
  457. * author: erik
  458. * version: 1.1.0
  459. * date: 2009/12/02
  460. */
  461. /**
  462. * 查询数组中指定元素的索引位置
  463. * @name baidu.array.indexOf
  464. * @function
  465. * @grammar baidu.array.indexOf(source, match[, fromIndex])
  466. * @param {Array} source 需要查询的数组
  467. * @param {Any} match 查询项
  468. * @param {number} [fromIndex] 查询的起始位索引位置,如果为负数,则从source.length+fromIndex往后开始查找
  469. * @see baidu.array.find,baidu.array.lastIndexOf
  470. *
  471. * @returns {number} 指定元素的索引位置,查询不到时返回-1
  472. */
  473. baidu.array.indexOf = function (source, match, fromIndex) {
  474. var len = source.length,
  475. iterator = match;
  476. fromIndex = fromIndex | 0;
  477. if(fromIndex < 0){//小于0
  478. fromIndex = Math.max(0, len + fromIndex)
  479. }
  480. for ( ; fromIndex < len; fromIndex++) {
  481. if(fromIndex in source && source[fromIndex] === match) {
  482. return fromIndex;
  483. }
  484. }
  485. return -1;
  486. };
  487. /*
  488. * Tangram
  489. * Copyright 2009 Baidu Inc. All rights reserved.
  490. */
  491. /**
  492. * 判断一个数组中是否包含给定元素
  493. * @name baidu.array.contains
  494. * @function
  495. * @grammar baidu.array.contains(source, obj)
  496. * @param {Array} source 需要判断的数组.
  497. * @param {Any} obj 要查找的元素.
  498. * @return {boolean} 判断结果.
  499. * @author berg
  500. */
  501. baidu.array.contains = function(source, obj) {
  502. return (baidu.array.indexOf(source, obj) >= 0);
  503. };
  504. /*
  505. * Tangram
  506. * Copyright 2009 Baidu Inc. All rights reserved.
  507. *
  508. * path: baidu/array/each.js
  509. * author: erik
  510. * version: 1.1.0
  511. * date: 2009/12/02
  512. */
  513. /**
  514. * 遍历数组中所有元素
  515. * @name baidu.array.each
  516. * @function
  517. * @grammar baidu.array.each(source, iterator[, thisObject])
  518. * @param {Array} source 需要遍历的数组
  519. * @param {Function} iterator 对每个数组元素进行调用的函数,该函数有两个参数,第一个为数组元素,第二个为数组索引值,function (item, index)。
  520. * @param {Object} [thisObject] 函数调用时的this指针,如果没有此参数,默认是当前遍历的数组
  521. * @remark
  522. * each方法不支持对Object的遍历,对Object的遍历使用baidu.object.each 。
  523. * @shortcut each
  524. * @meta standard
  525. *
  526. * @returns {Array} 遍历的数组
  527. */
  528. baidu.each = baidu.array.forEach = baidu.array.each = function (source, iterator, thisObject) {
  529. var returnValue, item, i, len = source.length;
  530. if ('function' == typeof iterator) {
  531. for (i = 0; i < len; i++) {
  532. item = source[i];
  533. //TODO
  534. //此处实现和标准不符合,标准中是这样说的:
  535. //If a thisObject parameter is provided to forEach, it will be used as the this for each invocation of the callback. If it is not provided, or is null, the global object associated with callback is used instead.
  536. returnValue = iterator.call(thisObject || source, item, i);
  537. if (returnValue === false) {
  538. break;
  539. }
  540. }
  541. }
  542. return source;
  543. };
  544. /*
  545. * Tangram
  546. * Copyright 2009 Baidu Inc. All rights reserved.
  547. */
  548. /**
  549. * 清空一个数组
  550. * @name baidu.array.empty
  551. * @function
  552. * @grammar baidu.array.empty(source)
  553. * @param {Array} source 需要清空的数组.
  554. * @author berg
  555. */
  556. baidu.array.empty = function(source) {
  557. source.length = 0;
  558. };
  559. /*
  560. * Tangram
  561. * Copyright 2009 Baidu Inc. All rights reserved.
  562. */
  563. /**
  564. * 判断一个数组中是否所有元素都满足给定条件
  565. * @name baidu.array.every
  566. * @function
  567. * @grammar baidu.array.every(source, iterator[,thisObject])
  568. * @param {Array} source 需要判断的数组.
  569. * @param {Function} iterator 判断函数.
  570. * @param {Object} [thisObject] 函数调用时的this指针,如果没有此参数,默认是当前遍历的数组
  571. * @return {boolean} 判断结果.
  572. * @see baidu.array.some
  573. */
  574. baidu.array.every = function(source, iterator, thisObject) {
  575. var i = 0,
  576. len = source.length;
  577. for (; i < len; i++) {
  578. if (i in source && !iterator.call(thisObject || source, source[i], i)) {
  579. return false;
  580. }
  581. }
  582. return true;
  583. };
  584. /*
  585. * Tangram
  586. * Copyright 2009 Baidu Inc. All rights reserved.
  587. */
  588. /**
  589. * 从数组中筛选符合条件的元素
  590. * @name baidu.array.filter
  591. * @function
  592. * @grammar baidu.array.filter(source, iterator[, thisObject])
  593. * @param {Array} source 需要筛选的数组
  594. * @param {Function} iterator 对每个数组元素进行筛选的函数,该函数有两个参数,第一个为数组元素,第二个为数组索引值,function (item, index),函数需要返回true或false
  595. * @param {Object} [thisObject] 函数调用时的this指针,如果没有此参数,默认是当前遍历的数组
  596. * @meta standard
  597. * @see baidu.array.find
  598. *
  599. * @returns {Array} 符合条件的数组项集合
  600. */
  601. baidu.array.filter = function (source, iterator, thisObject) {
  602. var result = [],
  603. resultIndex = 0,
  604. len = source.length,
  605. item,
  606. i;
  607. if ('function' == typeof iterator) {
  608. for (i = 0; i < len; i++) {
  609. item = source[i];
  610. //TODO
  611. //和标准不符,see array.each
  612. if (true === iterator.call(thisObject || source, item, i)) {
  613. // resultIndex用于优化对result.length的多次读取
  614. result[resultIndex++] = item;
  615. }
  616. }
  617. }
  618. return result;
  619. };
  620. /*
  621. * Tangram
  622. * Copyright 2009 Baidu Inc. All rights reserved.
  623. *
  624. * path: baidu/array/find.js
  625. * author: erik
  626. * version: 1.1.0
  627. * date: 2009/12/02
  628. */
  629. /**
  630. * 从数组中寻找符合条件的第一个元素
  631. * @name baidu.array.find
  632. * @function
  633. * @grammar baidu.array.find(source, iterator)
  634. * @param {Array} source 需要查找的数组
  635. * @param {Function} iterator 对每个数组元素进行查找的函数,该函数有两个参数,第一个为数组元素,第二个为数组索引值,function (item, index),函数需要返回true或false
  636. * @see baidu.array.filter,baidu.array.indexOf
  637. *
  638. * @returns {Any|null} 符合条件的第一个元素,找不到时返回null
  639. */
  640. baidu.array.find = function (source, iterator) {
  641. var item, i, len = source.length;
  642. if ('function' == typeof iterator) {
  643. for (i = 0; i < len; i++) {
  644. item = source[i];
  645. if (true === iterator.call(source, item, i)) {
  646. return item;
  647. }
  648. }
  649. }
  650. return null;
  651. };
  652. /*
  653. * Tangram
  654. * Copyright 2009 Baidu Inc. All rights reserved.
  655. */
  656. /**
  657. * 将两个数组参数合并成一个类似hashMap结构的对象,这个对象使用第一个数组做为key,使用第二个数组做为值,如果第二个参数未指定,则把对象的所有值置为true。
  658. * @name baidu.array.hash
  659. * @function
  660. * @grammar baidu.array.hash(keys[, values])
  661. * @param {Array} keys 作为key的数组
  662. * @param {Array} [values] 作为value的数组,未指定此参数时,默认值将对象的值都设为true。
  663. *
  664. * @returns {Object} 合并后的对象{key : value}
  665. */
  666. baidu.array.hash = function(keys, values) {
  667. var o = {}, vl = values && values.length, i = 0, l = keys.length;
  668. for (; i < l; i++) {
  669. o[keys[i]] = (vl && vl > i) ? values[i] : true;
  670. }
  671. return o;
  672. };
  673. /*
  674. * Tangram
  675. * Copyright 2009 Baidu Inc. All rights reserved.
  676. *
  677. * path: baidu/array/lastIndexOf.js
  678. * author: erik
  679. * version: 1.1.0
  680. * date: 2009/11/14
  681. */
  682. /**
  683. * 从后往前,查询数组中指定元素的索引位置
  684. * @name baidu.array.lastIndexOf
  685. * @function
  686. * @grammar baidu.array.lastIndexOf(source, match)
  687. * @param {Array} source 需要查询的数组
  688. * @param {Any} match 查询项
  689. * @param {number} [fromIndex] 查询的起始位索引位置,如果为负数,则从source.length+fromIndex往前开始查找
  690. * @see baidu.array.indexOf
  691. *
  692. * @returns {number} 指定元素的索引位置,查询不到时返回-1
  693. */
  694. baidu.array.lastIndexOf = function (source, match, fromIndex) {
  695. var len = source.length;
  696. fromIndex = fromIndex | 0;
  697. if(!fromIndex || fromIndex >= len){
  698. fromIndex = len - 1;
  699. }
  700. if(fromIndex < 0){
  701. fromIndex += len;
  702. }
  703. for(; fromIndex >= 0; fromIndex --){
  704. if(fromIndex in source && source[fromIndex] === match){
  705. return fromIndex;
  706. }
  707. }
  708. return -1;
  709. };
  710. /*
  711. * Tangram
  712. * Copyright 2009 Baidu Inc. All rights reserved.
  713. */
  714. /**
  715. * 遍历数组中所有元素,将每一个元素应用方法进行转换,并返回转换后的新数组。
  716. * @name baidu.array.map
  717. * @function
  718. * @grammar baidu.array.map(source, iterator[, thisObject])
  719. * @param {Array} source 需要遍历的数组.
  720. * @param {Function} iterator 对每个数组元素进行处理的函数.
  721. * @param {Object} [thisObject] 函数调用时的this指针,如果没有此参数,默认是当前遍历的数组
  722. * @return {Array} map后的数组.
  723. * @see baidu.array.reduce
  724. */
  725. baidu.array.map = function(source, iterator, thisObject) {
  726. var results = [],
  727. i = 0,
  728. l = source.length;
  729. for (; i < l; i++) {
  730. results[i] = iterator.call(thisObject || source, source[i], i);
  731. }
  732. return results;
  733. };
  734. /*
  735. * Tangram
  736. * Copyright 2009 Baidu Inc. All rights reserved.
  737. */
  738. /**
  739. * 遍历数组中所有元素,将每一个元素应用方法进行合并,并返回合并后的结果。
  740. * @name baidu.array.reduce
  741. * @function
  742. * @grammar baidu.array.reduce(source, iterator[, initializer])
  743. * @param {Array} source 需要遍历的数组.
  744. * @param {Function} iterator 对每个数组元素进行处理的函数,函数接受四个参数:上一次reduce的结果(或初始值),当前元素值,索引值,整个数组.
  745. * @param {Object} [initializer] 合并的初始项,如果没有此参数,默认用数组中的第一个值作为初始值.
  746. * @return {Array} reduce后的值.
  747. * @version 1.3.4
  748. * @see baidu.array.reduce
  749. */
  750. baidu.array.reduce = function(source, iterator, initializer) {
  751. var i = 0,
  752. l = source.length,
  753. found = 0;
  754. if( arguments.length < 3){
  755. //没有initializer的情况,找到第一个可用的值
  756. for(; i < l; i++){
  757. initializer = source[i++];
  758. found = 1;
  759. break;
  760. }
  761. if(!found){
  762. return ;
  763. }
  764. }
  765. for (; i < l; i++) {
  766. if( i in source){
  767. initializer = iterator(initializer, source[i] , i , source);
  768. }
  769. }
  770. return initializer;
  771. };
  772. /*
  773. * Tangram
  774. * Copyright 2009 Baidu Inc. All rights reserved.
  775. *
  776. * path: baidu/array/remove.js
  777. * author: erik
  778. * version: 1.1.0
  779. * date: 2009/11/30
  780. */
  781. /**
  782. * 移除数组中的项
  783. * @name baidu.array.remove
  784. * @function
  785. * @grammar baidu.array.remove(source, match)
  786. * @param {Array} source 需要移除项的数组
  787. * @param {Any} match 要移除的项
  788. * @meta standard
  789. * @see baidu.array.removeAt
  790. *
  791. * @returns {Array} 移除后的数组
  792. */
  793. baidu.array.remove = function (source, match) {
  794. var len = source.length;
  795. while (len--) {
  796. if (len in source && source[len] === match) {
  797. source.splice(len, 1);
  798. }
  799. }
  800. return source;
  801. };
  802. /*
  803. * Tangram
  804. * Copyright 2009 Baidu Inc. All rights reserved.
  805. *
  806. * path: baidu/array/removeAt.js
  807. * author: erik
  808. * version: 1.1.0
  809. * date: 2009/11/30
  810. */
  811. /**
  812. * 移除数组中的项
  813. * @name baidu.array.removeAt
  814. * @function
  815. * @grammar baidu.array.removeAt(source, index)
  816. * @param {Array} source 需要移除项的数组
  817. * @param {number} index 要移除项的索引位置
  818. * @see baidu.array.remove
  819. * @meta standard
  820. * @returns {Any} 被移除的数组项
  821. */
  822. baidu.array.removeAt = function (source, index) {
  823. return source.splice(index, 1)[0];
  824. };
  825. /*
  826. * Tangram
  827. * Copyright 2009 Baidu Inc. All rights reserved.
  828. */
  829. /**
  830. * 判断一个数组中是否有部分元素满足给定条件
  831. * @name baidu.array.some
  832. * @function
  833. * @grammar baidu.array.some(source, iterator[,thisObject])
  834. * @param {Array} source 需要判断的数组.
  835. * @param {Function} iterator 判断函数.
  836. * @param {Object} [thisObject] 函数调用时的this指针,如果没有此参数,默认是当前遍历的数组
  837. * @return {boolean} 判断结果.
  838. * @see baidu.array.every
  839. */
  840. baidu.array.some = function(source, iterator, thisObject) {
  841. var i = 0,
  842. len = source.length;
  843. for (; i < len; i++) {
  844. if (i in source && iterator.call(thisObject || source, source[i], i)) {
  845. return true;
  846. }
  847. }
  848. return false;
  849. };
  850. /*
  851. * Tangram
  852. * Copyright 2009 Baidu Inc. All rights reserved.
  853. *
  854. * path: baidu/array/unique.js
  855. * author: allstar, erik
  856. * version: 1.1.0
  857. * date: 2009/12/02
  858. */
  859. /**
  860. * 过滤数组中的相同项。如果两个元素相同,会删除后一个元素。
  861. * @name baidu.array.unique
  862. * @function
  863. * @grammar baidu.array.unique(source[, compareFn])
  864. * @param {Array} source 需要过滤相同项的数组
  865. * @param {Function} [compareFn] 比较两个数组项是否相同的函数,两个数组项作为函数的参数。
  866. *
  867. * @returns {Array} 过滤后的新数组
  868. */
  869. baidu.array.unique = function (source, compareFn) {
  870. var len = source.length,
  871. result = source.slice(0),
  872. i, datum;
  873. if ('function' != typeof compareFn) {
  874. compareFn = function (item1, item2) {
  875. return item1 === item2;
  876. };
  877. }
  878. // 从后往前双重循环比较
  879. // 如果两个元素相同,删除后一个
  880. while (--len > 0) {
  881. datum = result[len];
  882. i = len;
  883. while (i--) {
  884. if (compareFn(datum, result[i])) {
  885. result.splice(len, 1);
  886. break;
  887. }
  888. }
  889. }
  890. return result;
  891. };
  892. /*
  893. * Tangram
  894. * Copyright 2009 Baidu Inc. All rights reserved.
  895. */
  896. /**
  897. * @namespace baidu.async 对异步调用的封装。
  898. * @author rocy
  899. */
  900. baidu.async = baidu.async || {};
  901. /*
  902. * Tangram
  903. * Copyright 2009 Baidu Inc. All rights reserved.
  904. *
  905. * path: baidu/object.js
  906. * author: erik
  907. * version: 1.1.0
  908. * date: 2009/11/15
  909. */
  910. /**
  911. * @namespace baidu.object 操作原生对象的方法。
  912. */
  913. baidu.object = baidu.object || {};
  914. /*
  915. * Tangram
  916. * Copyright 2009 Baidu Inc. All rights reserved.
  917. */
  918. /**
  919. * 将源对象的所有属性拷贝到目标对象中
  920. * @author erik
  921. * @name baidu.object.extend
  922. * @function
  923. * @grammar baidu.object.extend(target, source)
  924. * @param {Object} target 目标对象
  925. * @param {Object} source 源对象
  926. * @see baidu.array.merge
  927. * @remark
  928. *
  929. 1.目标对象中,与源对象key相同的成员将会被覆盖。<br>
  930. 2.源对象的prototype成员不会拷贝。
  931. * @shortcut extend
  932. * @meta standard
  933. *
  934. * @returns {Object} 目标对象
  935. */
  936. baidu.extend =
  937. baidu.object.extend = function (target, source) {
  938. for (var p in source) {
  939. if (source.hasOwnProperty(p)) {
  940. target[p] = source[p];
  941. }
  942. }
  943. return target;
  944. };
  945. /*
  946. * Tangram
  947. * Copyright 2009 Baidu Inc. All rights reserved.
  948. *
  949. * path: baidu/lang.js
  950. * author: erik
  951. * version: 1.1.0
  952. * date: 2009/12/02
  953. */
  954. /**
  955. * @namespace baidu.lang 对语言层面的封装,包括类型判断、模块扩展、继承基类以及对象自定义事件的支持。
  956. */
  957. baidu.lang = baidu.lang || {};
  958. /*
  959. * Tangram
  960. * Copyright 2009 Baidu Inc. All rights reserved.
  961. *
  962. * path: baidu/lang/isFunction.js
  963. * author: rocy
  964. * version: 1.1.2
  965. * date: 2010/06/12
  966. */
  967. /**
  968. * 判断目标参数是否为function或Function实例
  969. * @name baidu.lang.isFunction
  970. * @function
  971. * @grammar baidu.lang.isFunction(source)
  972. * @param {Any} source 目标参数
  973. * @version 1.2
  974. * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate
  975. * @meta standard
  976. * @returns {boolean} 类型判断结果
  977. */
  978. baidu.lang.isFunction = function (source) {
  979. // chrome下,'function' == typeof /a/ 为true.
  980. return '[object Function]' == Object.prototype.toString.call(source);
  981. };
  982. /*
  983. * Tangram
  984. * Copyright 2009 Baidu Inc. All rights reserved.
  985. */
  986. /**
  987. * 判断给定object是否包含Deferred主要特征.
  988. * @param {Object} obj 待判定object.
  989. * @return {Boolean} 判定结果, true 则该object符合Deferred特征.
  990. * @private
  991. * @author rocy
  992. */
  993. baidu.async._isDeferred = function(obj) {
  994. var isFn = baidu.lang.isFunction;
  995. return obj && isFn(obj.success) && isFn(obj.then)
  996. && isFn(obj.fail) && isFn(obj.cancel);
  997. };
  998. /*
  999. * Tangram
  1000. * Copyright 2009 Baidu Inc. All rights reserved.
  1001. */
  1002. /**
  1003. * 用于支持异步处理, 使同步异步的调用风格统一.
  1004. * @class
  1005. * @private
  1006. * @grammar new baidu.async.Deferred()
  1007. * @remark
  1008. * 示例:
  1009. function someAsync(){
  1010. var deferred = new baidu.async.Deferred();
  1011. setTimeout(function(){
  1012. afterSomeOperation();
  1013. if(someReason){
  1014. deferred.resolve(someValue);
  1015. } else {
  1016. deferred.reject(someError);
  1017. }
  1018. },100);
  1019. return deferred;
  1020. }
  1021. //用类似同步的方式调用异步操作.
  1022. someAsync().then(onSuccess, onFail);
  1023. //onSuccess或onFail可以确保在正确的时间点执行.
  1024. * @author rocy
  1025. */
  1026. baidu.async.Deferred = function() {
  1027. var me = this;
  1028. baidu.extend(me, {
  1029. _fired: 0,
  1030. _firing: 0,
  1031. _cancelled: 0,
  1032. _resolveChain: [],
  1033. _rejectChain: [],
  1034. _result: [],
  1035. _isError: 0
  1036. });
  1037. function fire() {
  1038. if (me._cancelled || me._firing) {
  1039. return;
  1040. }
  1041. //如果已有nextDeferred对象,则转移到nextDeferred上.
  1042. if (me._nextDeferred) {
  1043. me._nextDeferred.then(me._resolveChain[0], me._rejectChain[0]);
  1044. return;
  1045. }
  1046. me._firing = 1;
  1047. var chain = me._isError ? me._rejectChain : me._resolveChain,
  1048. result = me._result[me._isError ? 1 : 0];
  1049. // 此处使用while而非for循环,是为了避免firing时插入新函数.
  1050. while (chain[0] && (! me._cancelled)) {
  1051. //所有函数仅调用一次.
  1052. //TODO: 支持传入 this 和 arguments, 而不是仅仅一个值.
  1053. try {
  1054. var chainResult = chain.shift().call(me, result);
  1055. //若方法返回Deferred,则将剩余方法延至Deferred中执行
  1056. if (baidu.async._isDeferred(chainResult)) {
  1057. me._nextDeferred = chainResult;
  1058. [].push.apply(chainResult._resolveChain, me._resolveChain);
  1059. [].push.apply(chainResult._rejectChain, me._rejectChain);
  1060. chain = me._resolveChain = [];
  1061. me._rejectChain = [];
  1062. }
  1063. } catch (error) {
  1064. throw error;
  1065. } finally {
  1066. me._fired = 1;
  1067. me._firing = 0;
  1068. }
  1069. }
  1070. }
  1071. /**
  1072. * 调用onSuccess链.使用给定的value作为函数参数.
  1073. * @param {*} value 成功结果.
  1074. * @return {baidu.async.Deferred} this.
  1075. */
  1076. me.resolve = me.fireSuccess = function(value) {
  1077. me._result[0] = value;
  1078. fire();
  1079. return me;
  1080. };
  1081. /**
  1082. * 调用onFail链. 使用给定的error作为函数参数.
  1083. * @param {Error} error 失败原因.
  1084. * @return {baidu.async.Deferred} this.
  1085. */
  1086. me.reject = me.fireFail = function(error) {
  1087. me._result[1] = error;
  1088. me._isError = 1;
  1089. fire();
  1090. return me;
  1091. };
  1092. /**
  1093. * 添加onSuccess和onFail方法到各自的链上. 如果该deferred已触发,则立即执行.
  1094. * @param {Function} onSuccess 该deferred成功时的回调函数.第一个形参为成功时结果.
  1095. * @param {Function} onFail 该deferred失败时的回调函数.第一个形参为失败时结果.
  1096. * @return {baidu.async.Deferred} this.
  1097. */
  1098. me.then = function(onSuccess, onFail) {
  1099. me._resolveChain.push(onSuccess);
  1100. me._rejectChain.push(onFail);
  1101. if (me._fired) {
  1102. fire();
  1103. }
  1104. return me;
  1105. };
  1106. /**
  1107. * 添加方法到onSuccess链上. 如果该deferred已触发,则立即执行.
  1108. * @param {Function} onSuccess 该deferred成功时的回调函数.第一个形参为成功时结果.
  1109. * @return {baidu.async.Deferred} this.
  1110. */
  1111. me.success = function(onSuccess) {
  1112. return me.then(onSuccess, baidu.fn.blank);
  1113. };
  1114. /**
  1115. * 添加方法到onFail链上. 如果该deferred已触发,则立即执行.
  1116. * @param {Function} onFail 该deferred失败时的回调函数.第一个形参为失败时结果.
  1117. * @return {baidu.async.Deferred} this.
  1118. */
  1119. me.fail = function(onFail) {
  1120. return me.then(baidu.fn.blank, onFail);
  1121. };
  1122. /**
  1123. * 中断该deferred, 使其失效.
  1124. */
  1125. me.cancel = function() {
  1126. me._cancelled = 1;
  1127. };
  1128. };
  1129. /*
  1130. * Tangram
  1131. * Copyright 2009 Baidu Inc. All rights reserved.
  1132. */
  1133. /**
  1134. * 支持异步的ajax.get封装.
  1135. * @param {String} url 请求地址.
  1136. * @version 1.3.9
  1137. * @return {baidu.async.Deferred} Deferred对象,支持链式调用.
  1138. */
  1139. baidu.async.get = function(url){
  1140. var deferred = new baidu.async.Deferred();
  1141. baidu.ajax.request(url, {
  1142. onsuccess: function(xhr, responseText) {
  1143. deferred.resolve({xhr: xhr, responseText: responseText});
  1144. },
  1145. onfailure: function(xhr) {
  1146. deferred.reject({xhr: xhr});
  1147. }
  1148. });
  1149. return deferred;
  1150. };
  1151. /*
  1152. * Tangram
  1153. * Copyright 2009 Baidu Inc. All rights reserved.
  1154. */
  1155. /**
  1156. * 支持异步的ajax.post封装.
  1157. * @param {String} url 请求地址.
  1158. * @param {String} data 请求数据.
  1159. * @version 1.3.9
  1160. * @return {baidu.async.Deferred} Deferred对象,支持链式调用.
  1161. */
  1162. baidu.async.post = function(url, data){
  1163. var deferred = new baidu.async.Deferred();
  1164. baidu.ajax.request(url, {
  1165. method: 'POST',
  1166. data: data,
  1167. onsuccess: function(xhr, responseText) {
  1168. deferred.resolve({xhr: xhr, responseText: responseText});
  1169. },
  1170. onfailure: function(xhr) {
  1171. deferred.reject({xhr: xhr});
  1172. }
  1173. });
  1174. return deferred;
  1175. };
  1176. /*
  1177. * Tangram
  1178. * Copyright 2009 Baidu Inc. All rights reserved.
  1179. */
  1180. /**
  1181. * 保证onResolve或onReject可以按序执行. 若第一个参数为deferred,则deferred完成后执行.否则立即执行onResolve,并传入第一个参数.
  1182. * @param {baidu.async.Deferred|*} deferredOrValue deferred实例或任意值.
  1183. * @param {Function} onResolve 成功时的回调函数.若第一个参数不是Deferred实例,则立即执行此方法.
  1184. * @param {Function} onReject 失败时的回调函数.
  1185. * @version 1.3.9
  1186. * @remark
  1187. * 示例一:异步调用: baidu.async.when(asyncLoad(), onResolve, onReject).then(nextSuccess, nextFail);
  1188. * 示例二:同步异步不确定的调用: baidu.async.when(syncOrNot(), onResolve, onReject).then(nextSuccess, nextFail);
  1189. * 示例三:同步接异步的调用: baidu.async.when(sync(), onResolve, onReject).then(asyncSuccess, asyncFail).then(afterAllSuccess, afterAllFail);
  1190. * @return {baidu.async.Deferred} deferred.
  1191. */
  1192. baidu.async.when = function(deferredOrValue, onResolve, onReject) {
  1193. if (baidu.async._isDeferred(deferredOrValue)) {
  1194. deferredOrValue.then(onResolve, onReject);
  1195. return deferredOrValue;
  1196. }
  1197. var deferred = new baidu.async.Deferred();
  1198. deferred.then(onResolve, onReject).resolve(deferredOrValue);
  1199. return deferred;
  1200. };
  1201. /*
  1202. * Tangram
  1203. * Copyright 2009 Baidu Inc. All rights reserved.
  1204. *
  1205. * path: baidu/browser.js
  1206. * author: allstar, erik
  1207. * version: 1.1.0
  1208. * date: 2009/12/02
  1209. */
  1210. /**
  1211. * @namespace baidu.browser 判断浏览器类型和特性的属性。
  1212. */
  1213. baidu.browser = baidu.browser || {};
  1214. /*
  1215. * Tangram
  1216. * Copyright 2009 Baidu Inc. All rights reserved.
  1217. *
  1218. * path: baidu/browser/chrome.js
  1219. * author: allstar
  1220. * version: 1.1.0
  1221. * date: 2009/11/24
  1222. */
  1223. if (/chrome\/(\d+\.\d)/i.test(navigator.userAgent)) {
  1224. /**
  1225. * 判断是否为chrome浏览器
  1226. * @grammar baidu.browser.chrome
  1227. * @see baidu.browser.ie,baidu.browser.firefox,baidu.browser.safari,baidu.browser.opera
  1228. * @property chrome chrome版本号
  1229. */
  1230. baidu.browser.chrome = + RegExp['\x241'];
  1231. }
  1232. /*
  1233. * Tangram
  1234. * Copyright 2009 Baidu Inc. All rights reserved.
  1235. *
  1236. * path: baidu/browser/firefox.js
  1237. * author: allstar
  1238. * version: 1.1.0
  1239. * date: 2009/11/23
  1240. */
  1241. if (/firefox\/(\d+\.\d)/i.test(navigator.userAgent)) {
  1242. /**
  1243. * 判断是否为firefox浏览器
  1244. * @property firefox firefox版本号
  1245. * @grammar baidu.browser.firefox
  1246. * @meta standard
  1247. * @see baidu.browser.ie,baidu.browser.safari,baidu.browser.opera,baidu.browser.chrome
  1248. */
  1249. baidu.browser.firefox = + RegExp['\x241'];
  1250. }
  1251. /*
  1252. * Tangram
  1253. * Copyright 2009 Baidu Inc. All rights reserved.
  1254. *
  1255. * path: baidu/browser/ie.js
  1256. * author: allstar
  1257. * version: 1.1.0
  1258. * date: 2009/11/23
  1259. */
  1260. if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {
  1261. //IE 8下,以documentMode为准
  1262. //在百度模板中,可能会有$,防止冲突,将$1 写成 \x241
  1263. /**
  1264. * 判断是否为ie浏览器
  1265. * @property ie ie版本号
  1266. * @grammar baidu.browser.ie
  1267. * @meta standard
  1268. * @shortcut ie
  1269. * @see baidu.browser.firefox,baidu.browser.safari,baidu.browser.opera,baidu.browser.chrome,baidu.browser.maxthon
  1270. */
  1271. baidu.browser.ie = baidu.ie = document.documentMode || + RegExp['\x241'];
  1272. }
  1273. /*
  1274. * Tangram
  1275. * Copyright 2009 Baidu Inc. All rights reserved.
  1276. *
  1277. * path: baidu/browser/isGecko.js
  1278. * author: allstar
  1279. * version: 1.1.0
  1280. * date: 2009/11/23
  1281. */
  1282. /**
  1283. * 判断是否为gecko内核
  1284. * @property isGecko
  1285. * @grammar baidu.browser.isGecko
  1286. * @meta standard
  1287. * @see baidu.browser.isWebkit
  1288. */
  1289. baidu.browser.isGecko = /gecko/i.test(navigator.userAgent) && !/like gecko/i.test(navigator.userAgent);
  1290. /*
  1291. * Tangram
  1292. * Copyright 2009 Baidu Inc. All rights reserved.
  1293. *
  1294. * path: baidu/browser/isStrict.js
  1295. * author: allstar
  1296. * version: 1.1.0
  1297. * date: 2009/11/23
  1298. */
  1299. /**
  1300. * 判断是否严格标准的渲染模式
  1301. * @property isStrict
  1302. * @grammar baidu.browser.isStrict
  1303. * @meta standard
  1304. */
  1305. baidu.browser.isStrict = document.compatMode == "CSS1Compat";
  1306. /*
  1307. * Tangram
  1308. * Copyright 2009 Baidu Inc. All rights reserved.
  1309. *
  1310. * path: baidu/browser/isWebkit.js
  1311. * author: allstar
  1312. * version: 1.1.0
  1313. * date: 2009/11/23
  1314. */
  1315. /**
  1316. * 判断是否为webkit内核
  1317. * @property isWebkit
  1318. * @grammar baidu.browser.isWebkit
  1319. * @meta standard
  1320. * @see baidu.browser.isGecko
  1321. */
  1322. baidu.browser.isWebkit = /webkit/i.test(navigator.userAgent);
  1323. /*
  1324. * Tangram
  1325. * Copyright 2009 Baidu Inc. All rights reserved.
  1326. *
  1327. * path: baidu/browser/maxthon.js
  1328. * author: allstar
  1329. * version: 1.1.0
  1330. * date: 2009/11/23
  1331. */
  1332. try {
  1333. if (/(\d+\.\d)/.test(external.max_version)) {
  1334. /**
  1335. * 判断是否为maxthon浏览器
  1336. * @property maxthon maxthon版本号
  1337. * @grammar baidu.browser.maxthon
  1338. * @see baidu.browser.ie
  1339. */
  1340. baidu.browser.maxthon = + RegExp['\x241'];
  1341. }
  1342. } catch (e) {}
  1343. /*
  1344. * Tangram
  1345. * Copyright 2009 Baidu Inc. All rights reserved.
  1346. *
  1347. * path: baidu/browser/opera.js
  1348. * author: allstar
  1349. * version: 1.1.0
  1350. * date: 2009/11/23
  1351. */
  1352. if (/opera\/(\d+\.\d)/i.test(navigator.userAgent)) {
  1353. /**
  1354. * 判断是否为opera浏览器
  1355. * @property opera opera版本号
  1356. * @grammar baidu.browser.opera
  1357. * @meta standard
  1358. * @see baidu.browser.ie,baidu.browser.firefox,baidu.browser.safari,baidu.browser.chrome
  1359. */
  1360. baidu.browser.opera = + RegExp['\x241'];
  1361. }
  1362. /*
  1363. * Tangram
  1364. * Copyright 2009 Baidu Inc. All rights reserved.
  1365. *
  1366. * path: baidu/browser/safari.js
  1367. * author: allstar, rocy
  1368. * version: 1.1.0
  1369. * date: 2009/11/23
  1370. */
  1371. (function(){
  1372. var ua = navigator.userAgent;
  1373. /*
  1374. * 兼容浏览器为safari或ipad,其中,一段典型的ipad UA 如下:
  1375. * Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10
  1376. */
  1377. if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(ua) && !/chrome/i.test(ua)){
  1378. /**
  1379. * 判断是否为safari浏览器, 支持ipad
  1380. * @property safari safari版本号
  1381. * @grammar baidu.browser.safari
  1382. * @meta standard
  1383. * @see baidu.browser.ie,baidu.browser.firefox,baidu.browser.opera,baidu.browser.chrome
  1384. */
  1385. baidu.browser.safari = + (RegExp['\x241'] || RegExp['\x242']);
  1386. }
  1387. })();
  1388. /*
  1389. * Tangram
  1390. * Copyright 2009 Baidu Inc. All rights reserved.
  1391. *
  1392. * path: baidu/cookie.js
  1393. * author: erik
  1394. * version: 1.1.0
  1395. * date: 2009/12/02
  1396. */
  1397. /**
  1398. * @namespace baidu.cookie 操作cookie的方法。
  1399. */
  1400. baidu.cookie = baidu.cookie || {};
  1401. /*
  1402. * Tangram
  1403. * Copyright 2009 Baidu Inc. All rights reserved.
  1404. *
  1405. * path: baidu/cookie/_isValidKey.js
  1406. * author: erik
  1407. * version: 1.1.0
  1408. * date: 2009/11/15
  1409. */
  1410. /**
  1411. * 验证字符串是否合法的cookie键名
  1412. *
  1413. * @param {string} source 需要遍历的数组
  1414. * @meta standard
  1415. * @return {boolean} 是否合法的cookie键名
  1416. */
  1417. baidu.cookie._isValidKey = function (key) {
  1418. // http://www.w3.org/Protocols/rfc2109/rfc2109
  1419. // Syntax: General
  1420. // The two state management headers, Set-Cookie and Cookie, have common
  1421. // syntactic properties involving attribute-value pairs. The following
  1422. // grammar uses the notation, and tokens DIGIT (decimal digits) and
  1423. // token (informally, a sequence of non-special, non-white space
  1424. // characters) from the HTTP/1.1 specification [RFC 2068] to describe
  1425. // their syntax.
  1426. // av-pairs = av-pair *(";" av-pair)
  1427. // av-pair = attr ["=" value] ; optional value
  1428. // attr = token
  1429. // value = word
  1430. // word = token | quoted-string
  1431. // http://www.ietf.org/rfc/rfc2068.txt
  1432. // token = 1*<any CHAR except CTLs or tspecials>
  1433. // CHAR = <any US-ASCII character (octets 0 - 127)>
  1434. // CTL = <any US-ASCII control character
  1435. // (octets 0 - 31) and DEL (127)>
  1436. // tspecials = "(" | ")" | "<" | ">" | "@"
  1437. // | "," | ";" | ":" | "\" | <">
  1438. // | "/" | "[" | "]" | "?" | "="
  1439. // | "{" | "}" | SP | HT
  1440. // SP = <US-ASCII SP, space (32)>
  1441. // HT = <US-ASCII HT, horizontal-tab (9)>
  1442. return (new RegExp("^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+\x24")).test(key);
  1443. };
  1444. /*
  1445. * Tangram
  1446. * Copyright 2009 Baidu Inc. All rights reserved.
  1447. *
  1448. * path: baidu/cookie/getRaw.js
  1449. * author: erik
  1450. * version: 1.1.0
  1451. * date: 2009/11/15
  1452. */
  1453. /**
  1454. * 获取cookie的值,不对值进行解码
  1455. * @name baidu.cookie.getRaw
  1456. * @function
  1457. * @grammar baidu.cookie.getRaw(key)
  1458. * @param {string} key 需要获取Cookie的键名
  1459. * @meta standard
  1460. * @see baidu.cookie.get,baidu.cookie.setRaw
  1461. *
  1462. * @returns {string|null} 获取的Cookie值,获取不到时返回null
  1463. */
  1464. baidu.cookie.getRaw = function (key) {
  1465. if (baidu.cookie._isValidKey(key)) {
  1466. var reg = new RegExp("(^| )" + key + "=([^;]*)(;|\x24)"),
  1467. result = reg.exec(document.cookie);
  1468. if (result) {
  1469. return result[2] || null;
  1470. }
  1471. }
  1472. return null;
  1473. };
  1474. /*
  1475. * Tangram
  1476. * Copyright 2009 Baidu Inc. All rights reserved.
  1477. *
  1478. * path: baidu/cookie/get.js
  1479. * author: erik
  1480. * version: 1.1.0
  1481. * date: 2009/11/15
  1482. */
  1483. /**
  1484. * 获取cookie的值,用decodeURIComponent进行解码
  1485. * @name baidu.cookie.get
  1486. * @function
  1487. * @grammar baidu.cookie.get(key)
  1488. * @param {string} key 需要获取Cookie的键名
  1489. * @remark
  1490. * <b>注意:</b>该方法会对cookie值进行decodeURIComponent解码。如果想获得cookie源字符串,请使用getRaw方法。
  1491. * @meta standard
  1492. * @see baidu.cookie.getRaw,baidu.cookie.set
  1493. *
  1494. * @returns {string|null} cookie的值,获取不到时返回null
  1495. */
  1496. baidu.cookie.get = function (key) {
  1497. var value = baidu.cookie.getRaw(key);
  1498. if ('string' == typeof value) {
  1499. value = decodeURIComponent(value);
  1500. return value;
  1501. }
  1502. return null;
  1503. };
  1504. /*
  1505. * Tangram
  1506. * Copyright 2009 Baidu Inc. All rights reserved.
  1507. *
  1508. * path: baidu/cookie/setRaw.js
  1509. * author: erik
  1510. * version: 1.1.0
  1511. * date: 2009/11/15
  1512. */
  1513. /**
  1514. * 设置cookie的值,不对值进行编码
  1515. * @name baidu.cookie.setRaw
  1516. * @function
  1517. * @grammar baidu.cookie.setRaw(key, value[, options])
  1518. * @param {string} key 需要设置Cookie的键名
  1519. * @param {string} value 需要设置Cookie的值
  1520. * @param {Object} [options] 设置Cookie的其他可选参数
  1521. * @config {string} [path] cookie路径
  1522. * @config {Date|number} [expires] cookie过期时间,如果类型是数字的话, 单位是毫秒
  1523. * @config {string} [domain] cookie域名
  1524. * @config {string} [secure] cookie是否安全传输
  1525. * @remark
  1526. *
  1527. <b>options参数包括:</b><br>
  1528. path:cookie路径<br>
  1529. expires:cookie过期时间,Number型,单位为毫秒。<br>
  1530. domain:cookie域名<br>
  1531. secure:cookie是否安全传输
  1532. * @meta standard
  1533. * @see baidu.cookie.set,baidu.cookie.getRaw
  1534. */
  1535. baidu.cookie.setRaw = function (key, value, options) {
  1536. if (!baidu.cookie._isValidKey(key)) {
  1537. return;
  1538. }
  1539. options = options || {};
  1540. //options.path = options.path || "/"; // meizz 20100402 设定一个初始值,方便后续的操作
  1541. //berg 20100409 去掉,因为用户希望默认的path是当前路径,这样和浏览器对cookie的定义也是一致的
  1542. // 计算cookie过期时间
  1543. var expires = options.expires;
  1544. if ('number' == typeof options.expires) {
  1545. expires = new Date();
  1546. expires.setTime(expires.getTime() + options.expires);
  1547. }
  1548. document.cookie =
  1549. key + "=" + value
  1550. + (options.path ? "; path=" + options.path : "")
  1551. + (expires ? "; expires=" + expires.toGMTString() : "")
  1552. + (options.domain ? "; domain=" + options.domain : "")
  1553. + (options.secure ? "; secure" : '');
  1554. };
  1555. /*
  1556. * Tangram
  1557. * Copyright 2009 Baidu Inc. All rights reserved.
  1558. *
  1559. * path: baidu/cookie/remove.js
  1560. * author: erik
  1561. * version: 1.1.0
  1562. * date: 2009/11/15
  1563. */
  1564. /**
  1565. * 删除cookie的值
  1566. * @name baidu.cookie.remove
  1567. * @function
  1568. * @grammar baidu.cookie.remove(key, options)
  1569. * @param {string} key 需要删除Cookie的键名
  1570. * @param {Object} options 需要删除的cookie对应的 path domain 等值
  1571. * @meta standard
  1572. */
  1573. baidu.cookie.remove = function (key, options) {
  1574. options = options || {};
  1575. options.expires = new Date(0);
  1576. baidu.cookie.setRaw(key, '', options);
  1577. };
  1578. /*
  1579. * Tangram
  1580. * Copyright 2009 Baidu Inc. All rights reserved.
  1581. *
  1582. * path: baidu/cookie/set.js
  1583. * author: erik
  1584. * version: 1.1.0
  1585. * date: 2009/11/15
  1586. */
  1587. /**
  1588. * 设置cookie的值,用encodeURIComponent进行编码
  1589. * @name baidu.cookie.set
  1590. * @function
  1591. * @grammar baidu.cookie.set(key, value[, options])
  1592. * @param {string} key 需要设置Cookie的键名
  1593. * @param {string} value 需要设置Cookie的值
  1594. * @param {Object} [options] 设置Cookie的其他可选参数
  1595. * @config {string} [path] cookie路径
  1596. * @config {Date|number} [expires] cookie过期时间,如果类型是数字的话, 单位是毫秒
  1597. * @config {string} [domain] cookie域名
  1598. * @config {string} [secure] cookie是否安全传输
  1599. * @remark
  1600. *
  1601. 1. <b>注意:</b>该方法会对cookie值进行encodeURIComponent编码。如果想设置cookie源字符串,请使用setRaw方法。<br><br>
  1602. 2. <b>options参数包括:</b><br>
  1603. path:cookie路径<br>
  1604. expires:cookie过期时间,Number型,单位为毫秒。<br>
  1605. domain:cookie域名<br>
  1606. secure:cookie是否安全传输
  1607. * @meta standard
  1608. * @see baidu.cookie.setRaw,baidu.cookie.get
  1609. */
  1610. baidu.cookie.set = function (key, value, options) {
  1611. baidu.cookie.setRaw(key, encodeURIComponent(value), options);
  1612. };
  1613. /*
  1614. * Tangram
  1615. * Copyright 2009 Baidu Inc. All rights reserved.
  1616. *
  1617. * path: baidu/date.js
  1618. * author: erik
  1619. * version: 1.1.0
  1620. * date: 2009/12/04
  1621. */
  1622. /**
  1623. * @namespace baidu.date 操作日期的方法。
  1624. */
  1625. baidu.date = baidu.date || {};
  1626. /*
  1627. * Tangram
  1628. * Copyright 2009 Baidu Inc. All rights reserved.
  1629. *
  1630. * path: baidu/number.js
  1631. * author: erik
  1632. * version: 1.1.0
  1633. * date: 2009/12/2
  1634. */
  1635. /**
  1636. * @namespace baidu.number 操作number的方法。
  1637. */
  1638. baidu.number = baidu.number || {};
  1639. /*
  1640. * Tangram
  1641. * Copyright 2009 Baidu Inc. All rights reserved.
  1642. *
  1643. * path: baidu/number/pad.js
  1644. * author: dron, erik, berg
  1645. * version: 1.1.0
  1646. * date: 20100412
  1647. */
  1648. /**
  1649. * 对目标数字进行0补齐处理
  1650. * @name baidu.number.pad
  1651. * @function
  1652. * @grammar baidu.number.pad(source, length)
  1653. * @param {number} source 需要处理的数字
  1654. * @param {number} length 需要输出的长度
  1655. *
  1656. * @returns {string} 对目标数字进行0补齐处理后的结果
  1657. */
  1658. baidu.number.pad = function (source, length) {
  1659. var pre = "",
  1660. negative = (source < 0),
  1661. string = String(Math.abs(source));
  1662. if (string.length < length) {
  1663. pre = (new Array(length - string.length + 1)).join('0');
  1664. }
  1665. return (negative ? "-" : "") + pre + string;
  1666. };
  1667. /*
  1668. * Tangram
  1669. * Copyright 2009 Baidu Inc. All rights reserved.
  1670. *
  1671. * path: baidu/date/format.js
  1672. * author: erik
  1673. * version: 1.1.0
  1674. * date: 2009/12/04
  1675. */
  1676. /**
  1677. * 对目标日期对象进行格式化
  1678. * @name baidu.date.format
  1679. * @function
  1680. * @grammar baidu.date.format(source, pattern)
  1681. * @param {Date} source 目标日期对象
  1682. * @param {string} pattern 日期格式化规则
  1683. * @remark
  1684. *
  1685. <b>格式表达式,变量含义:</b><br><br>
  1686. hh: 带 0 补齐的两位 12 进制时表示<br>
  1687. h: 不带 0 补齐的 12 进制时表示<br>
  1688. HH: 带 0 补齐的两位 24 进制时表示<br>
  1689. H: 不带 0 补齐的 24 进制时表示<br>
  1690. mm: 带 0 补齐两位分表示<br>
  1691. m: 不带 0 补齐分表示<br>
  1692. ss: 带 0 补齐两位秒表示<br>
  1693. s: 不带 0 补齐秒表示<br>
  1694. yyyy: 带 0 补齐的四位年表示<br>
  1695. yy: 带 0 补齐的两位年表示<br>
  1696. MM: 带 0 补齐的两位月表示<br>
  1697. M: 不带 0 补齐的月表示<br>
  1698. dd: 带 0 补齐的两位日表示<br>
  1699. d: 不带 0 补齐的日表示
  1700. *
  1701. * @returns {string} 格式化后的字符串
  1702. */
  1703. baidu.date.format = function (source, pattern) {
  1704. if ('string' != typeof pattern) {
  1705. return source.toString();
  1706. }
  1707. function replacer(patternPart, result) {
  1708. pattern = pattern.replace(patternPart, result);
  1709. }
  1710. var pad = baidu.number.pad,
  1711. year = source.getFullYear(),
  1712. month = source.getMonth() + 1,
  1713. date2 = source.getDate(),
  1714. hours = source.getHours(),
  1715. minutes = source.getMinutes(),
  1716. seconds = source.getSeconds();
  1717. replacer(/yyyy/g, pad(year, 4));
  1718. replacer(/yy/g, pad(parseInt(year.toString().slice(2), 10), 2));
  1719. replacer(/MM/g, pad(month, 2));
  1720. replacer(/M/g, month);
  1721. replacer(/dd/g, pad(date2, 2));
  1722. replacer(/d/g, date2);
  1723. replacer(/HH/g, pad(hours, 2));
  1724. replacer(/H/g, hours);
  1725. replacer(/hh/g, pad(hours % 12, 2));
  1726. replacer(/h/g, hours % 12);
  1727. replacer(/mm/g, pad(minutes, 2));
  1728. replacer(/m/g, minutes);
  1729. replacer(/ss/g, pad(seconds, 2));
  1730. replacer(/s/g, seconds);
  1731. return pattern;
  1732. };
  1733. /*
  1734. * Tangram
  1735. * Copyright 2009 Baidu Inc. All rights reserved.
  1736. *
  1737. * path: baidu/date/parse.js
  1738. * author: erik
  1739. * version: 1.1.0
  1740. * date: 2009/12/04
  1741. */
  1742. /**
  1743. * 将目标字符串转换成日期对象
  1744. * @name baidu.date.parse
  1745. * @function
  1746. * @grammar baidu.date.parse(source)
  1747. * @param {string} source 目标字符串
  1748. * @remark
  1749. *
  1750. 对于目标字符串,下面这些规则决定了 parse 方法能够成功地解析: <br>
  1751. <ol>
  1752. <li>短日期可以使用“/”或“-”作为日期分隔符,但是必须用月/日/年的格式来表示,例如"7/20/96"。</li>
  1753. <li>以 "July 10 1995" 形式表示的长日期中的年、月、日可以按任何顺序排列,年份值可以用 2 位数字表示也可以用 4 位数字表示。如果使用 2 位数字来表示年份,那么该年份必须大于或等于 70。 </li>
  1754. <li>括号中的任何文本都被视为注释。这些括号可以嵌套使用。 </li>
  1755. <li>逗号和空格被视为分隔符。允许使用多个分隔符。 </li>
  1756. <li>月和日的名称必须具有两个或两个以上的字符。如果两个字符所组成的名称不是独一无二的,那么该名称就被解析成最后一个符合条件的月或日。例如,"Ju" 被解释为七月而不是六月。 </li>
  1757. <li>在所提供的日期中,如果所指定的星期几的值与按照该日期中剩余部分所确定的星期几的值不符合,那么该指定值就会被忽略。例如,尽管 1996 年 11 月 9 日实际上是星期五,"Tuesday November 9 1996" 也还是可以被接受并进行解析的。但是结果 date 对象中包含的是 "Friday November 9 1996"。 </li>
  1758. <li>JScript 处理所有的标准时区,以及全球标准时间 (UTC) 和格林威治标准时间 (GMT)。</li>
  1759. <li>小时、分钟、和秒钟之间用冒号分隔,尽管不是这三项都需要指明。"10:"、"10:11"、和 "10:11:12" 都是有效的。 </li>
  1760. <li>如果使用 24 小时计时的时钟,那么为中午 12 点之后的时间指定 "PM" 是错误的。例如 "23:15 PM" 就是错误的。</li>
  1761. <li>包含无效日期的字符串是错误的。例如,一个包含有两个年份或两个月份的字符串就是错误的。</li>
  1762. </ol>
  1763. *
  1764. * @returns {Date} 转换后的日期对象
  1765. */
  1766. baidu.date.parse = function (source) {
  1767. var reg = new RegExp("^\\d+(\\-|\\/)\\d+(\\-|\\/)\\d+\x24");
  1768. if ('string' == typeof source) {
  1769. if (reg.test(source) || isNaN(Date.parse(source))) {
  1770. var d = source.split(/ |T/),
  1771. d1 = d.length > 1
  1772. ? d[1].split(/[^\d]/)
  1773. : [0, 0, 0],
  1774. d0 = d[0].split(/[^\d]/);
  1775. return new Date(d0[0] - 0,
  1776. d0[1] - 1,
  1777. d0[2] - 0,
  1778. d1[0] - 0,
  1779. d1[1] - 0,
  1780. d1[2] - 0);
  1781. } else {
  1782. return new Date(source);
  1783. }
  1784. }
  1785. return new Date();
  1786. };
  1787. /*
  1788. * Tangram
  1789. * Copyright 2009 Baidu Inc. All rights reserved.
  1790. *
  1791. * path: baidu/dom.js
  1792. * author: allstar, erik
  1793. * version: 1.1.0
  1794. * date: 2009/12/02
  1795. */
  1796. /**
  1797. * @namespace baidu.dom 操作dom的方法。
  1798. */
  1799. baidu.dom = baidu.dom || {};
  1800. /*
  1801. * Tangram
  1802. * Copyright 2009 Baidu Inc. All rights reserved.
  1803. *
  1804. * path: baidu/dom/g.js
  1805. * author: allstar, erik
  1806. * version: 1.1.0
  1807. * date: 2009/11/17
  1808. */
  1809. /**
  1810. * 从文档中获取指定的DOM元素
  1811. * @name baidu.dom.g
  1812. * @function
  1813. * @grammar baidu.dom.g(id)
  1814. * @param {string|HTMLElement} id 元素的id或DOM元素
  1815. * @shortcut g,T.G
  1816. * @meta standard
  1817. * @see baidu.dom.q
  1818. *
  1819. * @returns {HTMLElement|null} 获取的元素,查找不到时返回null,如果参数不合法,直接返回参数
  1820. */
  1821. baidu.dom.g = function (id) {
  1822. if ('string' == typeof id || id instanceof String) {
  1823. return document.getElementById(id);
  1824. } else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
  1825. return id;
  1826. }
  1827. return null;
  1828. };
  1829. // 声明快捷方法
  1830. baidu.g = baidu.G = baidu.dom.g;
  1831. /*
  1832. * Tangram
  1833. * Copyright 2009 Baidu Inc. All rights reserved.
  1834. *
  1835. * path: baidu/string.js
  1836. * author: erik
  1837. * version: 1.1.0
  1838. * date: 2009/11/15
  1839. */
  1840. /**
  1841. * @namespace baidu.string 操作字符串的方法。
  1842. */
  1843. baidu.string = baidu.string || {};
  1844. /*
  1845. * Tangram
  1846. * Copyright 2009 Baidu Inc. All rights reserved.
  1847. *
  1848. * path: baidu/string/trim.js
  1849. * author: dron, erik
  1850. * version: 1.1.0
  1851. * date: 2009/11/15
  1852. */
  1853. /**
  1854. * 删除目标字符串两端的空白字符
  1855. * @name baidu.string.trim
  1856. * @function
  1857. * @grammar baidu.string.trim(source)
  1858. * @param {string} source 目标字符串
  1859. * @remark
  1860. * 不支持删除单侧空白字符
  1861. * @shortcut trim
  1862. * @meta standard
  1863. *
  1864. * @returns {string} 删除两端空白字符后的字符串
  1865. */
  1866. (function () {
  1867. var trimer = new RegExp("(^[\\s\\t\\xa0\\u3000]+)|([\\u3000\\xa0\\s\\t]+\x24)", "g");
  1868. baidu.string.trim = function (source) {
  1869. return String(source)
  1870. .replace(trimer, "");
  1871. };
  1872. })();
  1873. // 声明快捷方法
  1874. baidu.trim = baidu.string.trim;
  1875. /*
  1876. * Tangram
  1877. * Copyright 2009 Baidu Inc. All right reserved.
  1878. *
  1879. * path: baidu/dom/addClass.js
  1880. * author: allstar, erik
  1881. * version: 1.1.0
  1882. * date: 2009/12/2
  1883. */
  1884. /**
  1885. * 为目标元素添加className
  1886. * @name baidu.dom.addClass
  1887. * @function
  1888. * @grammar baidu.dom.addClass(element, className)
  1889. * @param {HTMLElement|string} element 目标元素或目标元素的id
  1890. * @param {string} className 要添加的className,允许同时添加多个class,中间使用空白符分隔
  1891. * @remark
  1892. * 使用者应保证提供的className合法性,不应包含不合法字符,className合法字符参考:http://www.w3.org/TR/CSS2/syndata.html。
  1893. * @shortcut addClass
  1894. * @meta standard
  1895. * @see baidu.dom.removeClass
  1896. *
  1897. *
  1898. * @returns {HTMLElement} 目标元素
  1899. */
  1900. baidu.dom.addClass = function (element, className) {
  1901. element = baidu.dom.g(element);
  1902. var classArray = className.split(/\s+/),
  1903. result = element.className,
  1904. classMatch = " " + result + " ",
  1905. i = 0,
  1906. l = classArray.length;
  1907. for (; i < l; i++){
  1908. if ( classMatch.indexOf( " " + classArray[i] + " " ) < 0 ) {
  1909. result += (result ? ' ' : '') + classArray[i];
  1910. }
  1911. }
  1912. element.className = result;
  1913. return element;
  1914. };
  1915. // 声明快捷方法
  1916. baidu.addClass = baidu.dom.addClass;
  1917. /*
  1918. * Tangram
  1919. * Copyright 2009 Baidu Inc. All rights reserved.
  1920. *
  1921. * path: baidu/dom/children.js
  1922. * author: allstar
  1923. * version: 1.1.0
  1924. * date: 2009/11/17
  1925. */
  1926. /**
  1927. * 获取目标元素的直接子元素列表
  1928. * @name baidu.dom.children
  1929. * @function
  1930. * @grammar baidu.dom.children(element)
  1931. * @param {HTMLElement|String} element 目标元素或目标元素的id
  1932. * @meta standard
  1933. *
  1934. * @returns {Array} 目标元素的子元素列表,没有子元素时返回空数组
  1935. */
  1936. baidu.dom.children = function (element) {
  1937. element = baidu.dom.g(element);
  1938. for (var children = [], tmpEl = element.firstChild; tmpEl; tmpEl = tmpEl.nextSibling) {
  1939. if (tmpEl.nodeType == 1) {
  1940. children.push(tmpEl);
  1941. }
  1942. }
  1943. return children;
  1944. };
  1945. /*
  1946. * Tangram
  1947. * Copyright 2009 Baidu Inc. All rights reserved.
  1948. *
  1949. * path: baidu/lang/isString.js
  1950. * author: erik
  1951. * version: 1.1.0
  1952. * date: 2009/12/30
  1953. */
  1954. /**
  1955. * 判断目标参数是否string类型或String对象
  1956. * @name baidu.lang.isString
  1957. * @function
  1958. * @grammar baidu.lang.isString(source)
  1959. * @param {Any} source 目标参数
  1960. * @shortcut isString
  1961. * @meta standard
  1962. * @see baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate
  1963. *
  1964. * @returns {boolean} 类型判断结果
  1965. */
  1966. baidu.lang.isString = function (source) {
  1967. return '[object String]' == Object.prototype.toString.call(source);
  1968. };
  1969. // 声明快捷方法
  1970. baidu.isString = baidu.lang.isString;
  1971. /*
  1972. * Tangram
  1973. * Copyright 2009 Baidu Inc. All rights reserved.
  1974. *
  1975. * path: baidu/dom/g.js
  1976. * author: allstar, erik, berg
  1977. * version: 1.3
  1978. * date: 2010-07-07
  1979. */
  1980. /**
  1981. * 从文档中获取指定的DOM元素
  1982. * **内部方法**
  1983. *
  1984. * @param {string|HTMLElement} id 元素的id或DOM元素
  1985. * @meta standard
  1986. * @return {HTMLElement} DOM元素,如果不存在,返回null,如果参数不合法,直接返回参数
  1987. */
  1988. baidu.dom._g = function (id) {
  1989. if (baidu.lang.isString(id)) {
  1990. return document.getElementById(id);
  1991. }
  1992. return id;
  1993. };
  1994. // 声明快捷方法
  1995. baidu._g = baidu.dom._g;
  1996. /*
  1997. * Tangram
  1998. * Copyright 2009 Baidu Inc. All rights reserved.
  1999. *
  2000. * path: baidu/dom/contains.js
  2001. * author: allstar
  2002. * version: 1.1.0
  2003. * date: 2009/11/17
  2004. */
  2005. /**
  2006. * 判断一个元素是否包含另一个元素
  2007. * @name baidu.dom.contains
  2008. * @function
  2009. * @grammar baidu.dom.contains(container, contained)
  2010. * @param {HTMLElement|string} container 包含元素或元素的id
  2011. * @param {HTMLElement|string} contained 被包含元素或元素的id
  2012. * @meta standard
  2013. * @see baidu.dom.intersect
  2014. *
  2015. * @returns {boolean} contained元素是否被包含于container元素的DOM节点上
  2016. */
  2017. baidu.dom.contains = function (container, contained) {
  2018. var g = baidu.dom._g;
  2019. container = g(container);
  2020. contained = g(contained);
  2021. //fixme: 无法处理文本节点的情况(IE)
  2022. return container.contains
  2023. ? container != contained && container.contains(contained)
  2024. : !!(container.compareDocumentPosition(contained) & 16);
  2025. };
  2026. /*
  2027. * Tangram
  2028. * Copyright 2009 Baidu Inc. All rights reserved.
  2029. *
  2030. * path: baidu/dom/_NAME_ATTRS.js
  2031. * author: allstar, erik
  2032. * version: 1.1.0
  2033. * date: 2009/12/2
  2034. */
  2035. /**
  2036. * 提供给setAttr与getAttr方法作名称转换使用
  2037. * ie6,7下class要转换成className
  2038. * @meta standard
  2039. */
  2040. baidu.dom._NAME_ATTRS = (function () {
  2041. var result = {
  2042. 'cellpadding': 'cellPadding',
  2043. 'cellspacing': 'cellSpacing',
  2044. 'colspan': 'colSpan',
  2045. 'rowspan': 'rowSpan',
  2046. 'valign': 'vAlign',
  2047. 'usemap': 'useMap',
  2048. 'frameborder': 'frameBorder'
  2049. };
  2050. if (baidu.browser.ie < 8) {
  2051. result['for'] = 'htmlFor';
  2052. result['class'] = 'className';
  2053. } else {
  2054. result['htmlFor'] = 'for';
  2055. result['className'] = 'class';
  2056. }
  2057. return result;
  2058. })();
  2059. /*
  2060. * Tangram
  2061. * Copyright 2009 Baidu Inc. All rights reserved.
  2062. *
  2063. * path: baidu/dom/setAttr.js
  2064. * author: allstar
  2065. * version: 1.1.0
  2066. * date: 2009/11/17
  2067. */
  2068. /**
  2069. * 设置目标元素的attribute值
  2070. * @name baidu.dom.setAttr
  2071. * @function
  2072. * @grammar baidu.dom.setAttr(element, key, value)
  2073. * @param {HTMLElement|string} element 目标元素或目标元素的id
  2074. * @param {string} key 要设置的attribute键名
  2075. * @param {string} value 要设置的attribute值
  2076. * @remark
  2077. *
  2078. 设置object的自定义属性时,由于浏览器限制,无法设置。
  2079. * @shortcut setAttr
  2080. * @meta standard
  2081. * @see baidu.dom.getAttr,baidu.dom.setAttrs
  2082. *
  2083. * @returns {HTMLElement} 目标元素
  2084. */
  2085. baidu.dom.setAttr = function (element, key, value) {
  2086. element = baidu.dom.g(element);
  2087. if ('style' == key){
  2088. element.style.cssText = value;
  2089. } else {
  2090. key = baidu.dom._NAME_ATTRS[key] || key;
  2091. element.setAttribute(key, value);
  2092. }
  2093. return element;
  2094. };
  2095. // 声明快捷方法
  2096. baidu.setAttr = baidu.dom.setAttr;
  2097. /*
  2098. * Tangram
  2099. * Copyright 2009 Baidu Inc. All rights reserved.
  2100. *
  2101. * path: baidu/dom/setAttrs.js
  2102. * author: allstar
  2103. * version: 1.1.0
  2104. * date: 2009/11/17
  2105. */
  2106. /**
  2107. * 批量设置目标元素的attribute值
  2108. * @name baidu.dom.setAttrs
  2109. * @function
  2110. * @grammar baidu.dom.setAttrs(element, attributes)
  2111. * @param {HTMLElement|string} element 目标元素或目标元素的id
  2112. * @param {Object} attributes 要设置的attribute集合
  2113. * @shortcut setAttrs
  2114. * @meta standard
  2115. * @see baidu.dom.setAttr,baidu.dom.getAttr
  2116. *
  2117. * @returns {HTMLElement} 目标元素
  2118. */
  2119. baidu.dom.setAttrs = function (element, attributes) {
  2120. element = baidu.dom.g(element);
  2121. for (var key in attributes) {
  2122. baidu.dom.setAttr(element, key, attributes[key]);
  2123. }
  2124. return element;
  2125. };
  2126. // 声明快捷方法
  2127. baidu.setAttrs = baidu.dom.setAttrs;
  2128. /*
  2129. * Tangram
  2130. * Copyright 2009 Baidu Inc. All right reserved.
  2131. */
  2132. /**
  2133. * 创建 Element 对象。
  2134. * @author berg
  2135. * @name baidu.dom.create
  2136. * @function
  2137. * @grammar baidu.dom.create(tagName[, options])
  2138. * @param {string} tagName 标签名称.
  2139. * @param {Object} opt_attributes 元素创建时拥有的属性,如style和className.
  2140. * @version 1.3
  2141. * @meta standard
  2142. * @return {HTMLElement} 创建的 Element 对象
  2143. */
  2144. baidu.dom.create = function(tagName, opt_attributes) {
  2145. var el = document.createElement(tagName),
  2146. attributes = opt_attributes || {};
  2147. return baidu.dom.setAttrs(el, attributes);
  2148. };
  2149. /*
  2150. * Tangram
  2151. * Copyright 2009 Baidu Inc. All rights reserved.
  2152. *
  2153. * path: baidu/lang/guid.js
  2154. * author: meizz
  2155. * version: 1.1.0
  2156. * date: 2010/02/04
  2157. */
  2158. /**
  2159. * 返回一个当前页面的唯一标识字符串。
  2160. * @name baidu.lang.guid
  2161. * @function
  2162. * @grammar baidu.lang.guid()
  2163. * @version 1.1.1
  2164. * @meta standard
  2165. *
  2166. * @returns {String} 当前页面的唯一标识字符串
  2167. */
  2168. (function(){
  2169. //不直接使用window,可以提高3倍左右性能
  2170. var guid = window[baidu.guid];
  2171. baidu.lang.guid = function() {
  2172. return "TANGRAM__" + (guid._counter ++).toString(36);
  2173. };
  2174. guid._counter = guid._counter || 1;
  2175. })();
  2176. /*
  2177. * Tangram
  2178. * Copyright 2009 Baidu Inc. All rights reserved.
  2179. *
  2180. * path: baidu/lang/_instances.js
  2181. * author: meizz, erik
  2182. * version: 1.1.0
  2183. * date: 2009/12/1
  2184. */
  2185. /**
  2186. * 所有类的实例的容器
  2187. * key为每个实例的guid
  2188. * @meta standard
  2189. */
  2190. window[baidu.guid]._instances = window[baidu.guid]._instances || {};
  2191. /*
  2192. * Tangram
  2193. * Copyright 2009 Baidu Inc. All rights reserved.
  2194. *
  2195. * path: baidu/lang/Class.js
  2196. * author: meizz, erik
  2197. * version: 1.1.0
  2198. * date: 2009/12/1
  2199. */
  2200. /**
  2201. *
  2202. * @class Tangram继承机制提供的一个基类,用户可以通过继承baidu.lang.Class来获取它的属性及方法。
  2203. * @name baidu.lang.Class
  2204. * @grammar baidu.lang.Class(guid)
  2205. * @param {string} guid 对象的唯一标识
  2206. * @meta standard
  2207. * @remark baidu.lang.Class和它的子类的实例均包含一个全局唯一的标识guid。guid是在构造函数中生成的,因此,继承自baidu.lang.Class的类应该直接或者间接调用它的构造函数。<br>baidu.lang.Class的构造函数中产生guid的方式可以保证guid的唯一性,及每个实例都有一个全局唯一的guid。
  2208. * @meta standard
  2209. * @see baidu.lang.inherits,baidu.lang.Event
  2210. */
  2211. baidu.lang.Class = function(guid) {
  2212. this.guid = guid || baidu.lang.guid();
  2213. window[baidu.guid]._instances[this.guid] = this;
  2214. };
  2215. window[baidu.guid]._instances = window[baidu.guid]._instances || {};
  2216. /**
  2217. * 释放对象所持有的资源,主要是自定义事件。
  2218. * @name dispose
  2219. * @grammar obj.dispose()
  2220. * TODO: 将_listeners中绑定的事件剔除掉
  2221. */
  2222. baidu.lang.Class.prototype.dispose = function(){
  2223. delete window[baidu.guid]._instances[this.guid];
  2224. for(var property in this){
  2225. if (!baidu.lang.isFunction(this[property])) {
  2226. delete this[property];
  2227. }
  2228. }
  2229. this.disposed = true; // 20100716
  2230. };
  2231. /**
  2232. * 重载了默认的toString方法,使得返回信息更加准确一些。
  2233. * @return {string} 对象的String表示形式
  2234. */
  2235. baidu.lang.Class.prototype.toString = function(){
  2236. return "[object " + (this._className || "Object" ) + "]";
  2237. };
  2238. /*
  2239. * Tangram
  2240. * Copyright 2009 Baidu Inc. All rights reserved.
  2241. *
  2242. * path: baidu/lang/Event.js
  2243. * author: meizz, erik, berg
  2244. * version: 1.1.1
  2245. * date: 2009/11/24
  2246. * modify: 2010/04/19 berg
  2247. */
  2248. /**
  2249. *
  2250. * @class 自定义的事件对象。
  2251. * @name baidu.lang.Event
  2252. * @grammar baidu.lang.Event(type[, target])
  2253. * @param {string} type 事件类型名称。为了方便区分事件和一个普通的方法,事件类型名称必须以"on"(小写)开头。
  2254. * @param {Object} [target]触发事件的对象
  2255. * @meta standard
  2256. * @remark 引入该模块,会自动为Class引入3个事件扩展方法:addEventListener、removeEventListener和dispatchEvent。
  2257. * @meta standard
  2258. * @see baidu.lang.Class
  2259. */
  2260. baidu.lang.Event = function (type, target) {
  2261. this.type = type;
  2262. this.returnValue = true;
  2263. this.target = target || null;
  2264. this.currentTarget = null;
  2265. };
  2266. /**
  2267. * 注册对象的事件监听器。引入baidu.lang.Event后,Class的子类实例才会获得该方法。
  2268. * @grammar obj.addEventListener(type, handler[, key])
  2269. * @param {string} type 自定义事件的名称
  2270. * @param {Function} handler 自定义事件被触发时应该调用的回调函数
  2271. * @param {string} [key] 为事件监听函数指定的名称,可在移除时使用。如果不提供,方法会默认为它生成一个全局唯一的key。
  2272. * @remark 事件类型区分大小写。如果自定义事件名称不是以小写"on"开头,该方法会给它加上"on"再进行判断,即"click"和"onclick"会被认为是同一种事件。
  2273. */
  2274. baidu.lang.Class.prototype.addEventListener = function (type, handler, key) {
  2275. if (!baidu.lang.isFunction(handler)) {
  2276. return;
  2277. }
  2278. !this.__listeners && (this.__listeners = {});
  2279. var t = this.__listeners, id;
  2280. if (typeof key == "string" && key) {
  2281. if (/[^\w\-]/.test(key)) {
  2282. throw("nonstandard key:" + key);
  2283. } else {
  2284. handler.hashCode = key;
  2285. id = key;
  2286. }
  2287. }
  2288. type.indexOf("on") != 0 && (type = "on" + type);
  2289. typeof t[type] != "object" && (t[type] = {});
  2290. id = id || baidu.lang.guid();
  2291. handler.hashCode = id;
  2292. t[type][id] = handler;
  2293. };
  2294. /**
  2295. * 移除对象的事件监听器。引入baidu.lang.Event后,Class的子类实例才会获得该方法。
  2296. * @grammar obj.removeEventListener(type, handler)
  2297. * @param {string} type 事件类型
  2298. * @param {Function|string} handler 要移除的事件监听函数或者监听函数的key
  2299. * @remark 如果第二个参数handler没有被绑定到对应的自定义事件中,什么也不做。
  2300. */
  2301. baidu.lang.Class.prototype.removeEventListener = function (type, handler) {
  2302. if (typeof handler != "undefined") {
  2303. if ( (baidu.lang.isFunction(handler) && ! (handler = handler.hashCode))
  2304. || (! baidu.lang.isString(handler))
  2305. ){
  2306. return;
  2307. }
  2308. }
  2309. !this.__listeners && (this.__listeners = {});
  2310. type.indexOf("on") != 0 && (type = "on" + type);
  2311. var t = this.__listeners;
  2312. if (!t[type]) {
  2313. return;
  2314. }
  2315. if (typeof handler != "undefined") {
  2316. t[type][handler] && delete t[type][handler];
  2317. } else {
  2318. for(var guid in t[type]){
  2319. delete t[type][guid];
  2320. }
  2321. }
  2322. };
  2323. /**
  2324. * 派发自定义事件,使得绑定到自定义事件上面的函数都会被执行。引入baidu.lang.Event后,Class的子类实例才会获得该方法。
  2325. * @grammar obj.dispatchEvent(event, options)
  2326. * @param {baidu.lang.Event|String} event Event对象,或事件名称(1.1.1起支持)
  2327. * @param {Object} options 扩展参数,所含属性键值会扩展到Event对象上(1.2起支持)
  2328. * @remark 处理会调用通过addEventListenr绑定的自定义事件回调函数之外,还会调用直接绑定到对象上面的自定义事件。例如:<br>
  2329. myobj.onMyEvent = function(){}<br>
  2330. myobj.addEventListener("onMyEvent", function(){});
  2331. */
  2332. baidu.lang.Class.prototype.dispatchEvent = function (event, options) {
  2333. if (baidu.lang.isString(event)) {
  2334. event = new baidu.lang.Event(event);
  2335. }
  2336. !this.__listeners && (this.__listeners = {});
  2337. // 20100603 添加本方法的第二个参数,将 options extend到event中去传递
  2338. options = options || {};
  2339. for (var i in options) {
  2340. event[i] = options[i];
  2341. }
  2342. var i, t = this.__listeners, p = event.type;
  2343. event.target = event.target || this;
  2344. event.currentTarget = this;
  2345. p.indexOf("on") != 0 && (p = "on" + p);
  2346. baidu.lang.isFunction(this[p]) && this[p].apply(this, arguments);
  2347. if (typeof t[p] == "object") {
  2348. for (i in t[p]) {
  2349. t[p][i].apply(this, arguments);
  2350. }
  2351. }
  2352. return event.returnValue;
  2353. };
  2354. /*
  2355. * Tangram
  2356. * Copyright 2009 Baidu Inc. All rights reserved.
  2357. *
  2358. * path: baidu/lang/createSingle.js
  2359. * author: meizz, berg
  2360. * version: 1.1.2
  2361. * date: 2010-05-13
  2362. */
  2363. /**
  2364. * 创建一个baidu.lang.Class的单例实例
  2365. * @name baidu.lang.createSingle
  2366. * @function
  2367. * @grammar baidu.lang.createSingle(json)
  2368. * @param {Object} json 直接挂载到这个单例里的预定属性/方法
  2369. * @version 1.2
  2370. * @see baidu.lang.Class
  2371. *
  2372. * @returns {Object} 一个实例
  2373. */
  2374. baidu.lang.createSingle = function (json) {
  2375. var c = new baidu.lang.Class();
  2376. for (var key in json) {
  2377. c[key] = json[key];
  2378. }
  2379. return c;
  2380. };
  2381. /*
  2382. * Tangram
  2383. * Copyright 2010 Baidu Inc. All rights reserved.
  2384. *
  2385. * path: baidu/dom/dragManager.js
  2386. * author: rocy
  2387. * version: 1.4.0
  2388. * date: 2010/10/14
  2389. */
  2390. /**
  2391. * 拖曳管理器
  2392. * @function
  2393. * @param {HTMLElement|ID} element 被拖曳的元素
  2394. * @param {JSON} options 拖曳配置项 {toggle, autoStop, interval, capture, range, ondragstart, ondragend, ondrag}
  2395. * @return {DOMElement} 可拖拽的元素
  2396. */
  2397. baidu.dom.ddManager = baidu.lang.createSingle({
  2398. _targetsDroppingOver:{}
  2399. });
  2400. /*
  2401. * Tangram
  2402. * Copyright 2009 Baidu Inc. All rights reserved.
  2403. *
  2404. * path: baidu/dom/getDocument.js
  2405. * author: allstar
  2406. * version: 1.1.0
  2407. * date: 2009/11/17
  2408. */
  2409. /**
  2410. * 获取目标元素所属的document对象
  2411. * @name baidu.dom.getDocument
  2412. * @function
  2413. * @grammar baidu.dom.getDocument(element)
  2414. * @param {HTMLElement|string} element 目标元素或目标元素的id
  2415. * @meta standard
  2416. * @see baidu.dom.getWindow
  2417. *
  2418. * @returns {HTMLDocument} 目标元素所属的document对象
  2419. */
  2420. baidu.dom.getDocument = function (element) {
  2421. element = baidu.dom.g(element);
  2422. return element.nodeType == 9 ? element : element.ownerDocument || element.document;
  2423. };
  2424. /*
  2425. * Tangram
  2426. * Copyright 2009 Baidu Inc. All rights reserved.
  2427. */
  2428. /**
  2429. * 获取目标元素的computed style值。如果元素的样式值不能被浏览器计算,则会返回空字符串(IE)
  2430. *
  2431. * @author berg
  2432. * @name baidu.dom.getComputedStyle
  2433. * @function
  2434. * @grammar baidu.dom.getComputedStyle(element, key)
  2435. * @param {HTMLElement|string} element 目标元素或目标元素的id
  2436. * @param {string} key 要获取的样式名
  2437. *
  2438. * @see baidu.dom.getStyle
  2439. *
  2440. * @returns {string} 目标元素的computed style值
  2441. */
  2442. baidu.dom.getComputedStyle = function(element, key){
  2443. element = baidu.dom._g(element);
  2444. var doc = baidu.dom.getDocument(element),
  2445. styles;
  2446. if (doc.defaultView && doc.defaultView.getComputedStyle) {
  2447. styles = doc.defaultView.getComputedStyle(element, null);
  2448. if (styles) {
  2449. return styles[key] || styles.getPropertyValue(key);
  2450. }
  2451. }
  2452. return '';
  2453. };
  2454. /*
  2455. * Tangram
  2456. * Copyright 2009 Baidu Inc. All rights reserved.
  2457. *
  2458. * path: baidu/dom/_styleFixer.js
  2459. * author: allstar
  2460. * version: 1.1.0
  2461. * date: 2009/11/17
  2462. */
  2463. /**
  2464. * 提供给setStyle与getStyle使用
  2465. */
  2466. baidu.dom._styleFixer = baidu.dom._styleFixer || {};
  2467. /*
  2468. * Tangram
  2469. * Copyright 2009 Baidu Inc. All rights reserved.
  2470. *
  2471. * path: baidu/dom/_styleFilters.js
  2472. * author: allstar
  2473. * version: 1.1.0
  2474. * date: 2009/12/02
  2475. */
  2476. /**
  2477. * 提供给setStyle与getStyle使用
  2478. */
  2479. baidu.dom._styleFilter = baidu.dom._styleFilter || [];
  2480. /*
  2481. * Tangram
  2482. * Copyright 2009 Baidu Inc. All rights reserved.
  2483. *
  2484. * path: baidu/dom/_styleFilter/filter.js
  2485. * author: allstar, erik
  2486. * version: 1.1.0
  2487. * date: 2009/12/02
  2488. */
  2489. /**
  2490. * 为获取和设置样式的过滤器
  2491. * @private
  2492. * @meta standard
  2493. */
  2494. baidu.dom._styleFilter.filter = function (key, value, method) {
  2495. for (var i = 0, filters = baidu.dom._styleFilter, filter; filter = filters[i]; i++) {
  2496. if (filter = filter[method]) {
  2497. value = filter(key, value);
  2498. }
  2499. }
  2500. return value;
  2501. };
  2502. /*
  2503. * Tangram
  2504. * Copyright 2009 Baidu Inc. All rights reserved.
  2505. *
  2506. * path: baidu/string/toCamelCase.js
  2507. * author: erik, berg
  2508. * version: 1.2
  2509. * date: 2010-06-22
  2510. */
  2511. /**
  2512. * 将目标字符串进行驼峰化处理
  2513. * @name baidu.string.toCamelCase
  2514. * @function
  2515. * @grammar baidu.string.toCamelCase(source)
  2516. * @param {string} source 目标字符串
  2517. * @remark
  2518. * 支持单词以“-_”分隔
  2519. * @meta standard
  2520. *
  2521. * @returns {string} 驼峰化处理后的字符串
  2522. */
  2523. //todo:考虑以后去掉下划线支持?
  2524. baidu.string.toCamelCase = function (source) {
  2525. //提前判断,提高getStyle等的效率 thanks xianwei
  2526. if (source.indexOf('-') < 0 && source.indexOf('_') < 0) {
  2527. return source;
  2528. }
  2529. return source.replace(/[-_][^-_]/g, function (match) {
  2530. return match.charAt(1).toUpperCase();
  2531. });
  2532. };
  2533. /*
  2534. * Tangram
  2535. * Copyright 2009 Baidu Inc. All rights reserved.
  2536. */
  2537. /**
  2538. * 获取目标元素的样式值
  2539. * @name baidu.dom.getStyle
  2540. * @function
  2541. * @grammar baidu.dom.getStyle(element, key)
  2542. * @param {HTMLElement|string} element 目标元素或目标元素的id
  2543. * @param {string} key 要获取的样式名
  2544. * @remark
  2545. *
  2546. * 为了精简代码,本模块默认不对任何浏览器返回值进行归一化处理(如使用getStyle时,不同浏览器下可能返回rgb颜色或hex颜色),也不会修复浏览器的bug和差异性(如设置IE的float属性叫styleFloat,firefox则是cssFloat)。<br />
  2547. * baidu.dom._styleFixer和baidu.dom._styleFilter可以为本模块提供支持。<br />
  2548. * 其中_styleFilter能对颜色和px进行归一化处理,_styleFixer能对display,float,opacity,textOverflow的浏览器兼容性bug进行处理。
  2549. * @shortcut getStyle
  2550. * @meta standard
  2551. * @see baidu.dom.setStyle,baidu.dom.setStyles, baidu.dom.getComputedStyle
  2552. *
  2553. * @returns {string} 目标元素的样式值
  2554. */
  2555. // TODO
  2556. // 1. 无法解决px/em单位统一的问题(IE)
  2557. // 2. 无法解决样式值为非数字值的情况(medium等 IE)
  2558. baidu.dom.getStyle = function (element, key) {
  2559. var dom = baidu.dom;
  2560. element = dom.g(element);
  2561. key = baidu.string.toCamelCase(key);
  2562. //computed style, then cascaded style, then explicitly set style.
  2563. var value = element.style[key] ||
  2564. (element.currentStyle ? element.currentStyle[key] : "") ||
  2565. dom.getComputedStyle(element, key);
  2566. // 在取不到值的时候,用fixer进行修正
  2567. if (!value) {
  2568. var fixer = dom._styleFixer[key];
  2569. if(fixer){
  2570. value = fixer.get ? fixer.get(element) : baidu.dom.getStyle(element, fixer);
  2571. }
  2572. }
  2573. /* 检查结果过滤器 */
  2574. if (fixer = dom._styleFilter) {
  2575. value = fixer.filter(key, value, 'get');
  2576. }
  2577. return value;
  2578. };
  2579. // 声明快捷方法
  2580. baidu.getStyle = baidu.dom.getStyle;
  2581. /*
  2582. * Tangram
  2583. * Copyright 2009 Baidu Inc. All rights reserved.
  2584. *
  2585. * path: baidu/event.js
  2586. * author: erik
  2587. * version: 1.1.0
  2588. * date: 2009/12/02
  2589. */
  2590. /**
  2591. * @namespace baidu.event 屏蔽浏览器差异性的事件封装。
  2592. * @property target 事件的触发元素
  2593. * @property pageX 鼠标事件的鼠标x坐标
  2594. * @property pageY 鼠标事件的鼠标y坐标
  2595. * @property keyCode 键盘事件的键值
  2596. */
  2597. baidu.event = baidu.event || {};
  2598. /*
  2599. * Tangram
  2600. * Copyright 2009 Baidu Inc. All rights reserved.
  2601. *
  2602. * path: baidu/event/_listeners.js
  2603. * author: erik
  2604. * version: 1.1.0
  2605. * date: 2009/11/23
  2606. */
  2607. /**
  2608. * 事件监听器的存储表
  2609. * @private
  2610. * @meta standard
  2611. */
  2612. baidu.event._listeners = baidu.event._listeners || [];
  2613. /*
  2614. * Tangram
  2615. * Copyright 2009 Baidu Inc. All rights reserved.
  2616. *
  2617. * path: baidu/event/on.js
  2618. * author: erik
  2619. * version: 1.1.0
  2620. * date: 2009/12/16
  2621. */
  2622. /**
  2623. * 为目标元素添加事件监听器
  2624. * @name baidu.event.on
  2625. * @function
  2626. * @grammar baidu.event.on(element, type, listener)
  2627. * @param {HTMLElement|string|window} element 目标元素或目标元素id
  2628. * @param {string} type 事件类型
  2629. * @param {Function} listener 需要添加的监听器
  2630. * @remark
  2631. *
  2632. 1. 不支持跨浏览器的鼠标滚轮事件监听器添加<br>
  2633. 2. 改方法不为监听器灌入事件对象,以防止跨iframe事件挂载的事件对象获取失败
  2634. * @shortcut on
  2635. * @meta standard
  2636. * @see baidu.event.un
  2637. *
  2638. * @returns {HTMLElement|window} 目标元素
  2639. */
  2640. baidu.event.on = function (element, type, listener) {
  2641. type = type.replace(/^on/i, '');
  2642. element = baidu.dom._g(element);
  2643. var realListener = function (ev) {
  2644. // 1. 这里不支持EventArgument, 原因是跨frame的事件挂载
  2645. // 2. element是为了修正this
  2646. listener.call(element, ev);
  2647. },
  2648. lis = baidu.event._listeners,
  2649. filter = baidu.event._eventFilter,
  2650. afterFilter,
  2651. realType = type;
  2652. type = type.toLowerCase();
  2653. // filter过滤
  2654. if(filter && filter[type]){
  2655. afterFilter = filter[type](element, type, realListener);
  2656. realType = afterFilter.type;
  2657. realListener = afterFilter.listener;
  2658. }
  2659. // 事件监听器挂载
  2660. if (element.addEventListener) {
  2661. element.addEventListener(realType, realListener, false);
  2662. } else if (element.attachEvent) {
  2663. element.attachEvent('on' + realType, realListener);
  2664. }
  2665. // 将监听器存储到数组中
  2666. lis[lis.length] = [element, type, listener, realListener, realType];
  2667. return element;
  2668. };
  2669. // 声明快捷方法
  2670. baidu.on = baidu.event.on;
  2671. /*
  2672. * Tangram
  2673. * Copyright 2009 Baidu Inc. All rights reserved.
  2674. *
  2675. * path: baidu/event/un.js
  2676. * author: erik
  2677. * version: 1.1.0
  2678. * date: 2009/12/16
  2679. */
  2680. /**
  2681. * 为目标元素移除事件监听器
  2682. * @name baidu.event.un
  2683. * @function
  2684. * @grammar baidu.event.un(element, type, listener)
  2685. * @param {HTMLElement|string|window} element 目标元素或目标元素id
  2686. * @param {string} type 事件类型
  2687. * @param {Function} listener 需要移除的监听器
  2688. * @shortcut un
  2689. * @meta standard
  2690. * @see baidu.event.on
  2691. *
  2692. * @returns {HTMLElement|window} 目标元素
  2693. */
  2694. baidu.event.un = function (element, type, listener) {
  2695. element = baidu.dom._g(element);
  2696. type = type.replace(/^on/i, '').toLowerCase();
  2697. var lis = baidu.event._listeners,
  2698. len = lis.length,
  2699. isRemoveAll = !listener,
  2700. item,
  2701. realType, realListener;
  2702. //如果将listener的结构改成json
  2703. //可以节省掉这个循环,优化性能
  2704. //但是由于un的使用频率并不高,同时在listener不多的时候
  2705. //遍历数组的性能消耗不会对代码产生影响
  2706. //暂不考虑此优化
  2707. while (len--) {
  2708. item = lis[len];
  2709. // listener存在时,移除element的所有以listener监听的type类型事件
  2710. // listener不存在时,移除element的所有type类型事件
  2711. if (item[1] === type
  2712. && item[0] === element
  2713. && (isRemoveAll || item[2] === listener)) {
  2714. realType = item[4];
  2715. realListener = item[3];
  2716. if (element.removeEventListener) {
  2717. element.removeEventListener(realType, realListener, false);
  2718. } else if (element.detachEvent) {
  2719. element.detachEvent('on' + realType, realListener);
  2720. }
  2721. lis.splice(len, 1);
  2722. }
  2723. }
  2724. return element;
  2725. };
  2726. // 声明快捷方法
  2727. baidu.un = baidu.event.un;
  2728. /*
  2729. * Tangram
  2730. * Copyright 2009 Baidu Inc. All rights reserved.
  2731. *
  2732. * path: baidu/event/preventDefault.js
  2733. * author: erik
  2734. * version: 1.1.0
  2735. * date: 2009/11/23
  2736. */
  2737. /**
  2738. * 阻止事件的默认行为
  2739. * @name baidu.event.preventDefault
  2740. * @function
  2741. * @grammar baidu.event.preventDefault(event)
  2742. * @param {Event} event 事件对象
  2743. * @meta standard
  2744. * @see baidu.event.stop,baidu.event.stopPropagation
  2745. */
  2746. baidu.event.preventDefault = function (event) {
  2747. if (event.preventDefault) {
  2748. event.preventDefault();
  2749. } else {
  2750. event.returnValue = false;
  2751. }
  2752. };
  2753. /*
  2754. * Tangram
  2755. * Copyright 2009 Baidu Inc. All rights reserved.
  2756. *
  2757. * path: baidu/page.js
  2758. * author: erik
  2759. * version: 1.1.0
  2760. * date: 2009/11/17
  2761. */
  2762. /**
  2763. * @namespace baidu.page 对页面层面的封装,包括页面的高宽属性、以及外部css和js的动态添加。
  2764. */
  2765. baidu.page = baidu.page || {};
  2766. /*
  2767. * Tangram
  2768. * Copyright 2009 Baidu Inc. All rights reserved.
  2769. *
  2770. * path: baidu/page/getScrollTop.js
  2771. * author: erik
  2772. * version: 1.1.0
  2773. * date: 2009/11/17
  2774. */
  2775. /**
  2776. * 获取纵向滚动量
  2777. * @name baidu.page.getScrollTop
  2778. * @function
  2779. * @grammar baidu.page.getScrollTop()
  2780. * @see baidu.page.getScrollLeft
  2781. * @meta standard
  2782. * @returns {number} 纵向滚动量
  2783. */
  2784. baidu.page.getScrollTop = function () {
  2785. var d = document;
  2786. return window.pageYOffset || d.documentElement.scrollTop || d.body.scrollTop;
  2787. };
  2788. /**
  2789. * 获取横向滚动量
  2790. * @name baidu.page.getScrollLeft
  2791. * @function
  2792. * @grammar baidu.page.getScrollLeft()
  2793. * @see baidu.page.getScrollTop
  2794. *
  2795. * @returns {number} 横向滚动量
  2796. */
  2797. /*
  2798. * Tangram
  2799. * Copyright 2009 Baidu Inc. All rights reserved.
  2800. *
  2801. * path: baidu/page/getScrollLeft.js
  2802. * author: erik
  2803. * version: 1.1.0
  2804. * date: 2009/11/17
  2805. */
  2806. /**
  2807. * 获取横向滚动量
  2808. *
  2809. * @return {number} 横向滚动量
  2810. */
  2811. baidu.page.getScrollLeft = function () {
  2812. var d = document;
  2813. return window.pageXOffset || d.documentElement.scrollLeft || d.body.scrollLeft;
  2814. };
  2815. /**
  2816. * 获得页面里的目前鼠标所在的坐标
  2817. * @name baidu.page.getMousePosition
  2818. * @function
  2819. * @grammar baidu.page.getMousePosition()
  2820. * @version 1.2
  2821. *
  2822. * @returns {object} 鼠标坐标值{x:[Number], y:[Number]}
  2823. */
  2824. /*
  2825. * Tangram
  2826. * Copyright 2010 Baidu Inc. All rights reserved.
  2827. *
  2828. * path: baidu/page/getMousePosition.js
  2829. * author: meizz
  2830. * version: 1.1.0
  2831. * date: 2010/06/02
  2832. */
  2833. /**
  2834. * 取得当前页面里的目前鼠标所在的坐标(x y)
  2835. *
  2836. * @return {JSON} 当前鼠标的坐标值({x, y})
  2837. */
  2838. (function(){
  2839. baidu.page.getMousePosition = function(){
  2840. return {
  2841. x : baidu.page.getScrollLeft() + xy.x,
  2842. y : baidu.page.getScrollTop() + xy.y
  2843. };
  2844. };
  2845. var xy = {x:0, y:0};
  2846. // 监听当前网页的 mousemove 事件以获得鼠标的实时坐标
  2847. baidu.event.on(document, "onmousemove", function(e){
  2848. e = window.event || e;
  2849. xy.x = e.clientX;
  2850. xy.y = e.clientY;
  2851. });
  2852. })();
  2853. /*
  2854. * Tangram
  2855. * Copyright 2009 Baidu Inc. All rights reserved.
  2856. *
  2857. * path: baidu/dom/getPosition.js
  2858. * author: berg
  2859. * version: 1.2.0
  2860. * date: 2010/12/16
  2861. *
  2862. * thanks google closure & jquery
  2863. * 本函数部分思想来自:http://code.google.com/p/doctype/wiki/ArticlePageOffset
  2864. */
  2865. /**
  2866. * 获取目标元素相对于整个文档左上角的位置
  2867. * @name baidu.dom.getPosition
  2868. * @function
  2869. * @grammar baidu.dom.getPosition(element)
  2870. * @param {HTMLElement|string} element 目标元素或目标元素的id
  2871. * @meta standard
  2872. *
  2873. * @returns {Object} 目标元素的位置,键值为top和left的Object。
  2874. */
  2875. baidu.dom.getPosition = function (element) {
  2876. element = baidu.dom.g(element);
  2877. var doc = baidu.dom.getDocument(element),
  2878. browser = baidu.browser,
  2879. getStyle = baidu.dom.getStyle,
  2880. // Gecko 1.9版本以下用getBoxObjectFor计算位置
  2881. // 但是某些情况下是有bug的
  2882. // 对于这些有bug的情况
  2883. // 使用递归查找的方式
  2884. BUGGY_GECKO_BOX_OBJECT = browser.isGecko > 0 &&
  2885. doc.getBoxObjectFor &&
  2886. getStyle(element, 'position') == 'absolute' &&
  2887. (element.style.top === '' || element.style.left === ''),
  2888. pos = {"left":0,"top":0},
  2889. viewport = (browser.ie && !browser.isStrict) ? doc.body : doc.documentElement,
  2890. parent,
  2891. box;
  2892. if(element == viewport){
  2893. return pos;
  2894. }
  2895. if(element.getBoundingClientRect){ // IE and Gecko 1.9+
  2896. //当HTML或者BODY有border width时, 原生的getBoundingClientRect返回值是不符合预期的
  2897. //考虑到通常情况下 HTML和BODY的border只会设成0px,所以忽略该问题.
  2898. box = element.getBoundingClientRect();
  2899. pos.left = Math.floor(box.left) + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
  2900. pos.top = Math.floor(box.top) + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
  2901. // IE会给HTML元素添加一个border,默认是medium(2px)
  2902. // 但是在IE 6 7 的怪异模式下,可以被html { border: 0; } 这条css规则覆盖
  2903. // 在IE7的标准模式下,border永远是2px,这个值通过clientLeft 和 clientTop取得
  2904. // 但是。。。在IE 6 7的怪异模式,如果用户使用css覆盖了默认的medium
  2905. // clientTop和clientLeft不会更新
  2906. pos.left -= doc.documentElement.clientLeft;
  2907. pos.top -= doc.documentElement.clientTop;
  2908. var htmlDom = doc.body,
  2909. // 在这里,不使用element.style.borderLeftWidth,只有computedStyle是可信的
  2910. htmlBorderLeftWidth = parseInt(getStyle(htmlDom, 'borderLeftWidth')),
  2911. htmlBorderTopWidth = parseInt(getStyle(htmlDom, 'borderTopWidth'));
  2912. if(browser.ie && !browser.isStrict){
  2913. pos.left -= isNaN(htmlBorderLeftWidth) ? 2 : htmlBorderLeftWidth;
  2914. pos.top -= isNaN(htmlBorderTopWidth) ? 2 : htmlBorderTopWidth;
  2915. }
  2916. /*
  2917. * 因为firefox 3.6和4.0在特定页面下(场景待补充)都会出现1px偏移,所以暂时移除该逻辑分支
  2918. * 如果 2.0版本时firefox仍存在问题,该逻辑分支将彻底移除. by rocy 2011-01-20
  2919. } else if (doc.getBoxObjectFor && !BUGGY_GECKO_BOX_OBJECT){ // gecko 1.9-
  2920. // 1.9以下的Gecko,会忽略ancestors的scroll值
  2921. // https://bugzilla.mozilla.org/show_bug.cgi?id=328881 and
  2922. // https://bugzilla.mozilla.org/show_bug.cgi?id=330619
  2923. box = doc.getBoxObjectFor(element);
  2924. var vpBox = doc.getBoxObjectFor(viewport);
  2925. pos.left = box.screenX - vpBox.screenX;
  2926. pos.top = box.screenY - vpBox.screenY;
  2927. */
  2928. } else { // safari/opera/firefox
  2929. parent = element;
  2930. do {
  2931. pos.left += parent.offsetLeft;
  2932. pos.top += parent.offsetTop;
  2933. // safari里面,如果遍历到了一个fixed的元素,后面的offset都不准了
  2934. if (browser.isWebkit > 0 && getStyle(parent, 'position') == 'fixed') {
  2935. pos.left += doc.body.scrollLeft;
  2936. pos.top += doc.body.scrollTop;
  2937. break;
  2938. }
  2939. parent = parent.offsetParent;
  2940. } while (parent && parent != element);
  2941. // 对body offsetTop的修正
  2942. if(browser.opera > 0 || (browser.isWebkit > 0 && getStyle(element, 'position') == 'absolute')){
  2943. pos.top -= doc.body.offsetTop;
  2944. }
  2945. // 计算除了body的scroll
  2946. parent = element.offsetParent;
  2947. while (parent && parent != doc.body) {
  2948. pos.left -= parent.scrollLeft;
  2949. // see https://bugs.opera.com/show_bug.cgi?id=249965
  2950. // if (!b.opera || parent.tagName != 'TR') {
  2951. if (!browser.opera || parent.tagName != 'TR') {
  2952. pos.top -= parent.scrollTop;
  2953. }
  2954. parent = parent.offsetParent;
  2955. }
  2956. }
  2957. return pos;
  2958. };
  2959. /*
  2960. * Tangram
  2961. * Copyright 2010 Baidu Inc. All rights reserved.
  2962. *
  2963. * path: baidu/dom/drag.js
  2964. * author: meizz, berg, lxp
  2965. * version: 1.1.0
  2966. * date: 2010/06/02
  2967. */
  2968. /**
  2969. * 拖动指定的DOM元素
  2970. * @name baidu.dom.drag
  2971. * @function
  2972. * @grammar baidu.dom.drag(element, options)
  2973. * @param {HTMLElement|string} element 元素或者元素的id
  2974. * @param {Object} options 拖曳配置项
  2975. * @param {Array} options.range 限制drag的拖拽范围,数组中必须包含四个值,分别是上、右、下、左边缘相对上方或左方的像素距离。默认无限制
  2976. * @param {Number} options.interval 拖曳行为的触发频度(时间:毫秒)
  2977. * @param {Boolean} options.capture 鼠标拖曳粘滞
  2978. * @param {Object} options.mouseEvent 键名为clientX和clientY的object,若不设置此项,默认会获取当前鼠标位置
  2979. * @param {Function} options.ondragstart drag开始时触发
  2980. * @param {Function} options.ondrag drag进行中触发
  2981. * @param {Function} options.ondragend drag结束时触发
  2982. * @param {function} options.autoStop 是否在onmouseup时自动停止拖拽。默认为true
  2983. * @version 1.2
  2984. * @remark
  2985. *
  2986. 要拖拽的元素必须事先设定样式的postion值,如果postion为absloute,并且没有设定top和left,拖拽开始时,无法取得元素的top和left值,这时会从[0,0]点开始拖拽
  2987. * @see baidu.dom.draggable
  2988. */
  2989. /**
  2990. * 拖曳DOM元素
  2991. * @param {HTMLElement|ID} element 被拖曳的元素
  2992. * @param {JSON} options 拖曳配置项
  2993. * {autoStop, interval, capture, range, ondragstart, ondragend, ondrag, mouseEvent}
  2994. */
  2995. (function(){
  2996. var target, // 被拖曳的DOM元素
  2997. op, ox, oy, //timer,
  2998. top, left, mozUserSelect,
  2999. lastLeft, lastTop,
  3000. isFunction = baidu.lang.isFunction,
  3001. timer,
  3002. offset_parent,offset_target;
  3003. baidu.dom.drag = function(element, options) {
  3004. //每次开始拖拽的时候重置lastTop和lastLeft
  3005. lastTop = lastLeft = null;
  3006. if (!(target = baidu.dom.g(element))) return false;
  3007. op = baidu.object.extend({
  3008. autoStop:true // false 用户手动结束拖曳 | true 在mouseup时自动停止拖曳
  3009. ,capture : true // 鼠标拖曳粘滞
  3010. ,interval : 16 // 拖曳行为的触发频度(时间:毫秒)
  3011. ,handler : target
  3012. }, options);
  3013. offset_parent = baidu.dom.getPosition(target.offsetParent);
  3014. offset_target = baidu.dom.getPosition(target);
  3015. if(baidu.getStyle(target,'position') == "absolute"){
  3016. top = offset_target.top - (target.offsetParent == document.body ? 0 : offset_parent.top);
  3017. left = offset_target.left - (target.offsetParent == document.body ? 0 :offset_parent.left);
  3018. }else{
  3019. top = parseFloat(baidu.getStyle(target,"top")) || -parseFloat(baidu.getStyle(target,"bottom")) || 0;
  3020. left = parseFloat(baidu.getStyle(target,"left")) || -parseFloat(baidu.getStyle(target,"right")) || 0;
  3021. }
  3022. if(op.mouseEvent){
  3023. // [2010/11/16] 可以不依赖getMousePosition,直接通过一个可选参数获得鼠标位置
  3024. ox = baidu.page.getScrollLeft() + op.mouseEvent.clientX;
  3025. oy = baidu.page.getScrollTop() + op.mouseEvent.clientY;
  3026. }else{
  3027. var xy = baidu.page.getMousePosition(); // 得到当前鼠标坐标值
  3028. ox = xy.x;
  3029. oy = xy.y;
  3030. }
  3031. //timer = setInterval(render, op.interval);
  3032. // 这项为 true,缺省在 onmouseup 事件终止拖曳
  3033. op.autoStop && baidu.event.on(op.handler, "mouseup", stop);
  3034. op.autoStop && baidu.event.on(window, "mouseup", stop);
  3035. // 在拖曳过程中页面里的文字会被选中高亮显示,在这里修正
  3036. baidu.event.on(document, "selectstart", unselect);
  3037. // 设置鼠标粘滞
  3038. if (op.capture && op.handler.setCapture) {
  3039. op.handler.setCapture();
  3040. } else if (op.capture && window.captureEvents) {
  3041. window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
  3042. }
  3043. //baidu.on(target,"mousemove",render);
  3044. // fixed for firefox
  3045. mozUserSelect = document.body.style.MozUserSelect;
  3046. document.body.style.MozUserSelect = "none";
  3047. // ondragstart 事件
  3048. if(isFunction(op.ondragstart)){
  3049. op.ondragstart(target, op);
  3050. }
  3051. timer = setInterval(render, op.interval);
  3052. return {stop : stop, update : update};
  3053. };
  3054. /**
  3055. * 更新当前拖拽对象的属性
  3056. */
  3057. function update(options){
  3058. baidu.extend(op, options);
  3059. }
  3060. /**
  3061. * 手动停止拖拽
  3062. */
  3063. function stop() {
  3064. clearInterval(timer);
  3065. // 解除鼠标粘滞
  3066. if (op.capture && op.handler.releaseCapture) {
  3067. op.handler.releaseCapture();
  3068. } else if (op.capture && window.releaseEvents) {
  3069. window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP);
  3070. }
  3071. // 拖曳时网页内容被框选
  3072. document.body.style.MozUserSelect = mozUserSelect;
  3073. baidu.event.un(document, "selectstart", unselect);
  3074. op.autoStop && baidu.event.un(op.handler, "mouseup", stop);
  3075. op.autoStop && baidu.event.un(window, "mouseup", stop);
  3076. // ondragend 事件
  3077. if(isFunction(op.ondragend)){
  3078. op.ondragend(target, op);
  3079. }
  3080. }
  3081. // 对DOM元素进行top/left赋新值以实现拖曳的效果
  3082. function render(e) {
  3083. var rg = op.range,
  3084. xy = baidu.page.getMousePosition(),
  3085. el = left + xy.x - ox,
  3086. et = top + xy.y - oy;
  3087. // 如果用户限定了可拖动的范围
  3088. if (typeof rg == "object" && rg && rg.length == 4) {
  3089. el = Math.max(rg[3], el);
  3090. el = Math.min(rg[1] - target.offsetWidth, el);
  3091. et = Math.max(rg[0], et);
  3092. et = Math.min(rg[2] - target.offsetHeight, et);
  3093. }
  3094. target.style.top = et + "px";
  3095. target.style.left = el + "px";
  3096. if((lastLeft !== el || lastTop !== et) && (lastLeft !== null || lastTop !== null) ){
  3097. if(isFunction(op.ondrag)){
  3098. op.ondrag(target, op);
  3099. }
  3100. }
  3101. lastLeft = el;
  3102. lastTop = et;
  3103. }
  3104. // 对document.body.onselectstart事件进行监听,避免拖曳时文字被选中
  3105. function unselect(e) {
  3106. return baidu.event.preventDefault(e, false);
  3107. }
  3108. })();
  3109. /*
  3110. * Tangram
  3111. * Copyright 2009 Baidu Inc. All rights reserved.
  3112. *
  3113. * path: baidu/dom/setStyle.js
  3114. * author: allstar
  3115. * version: 1.1.0
  3116. * date: 2009/11/18
  3117. */
  3118. /**
  3119. * 设置目标元素的style样式值
  3120. * @name baidu.dom.setStyle
  3121. * @function
  3122. * @grammar baidu.dom.setStyle(element, key, value)
  3123. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3124. * @param {string} key 要设置的样式名
  3125. * @param {string} value 要设置的样式值
  3126. * @remark
  3127. *
  3128. 为了精简代码,本模块默认不对任何浏览器返回值进行归一化处理(如使用getStyle时,不同浏览器下可能返回rgb颜色或hex颜色),也不会修复浏览器的bug和差异性(如设置IE的float属性叫styleFloat,firefox则是cssFloat)。<br />
  3129. baidu.dom._styleFixer和baidu.dom._styleFilter可以为本模块提供支持。<br />
  3130. 其中_styleFilter能对颜色和px进行归一化处理,_styleFixer能对display,float,opacity,textOverflow的浏览器兼容性bug进行处理。
  3131. * @shortcut setStyle
  3132. * @meta standard
  3133. * @see baidu.dom.getStyle,baidu.dom.setStyles
  3134. *
  3135. * @returns {HTMLElement} 目标元素
  3136. */
  3137. baidu.dom.setStyle = function (element, key, value) {
  3138. var dom = baidu.dom, fixer;
  3139. // 放弃了对firefox 0.9的opacity的支持
  3140. element = dom.g(element);
  3141. key = baidu.string.toCamelCase(key);
  3142. if (fixer = dom._styleFilter) {
  3143. value = fixer.filter(key, value, 'set');
  3144. }
  3145. fixer = dom._styleFixer[key];
  3146. (fixer && fixer.set) ? fixer.set(element, value) : (element.style[fixer || key] = value);
  3147. return element;
  3148. };
  3149. // 声明快捷方法
  3150. baidu.setStyle = baidu.dom.setStyle;
  3151. /*
  3152. * Tangram
  3153. * Copyright 2010 Baidu Inc. All rights reserved.
  3154. */
  3155. /**
  3156. * 让一个DOM元素可拖拽
  3157. * @name baidu.dom.draggable
  3158. * @function
  3159. * @grammar baidu.dom.draggable(element[, options])
  3160. * @param {string|HTMLElement} element 元素或者元素的ID.
  3161. * @param {Object} [options] 选项.
  3162. * @config {Array} [range] 限制drag的拖拽范围,数组中必须包含四个值,分别是上、右、下、左边缘相对上方或左方的像素距离。默认无限制.
  3163. * @config {Number} [interval] 拖曳行为的触发频度(时间:毫秒).
  3164. * @config {Boolean} [capture] 鼠标拖曳粘滞.
  3165. * @config {Object} [mouseEvent] 键名为clientX和clientY的object,若不设置此项,默认会获取当前鼠标位置.
  3166. * @config {Function} [onbeforedragstart] drag开始前触发(即鼠标按下时).
  3167. * @config {Function} [ondragstart] drag开始时触发.
  3168. * @config {Function} [ondrag] drag进行中触发.
  3169. * @config {Function} [ondragend] drag结束时触发.
  3170. * @config {HTMLElement} [handler] 用于拖拽的手柄,比如dialog的title.
  3171. * @config {Function} [toggle] 在每次ondrag的时候,会调用这个方法判断是否应该停止拖拽。如果此函数返回值为false,则停止拖拽.
  3172. * @version 1.2
  3173. * @remark 要拖拽的元素必须事先设定样式的postion值,如果postion为absloute,并且没有设定top和left,拖拽开始时,无法取得元素的top和left值,这时会从[0,0]点开始拖拽<br>如果要拖拽的元素是static定位,会被改成relative定位方式。
  3174. * @see baidu.dom.drag
  3175. * @return {Draggable Instance} 拖拽实例,包含cancel方法,可以停止拖拽.
  3176. */
  3177. baidu.dom.draggable = function(element, options) {
  3178. options = baidu.object.extend({toggle: function() {return true}}, options || {});
  3179. options.autoStop = true;
  3180. element = baidu.dom.g(element);
  3181. options.handler = options.handler || element;
  3182. var manager,
  3183. events = ['ondragstart', 'ondrag', 'ondragend'],
  3184. i = events.length - 1,
  3185. eventName,
  3186. dragSingle,
  3187. draggableSingle = {
  3188. dispose: function() {
  3189. dragSingle && dragSingle.stop();
  3190. baidu.event.un(options.handler, 'onmousedown', handlerMouseDown);
  3191. baidu.lang.Class.prototype.dispose.call(draggableSingle);
  3192. }
  3193. },
  3194. me = this;
  3195. //如果存在ddManager, 将事件转发到ddManager中
  3196. if (manager = baidu.dom.ddManager) {
  3197. for (; i >= 0; i--) {
  3198. eventName = events[i];
  3199. options[eventName] = (function(eventName) {
  3200. var fn = options[eventName];
  3201. return function() {
  3202. baidu.lang.isFunction(fn) && fn.apply(me, arguments);
  3203. manager.dispatchEvent(eventName, {DOM: element});
  3204. }
  3205. })(eventName);
  3206. }
  3207. }
  3208. // 拖曳只针对有 position 定位的元素
  3209. if (element) {
  3210. function handlerMouseDown(e) {
  3211. var event = options.mouseEvent = window.event || e;
  3212. if (event.button > 1 //只支持鼠标左键拖拽; 左键代码: IE为1,W3C为0
  3213. // 可以通过配置项里的这个开关函数暂停或启用拖曳功能
  3214. || (baidu.lang.isFunction(options.toggle) && !options.toggle())) {
  3215. return;
  3216. }
  3217. if (baidu.dom.getStyle(element, 'position') == 'static') {
  3218. baidu.dom.setStyle(element, 'position', 'relative');
  3219. }
  3220. if (baidu.lang.isFunction(options.onbeforedragstart)) {
  3221. options.onbeforedragstart(element);
  3222. }
  3223. dragSingle = baidu.dom.drag(element, options);
  3224. draggableSingle.stop = dragSingle.stop;
  3225. draggableSingle.update = dragSingle.update;
  3226. //防止ff下出现禁止拖拽的图标
  3227. baidu.event.preventDefault(event);
  3228. }
  3229. // 对拖曳的扳机元素监听 onmousedown 事件,以便进行拖曳行为
  3230. baidu.event.on(options.handler, 'onmousedown', handlerMouseDown);
  3231. }
  3232. return {
  3233. cancel: function() {
  3234. draggableSingle.dispose();
  3235. }
  3236. };
  3237. };
  3238. /*
  3239. * Tangram
  3240. * Copyright 2009 Baidu Inc. All rights reserved.
  3241. *
  3242. * path: baidu/dom/intersect.js
  3243. * author: allstar
  3244. * version: 1.1.0
  3245. * date: 2009/12/02
  3246. */
  3247. /**
  3248. * 检查两个元素是否相交
  3249. * @name baidu.dom.intersect
  3250. * @function
  3251. * @grammar baidu.dom.intersect(element1, element2)
  3252. * @param {HTMLElement|string} element1 要检查的元素或元素的id
  3253. * @param {HTMLElement|string} element2 要检查的元素或元素的id
  3254. * @see baidu.dom.contains
  3255. *
  3256. * @returns {boolean} 两个元素是否相交的检查结果
  3257. */
  3258. baidu.dom.intersect = function (element1, element2) {
  3259. var g = baidu.dom.g,
  3260. getPosition = baidu.dom.getPosition,
  3261. max = Math.max,
  3262. min = Math.min;
  3263. element1 = g(element1);
  3264. element2 = g(element2);
  3265. var pos1 = getPosition(element1),
  3266. pos2 = getPosition(element2);
  3267. return max(pos1.left, pos2.left) <= min(pos1.left + element1.offsetWidth, pos2.left + element2.offsetWidth)
  3268. && max(pos1.top, pos2.top) <= min(pos1.top + element1.offsetHeight, pos2.top + element2.offsetHeight);
  3269. };
  3270. /*
  3271. * Tangram
  3272. * Copyright 2010 Baidu Inc. All rights reserved.
  3273. *
  3274. * path: baidu/dom/droppable.js
  3275. * author: rocy
  3276. * version: 1.4.0
  3277. * date: 2010/10/14
  3278. */
  3279. //TODO: 添加对 accept, hoverclass 等参数的支持.
  3280. /**
  3281. * 让一个DOM元素可以容纳被拖拽的DOM元素
  3282. * @name baidu.dom.droppable
  3283. * @function
  3284. * @grammar baidu.dom.droppable(element[, options])
  3285. * @param {HTMLElement|string} element 容器元素或者容器元素的ID
  3286. * @param {Object} [options] 选项,拖拽元素对于容器元素的事件
  3287. * @config {Function} [ondrop] 当元素放到容器元素内部触发
  3288. * @config {Function} [ondropover] 当元素在容器元素上方时触发
  3289. * @config {Function} [ondropout] 当元素移除容器元素时触发
  3290. * @version 1.3
  3291. * @remark
  3292. *
  3293. 需要将元素和容器元素的定位都设置为absolute
  3294. * @see baidu.dom.droppable
  3295. *
  3296. * @returns {Function} cancel取消拖拽
  3297. */
  3298. baidu.dom.droppable = function(element, options){
  3299. options = options || {};
  3300. var manager = baidu.dom.ddManager,
  3301. target = baidu.dom.g(element),
  3302. guid = baidu.lang.guid(),
  3303. //拖拽进行时判断
  3304. _dragging = function(event){
  3305. var _targetsDroppingOver = manager._targetsDroppingOver,
  3306. eventData = {trigger:event.DOM,reciever: target};
  3307. //判断被拖拽元素和容器是否相撞
  3308. if(baidu.dom.intersect(target, event.DOM)){
  3309. //进入容器区域
  3310. if(! _targetsDroppingOver[guid]){
  3311. //初次进入
  3312. (typeof options.ondropover == 'function') && options.ondropover.call(target,eventData);
  3313. manager.dispatchEvent("ondropover", eventData);
  3314. _targetsDroppingOver[guid] = true;
  3315. }
  3316. } else {
  3317. //出了容器区域
  3318. if(_targetsDroppingOver[guid]){
  3319. (typeof options.ondropout == 'function') && options.ondropout.call(target,eventData);
  3320. manager.dispatchEvent("ondropout", eventData);
  3321. }
  3322. delete _targetsDroppingOver[guid];
  3323. }
  3324. },
  3325. //拖拽结束时判断
  3326. _dragend = function(event){
  3327. var eventData = {trigger:event.DOM,reciever: target};
  3328. if(baidu.dom.intersect(target, event.DOM)){
  3329. typeof options.ondrop == 'function' && options.ondrop.call(target, eventData);
  3330. manager.dispatchEvent("ondrop", eventData);
  3331. }
  3332. delete manager._targetsDroppingOver[guid];
  3333. };
  3334. //事件注册,return object提供事件解除
  3335. manager.addEventListener("ondrag", _dragging);
  3336. manager.addEventListener("ondragend", _dragend);
  3337. return {
  3338. cancel : function(){
  3339. manager.removeEventListener("ondrag", _dragging);
  3340. manager.removeEventListener("ondragend",_dragend);
  3341. }
  3342. };
  3343. };
  3344. /*
  3345. * Tangram
  3346. * Copyright 2009 Baidu Inc. All rights reserved.
  3347. *
  3348. * path: baidu/dom/empty.js
  3349. * author: berg
  3350. * version: 1.0
  3351. * date: 2010-07-06
  3352. */
  3353. /**
  3354. * 删除一个节点下面的所有子节点。
  3355. * @name baidu.dom.empty
  3356. * @function
  3357. * @grammar baidu.dom.empty(element)
  3358. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3359. * @version 1.3
  3360. *
  3361. * @returns {HTMLElement} 目标元素
  3362. */
  3363. baidu.dom.empty = function (element) {
  3364. element = baidu.dom.g(element);
  3365. while(element.firstChild){
  3366. element.removeChild(element.firstChild);
  3367. }
  3368. //todo:删除元素上绑定的事件等?
  3369. return element;
  3370. };
  3371. /*
  3372. * Tangram
  3373. * Copyright 2009 Baidu Inc. All rights reserved.
  3374. *
  3375. * path: baidu/dom/_matchNode.js
  3376. * author: allstar
  3377. * version: 1.1.0
  3378. * date: 2009/11/18
  3379. */
  3380. /**
  3381. * 从目标元素指定的方向搜索元素
  3382. *
  3383. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3384. * @param {string} direction 遍历的方向名称,取值为previousSibling,nextSibling
  3385. * @param {string} start 遍历的开始位置,取值为firstChild,lastChild,previousSibling,nextSibling
  3386. * @meta standard
  3387. * @return {HTMLElement} 搜索到的元素,如果没有找到,返回 null
  3388. */
  3389. baidu.dom._matchNode = function (element, direction, start) {
  3390. element = baidu.dom.g(element);
  3391. for (var node = element[start]; node; node = node[direction]) {
  3392. if (node.nodeType == 1) {
  3393. return node;
  3394. }
  3395. }
  3396. return null;
  3397. };
  3398. /*
  3399. * Tangram
  3400. * Copyright 2009 Baidu Inc. All rights reserved.
  3401. *
  3402. * path: baidu/dom/first.js
  3403. * author: allstar, erik
  3404. * version: 1.1.0
  3405. * date: 2009/11/18
  3406. */
  3407. /**
  3408. * 获取目标元素的第一个元素节点
  3409. * @name baidu.dom.first
  3410. * @function
  3411. * @grammar baidu.dom.first(element)
  3412. * @param {HTMLElement|String} element 目标元素或目标元素的id
  3413. * @see baidu.dom.last,baidu.dom.prev,baidu.dom.next
  3414. * @meta standard
  3415. * @returns {HTMLElement|null} 目标元素的第一个元素节点,查找不到时返回null
  3416. */
  3417. baidu.dom.first = function (element) {
  3418. return baidu.dom._matchNode(element, 'nextSibling', 'firstChild');
  3419. };
  3420. /*
  3421. * Tangram
  3422. * Copyright 2009 Baidu Inc. All rights reserved.
  3423. *
  3424. * path: baidu/dom/getAttr.js
  3425. * author: allstar, erik
  3426. * version: 1.1.0
  3427. * date: 2009/12/02
  3428. */
  3429. /**
  3430. * 获取目标元素的属性值
  3431. * @name baidu.dom.getAttr
  3432. * @function
  3433. * @grammar baidu.dom.getAttr(element, key)
  3434. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3435. * @param {string} key 要获取的attribute键名
  3436. * @shortcut getAttr
  3437. * @meta standard
  3438. * @see baidu.dom.setAttr,baidu.dom.setAttrs
  3439. *
  3440. * @returns {string|null} 目标元素的attribute值,获取不到时返回null
  3441. */
  3442. baidu.dom.getAttr = function (element, key) {
  3443. element = baidu.dom.g(element);
  3444. if ('style' == key){
  3445. return element.style.cssText;
  3446. }
  3447. key = baidu.dom._NAME_ATTRS[key] || key;
  3448. return element.getAttribute(key);
  3449. };
  3450. // 声明快捷方法
  3451. baidu.getAttr = baidu.dom.getAttr;
  3452. /*
  3453. * Tangram
  3454. * Copyright 2009 Baidu Inc. All rights reserved.
  3455. *
  3456. * path: baidu/dom/setStyles.js
  3457. * author: allstar
  3458. * version: 1.1.0
  3459. * date: 2009/11/18
  3460. */
  3461. /**
  3462. * 批量设置目标元素的style样式值
  3463. * @name baidu.dom.setStyles
  3464. * @function
  3465. * @grammar baidu.dom.setStyles(element, styles)
  3466. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3467. * @param {Object} styles 要设置的样式集合
  3468. * @shortcut setStyles
  3469. * @meta standard
  3470. * @see baidu.dom.setStyle,baidu.dom.getStyle
  3471. *
  3472. * @returns {HTMLElement} 目标元素
  3473. */
  3474. baidu.dom.setStyles = function (element, styles) {
  3475. element = baidu.dom.g(element);
  3476. for (var key in styles) {
  3477. baidu.dom.setStyle(element, key, styles[key]);
  3478. }
  3479. return element;
  3480. };
  3481. // 声明快捷方法
  3482. baidu.setStyles = baidu.dom.setStyles;
  3483. /*
  3484. * Tangram
  3485. * Copyright 2009 Baidu Inc. All rights reserved.
  3486. *
  3487. * path: baidu/page/getViewHeight.js
  3488. * author: allstar
  3489. * version: 1.1.0
  3490. * date: 2009/11/20
  3491. */
  3492. /**
  3493. * 获取页面视觉区域高度
  3494. * @name baidu.page.getViewHeight
  3495. * @function
  3496. * @grammar baidu.page.getViewHeight()
  3497. * @see baidu.page.getViewWidth
  3498. * @meta standard
  3499. * @returns {number} 页面视觉区域高度
  3500. */
  3501. baidu.page.getViewHeight = function () {
  3502. var doc = document,
  3503. client = doc.compatMode == 'BackCompat' ? doc.body : doc.documentElement;
  3504. return client.clientHeight;
  3505. };
  3506. /*
  3507. * Tangram
  3508. * Copyright 2009 Baidu Inc. All rights reserved.
  3509. *
  3510. * path: baidu/page/getViewWidth.js
  3511. * author: allstar
  3512. * version: 1.1.0
  3513. * date: 2009/11/20
  3514. */
  3515. /**
  3516. * 获取页面视觉区域宽度
  3517. * @name baidu.page.getViewWidth
  3518. * @function
  3519. * @grammar baidu.page.getViewWidth()
  3520. * @see baidu.page.getViewHeight
  3521. *
  3522. * @returns {number} 页面视觉区域宽度
  3523. */
  3524. baidu.page.getViewWidth = function () {
  3525. var doc = document,
  3526. client = doc.compatMode == 'BackCompat' ? doc.body : doc.documentElement;
  3527. return client.clientWidth;
  3528. };
  3529. /*
  3530. * Tangram
  3531. * Copyright 2009 Baidu Inc. All rights reserved.
  3532. *
  3533. * path: baidu/dom/_styleFilter/px.js
  3534. * author: allstar, erik
  3535. * version: 1.1.0
  3536. * date: 2009/12/02
  3537. */
  3538. /**
  3539. * 提供给setStyle与getStyle使用
  3540. * @meta standard
  3541. */
  3542. baidu.dom._styleFilter[baidu.dom._styleFilter.length] = {
  3543. set: function (key, value) {
  3544. if (value.constructor == Number
  3545. && !/zIndex|fontWeight|opacity|zoom|lineHeight/i.test(key)){
  3546. value = value + "px";
  3547. }
  3548. return value;
  3549. }
  3550. };
  3551. /*
  3552. * Tangram
  3553. * Copyright 2010 Baidu Inc. All right reserved.
  3554. */
  3555. /**
  3556. * 使目标元素拥有可进行与页面可见区域相对位置保持不变的移动的能力
  3557. * @name T.dom.fixable
  3558. * @function
  3559. * @param {HTMLElement|String} element 目标元素或目标元素的id
  3560. * @param {Object} options 配置项
  3561. * @config {String} [vertival] 取值[top|bottom] 默认值 top
  3562. * @config {Strgin} [horizontal] 取值[left|right] 默认值 left
  3563. * @config {Object} [offset] {x:String|Number, y:String|Number}} 横向与纵向的取值
  3564. * @config {Boolean} [autofix] 是否自动进行fix,默认值为true
  3565. * @config {Function} [onrender] 当被渲染时候触发
  3566. * @config {Function} [onupdate] 当位置被更新的时候触发
  3567. * @config {Function} [onrelease] 当被释放的时候触发
  3568. * @return {Object} 返回值一个对象,有三个方法:render、update、release
  3569. */
  3570. baidu.dom.fixable = function(element, options){
  3571. var target = baidu.g(element),
  3572. isUnderIE7 = baidu.browser.ie && baidu.browser.ie <= 7 ? true : false,
  3573. vertival = options.vertival || 'top',
  3574. horizontal = options.horizontal || 'left',
  3575. autofix = typeof options.autofix != 'undefined' ? options.autofix : true,
  3576. origPos,offset,isRender = false,
  3577. onrender = options.onrender || new Function(),
  3578. onupdate = options.onupdate || new Function(),
  3579. onrelease = options.onrelease || new Function();
  3580. if(!target) return;
  3581. //获取target原始值
  3582. origPos = _getOriginalStyle();
  3583. //设置offset值
  3584. offset = {
  3585. y: isUnderIE7 ? (origPos.position == "static" ? baidu.dom.getPosition(target).top : baidu.dom.getPosition(target).top - baidu.dom.getPosition(target.parentNode).top) : target.offsetTop,
  3586. x: isUnderIE7 ? (origPos.position == "static" ? baidu.dom.getPosition(target).left : baidu.dom.getPosition(target).left - baidu.dom.getPosition(target.parentNode).left) : target.offsetLeft
  3587. };
  3588. baidu.extend(offset, options.offset || {});
  3589. autofix && render();
  3590. function _convert(){
  3591. return {
  3592. top : vertival == "top" ? offset.y : baidu.page.getViewHeight() - offset.y - origPos.height,
  3593. left: horizontal == "left" ? offset.x : baidu.page.getViewWidth() - offset.x - origPos.width
  3594. };
  3595. }
  3596. /**
  3597. *
  3598. */
  3599. function _handleOnMove(){
  3600. var p = _convert();
  3601. target.style.setExpression("left","eval((document.body.scrollLeft || document.documentElement.scrollLeft) + " + p.left + ") + 'px'");
  3602. target.style.setExpression("top", "eval((document.body.scrollTop || document.documentElement.scrollTop) + " + p.top + ") + 'px'");
  3603. }
  3604. /**
  3605. * 返回target原始position值
  3606. * @return {Object}
  3607. */
  3608. function _getOriginalStyle(){
  3609. var result = {
  3610. position: baidu.getStyle(target,"position"),
  3611. height: function(){
  3612. var h = baidu.getStyle(target,"height");
  3613. return (h != "auto") ? (/\d+/.exec(h)[0]) : target.offsetHeight;
  3614. }(),
  3615. width: function(){
  3616. var w = baidu.getStyle(target,"width");
  3617. return (w != "auto") ? (/\d+/.exec(w)[0]) : target.offsetWidth;
  3618. }()
  3619. };
  3620. _getValue('top', result);
  3621. _getValue('left', result);
  3622. _getValue('bottom', result);
  3623. _getValue('right', result);
  3624. return result;
  3625. }
  3626. function _getValue(position, options){
  3627. var result;
  3628. if(options.position == 'static'){
  3629. options[position] = '';
  3630. }else{
  3631. result = baidu.getStyle(target, position);
  3632. if(result == 'auto' || result == '0px' ){
  3633. options[position] = '';
  3634. }else{
  3635. options[position] = result;
  3636. }
  3637. }
  3638. }
  3639. function render(){
  3640. if(isRender) return;
  3641. baidu.setStyles(target, {top:'', left:'', bottom:'', right:''});
  3642. if(!isUnderIE7){
  3643. var style = {position:"fixed"};
  3644. style[vertival == "top" ? "top" : "bottom"] = offset.y + "px";
  3645. style[horizontal == "left" ? "left" : "right"] = offset.x + "px";
  3646. baidu.setStyles(target, style);
  3647. }else{
  3648. baidu.setStyle(target,"position","absolute");
  3649. _handleOnMove();
  3650. }
  3651. onrender();
  3652. isRender = true;
  3653. }
  3654. function release(){
  3655. if(!isRender) return;
  3656. var style = {
  3657. position: origPos.position,
  3658. left: origPos.left == '' ? 'auto' : origPos.left,
  3659. top: origPos.top == '' ? 'auto' : origPos.top,
  3660. bottom: origPos.bottom == '' ? 'auto' : origPos.bottom,
  3661. right: origPos.right == '' ? 'auto' : origPos.right
  3662. };
  3663. if(isUnderIE7){
  3664. target.style.removeExpression("left");
  3665. target.style.removeExpression("top");
  3666. }
  3667. baidu.setStyles(target, style);
  3668. onrelease();
  3669. isRender = false;
  3670. }
  3671. function update(options){
  3672. if(!options) return;
  3673. //更新事件
  3674. onrender = options.onrender || onrender;
  3675. onupdate = options.onupdate || onupdate;
  3676. onrelease = options.onrelease || onrelease;
  3677. //更新设置
  3678. vertival = options.vertival || 'top';
  3679. horizontal = options.horizontal || 'left';
  3680. //更新offset
  3681. baidu.extend(offset, options.offset || {});
  3682. onupdate();
  3683. }
  3684. return {render: render, update: update, release:release};
  3685. };
  3686. /*
  3687. * Tangram
  3688. * Copyright 2009 Baidu Inc. All rights reserved.
  3689. *
  3690. * path: baidu/dom/getAncestorBy.js
  3691. * author: allstar, erik
  3692. * version: 1.1.0
  3693. * date: 2009/12/02
  3694. */
  3695. /**
  3696. * 获取目标元素符合条件的最近的祖先元素
  3697. * @name baidu.dom.getAncestorBy
  3698. * @function
  3699. * @grammar baidu.dom.getAncestorBy(element, method)
  3700. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3701. * @param {Function} method 判断祖先元素条件的函数,function (element)
  3702. * @see baidu.dom.getAncestorByTag,baidu.dom.getAncestorByClass
  3703. *
  3704. * @returns {HTMLElement|null} 符合条件的最近的祖先元素,查找不到时返回null
  3705. */
  3706. baidu.dom.getAncestorBy = function (element, method) {
  3707. element = baidu.dom.g(element);
  3708. while ((element = element.parentNode) && element.nodeType == 1) {
  3709. if (method(element)) {
  3710. return element;
  3711. }
  3712. }
  3713. return null;
  3714. };
  3715. /*
  3716. * Tangram
  3717. * Copyright 2009 Baidu Inc. All rights reserved.
  3718. *
  3719. * path: baidu/dom/getAncestorByClass.js
  3720. * author: allstar, erik
  3721. * version: 1.1.0
  3722. * date: 2009/12/02
  3723. */
  3724. /**
  3725. * 获取目标元素指定元素className最近的祖先元素
  3726. * @name baidu.dom.getAncestorByClass
  3727. * @function
  3728. * @grammar baidu.dom.getAncestorByClass(element, className)
  3729. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3730. * @param {string} className 祖先元素的class,只支持单个class
  3731. * @remark 使用者应保证提供的className合法性,不应包含不合法字符,className合法字符参考:http://www.w3.org/TR/CSS2/syndata.html。
  3732. * @see baidu.dom.getAncestorBy,baidu.dom.getAncestorByTag
  3733. *
  3734. * @returns {HTMLElement|null} 指定元素className最近的祖先元素,查找不到时返回null
  3735. */
  3736. baidu.dom.getAncestorByClass = function (element, className) {
  3737. element = baidu.dom.g(element);
  3738. className = new RegExp("(^|\\s)" + baidu.string.trim(className) + "(\\s|\x24)");
  3739. while ((element = element.parentNode) && element.nodeType == 1) {
  3740. if (className.test(element.className)) {
  3741. return element;
  3742. }
  3743. }
  3744. return null;
  3745. };
  3746. /*
  3747. * Tangram
  3748. * Copyright 2009 Baidu Inc. All rights reserved.
  3749. *
  3750. * path: baidu/dom/getAncestorByTag.js
  3751. * author: allstar, erik
  3752. * version: 1.1.0
  3753. * date: 2009/12/02
  3754. */
  3755. /**
  3756. * 获取目标元素指定标签的最近的祖先元素
  3757. * @name baidu.dom.getAncestorByTag
  3758. * @function
  3759. * @grammar baidu.dom.getAncestorByTag(element, tagName)
  3760. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3761. * @param {string} tagName 祖先元素的标签名
  3762. * @see baidu.dom.getAncestorBy,baidu.dom.getAncestorByClass
  3763. *
  3764. * @returns {HTMLElement|null} 指定标签的最近的祖先元素,查找不到时返回null
  3765. */
  3766. baidu.dom.getAncestorByTag = function (element, tagName) {
  3767. element = baidu.dom.g(element);
  3768. tagName = tagName.toUpperCase();
  3769. while ((element = element.parentNode) && element.nodeType == 1) {
  3770. if (element.tagName == tagName) {
  3771. return element;
  3772. }
  3773. }
  3774. return null;
  3775. };
  3776. /*
  3777. * Tangram
  3778. * Copyright 2009 Baidu Inc. All right reserved.
  3779. *
  3780. * path: baidu/dom/getParent.js
  3781. * author: berg
  3782. * version: 1.0.0
  3783. * date: 2010/12/02
  3784. */
  3785. /**
  3786. * 获得元素的父节点
  3787. * @name baidu.dom.getParent
  3788. * @function
  3789. * @grammar baidu.dom.getParent(element)
  3790. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3791. * @return {HTMLElement|null} 父元素,如果找不到父元素,返回null
  3792. */
  3793. baidu.dom.getParent = function (element) {
  3794. element = baidu.dom._g(element);
  3795. //parentElement在IE下准确,parentNode在ie下可能不准确
  3796. return element.parentElement || element.parentNode || null;
  3797. };
  3798. /*
  3799. * Tangram
  3800. * Copyright 2009 Baidu Inc. All rights reserved.
  3801. *
  3802. * path: baidu/dom/getText.js
  3803. * author: berg
  3804. * version: 1.0
  3805. * date: 2010/07/16
  3806. */
  3807. /**
  3808. * 获得元素中的文本内容。
  3809. * @name baidu.dom.getText
  3810. * @function
  3811. * @grammar baidu.dom.getText(element)
  3812. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3813. * @version 1.3
  3814. *
  3815. * @returns {String} 元素中文本的内容
  3816. */
  3817. baidu.dom.getText = function (element) {
  3818. var ret = "", childs, i=0, l;
  3819. element = baidu._g(element);
  3820. // text 和 CDATA 节点,取nodeValue
  3821. if ( element.nodeType === 3 || element.nodeType === 4 ) {
  3822. ret += element.nodeValue;
  3823. } else if ( element.nodeType !== 8 ) {// 8 是 comment Node
  3824. childs = element.childNodes;
  3825. for(l = childs.length; i < l; i++){
  3826. ret += baidu.dom.getText(childs[i]);
  3827. }
  3828. }
  3829. return ret;
  3830. };
  3831. /*
  3832. * Tangram
  3833. * Copyright 2009 Baidu Inc. All rights reserved.
  3834. *
  3835. * path: baidu/dom/getWindow.js
  3836. * author: allstar, erik
  3837. * version: 1.1.0
  3838. * date: 2009/12/02
  3839. */
  3840. /**
  3841. * 获取目标元素所属的window对象
  3842. * @name baidu.dom.getWindow
  3843. * @function
  3844. * @grammar baidu.dom.getWindow(element)
  3845. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3846. * @see baidu.dom.getDocument
  3847. *
  3848. * @returns {window} 目标元素所属的window对象
  3849. */
  3850. baidu.dom.getWindow = function (element) {
  3851. element = baidu.dom.g(element);
  3852. var doc = baidu.dom.getDocument(element);
  3853. // 没有考虑版本低于safari2的情况
  3854. // @see goog/dom/dom.js#goog.dom.DomHelper.prototype.getWindow
  3855. return doc.parentWindow || doc.defaultView || null;
  3856. };
  3857. /*
  3858. * Tangram
  3859. * Copyright 2009 Baidu Inc. All rights reserved.
  3860. *
  3861. * path: baidu/dom/hasAttr.js
  3862. * author: berg
  3863. * version: 1.0
  3864. * date: 2010/07/16
  3865. */
  3866. /**
  3867. * 查询一个元素是否包含指定的属性
  3868. * @name baidu.dom.hasAttr
  3869. * @function
  3870. * @grammar baidu.dom.hasAttr(element, name)
  3871. * @param {DOMElement|string} element DOM元素或元素的id
  3872. * @param {string} name 要查找的属性名
  3873. * @version 1.3
  3874. *
  3875. * @returns {Boolean} 是否包含此属性
  3876. */
  3877. baidu.dom.hasAttr = function (element, name){
  3878. element = baidu.g(element);
  3879. var attr = element.attributes.getNamedItem(name);
  3880. return !!( attr && attr.specified );
  3881. };
  3882. /*
  3883. * Tangram
  3884. * Copyright 2009 Baidu Inc. All rights reserved.
  3885. *
  3886. * path: baidu/dom/hasClass.js
  3887. * author: berg
  3888. * version: 1.0
  3889. * date: 2010-07-06
  3890. */
  3891. /**
  3892. * 判断元素是否拥有指定的className
  3893. * @name baidu.dom.hasClass
  3894. * @function
  3895. * @grammar baidu.dom.hasClass(element, className)
  3896. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3897. * @param {string} className 要判断的className,可以是用空格拼接的多个className
  3898. * @version 1.2
  3899. * @remark
  3900. * 对于参数className,支持空格分隔的多个className
  3901. * @see baidu.dom.addClass, baidu.dom.removeClass
  3902. * @meta standard
  3903. * @returns {Boolean} 是否拥有指定的className,如果要查询的classname有一个或多个不在元素的className中,返回false
  3904. */
  3905. baidu.dom.hasClass = function (element, className) {
  3906. element = baidu.dom.g(element);
  3907. var classArray = baidu.string.trim(className).split(/\s+/),
  3908. len = classArray.length;
  3909. className = element.className.split(/\s+/).join(" ");
  3910. while (len--) {
  3911. if(!(new RegExp("(^| )" + classArray[len] + "( |\x24)")).test(className)){
  3912. return false;
  3913. }
  3914. }
  3915. return true;
  3916. };
  3917. /*
  3918. * Tangram
  3919. * Copyright 2009 Baidu Inc. All rights reserved.
  3920. *
  3921. * path: baidu/dom/hide.js
  3922. * author: allstar
  3923. * version: 1.1.0
  3924. * date: 2009/11/17
  3925. */
  3926. /**
  3927. * 隐藏目标元素
  3928. * @name baidu.dom.hide
  3929. * @function
  3930. * @grammar baidu.dom.hide(element)
  3931. * @param {HTMLElement|string} element 目标元素或目标元素的id
  3932. * @shortcut hide
  3933. * @meta standard
  3934. * @see baidu.dom.show,baidu.dom.toggle
  3935. *
  3936. * @returns {HTMLElement} 目标元素
  3937. */
  3938. baidu.dom.hide = function (element) {
  3939. element = baidu.dom.g(element);
  3940. element.style.display = "none";
  3941. return element;
  3942. };
  3943. // 声明快捷方法
  3944. baidu.hide = baidu.dom.hide;
  3945. /*
  3946. * Tangram
  3947. * Copyright 2009 Baidu Inc. All rights reserved.
  3948. *
  3949. * path: baidu/dom/insertAfter.js
  3950. * author: allstar, erik
  3951. * version: 1.1.0
  3952. * date: 2009/12/02
  3953. */
  3954. /**
  3955. * 将目标元素添加到基准元素之后
  3956. * @name baidu.dom.insertAfter
  3957. * @function
  3958. * @grammar baidu.dom.insertAfter(newElement, existElement)
  3959. * @param {HTMLElement|string} newElement 被添加的目标元素
  3960. * @param {HTMLElement|string} existElement 基准元素
  3961. * @meta standard
  3962. * @see baidu.dom.insertBefore
  3963. *
  3964. * @returns {HTMLElement} 被添加的目标元素
  3965. */
  3966. baidu.dom.insertAfter = function (newElement, existElement) {
  3967. var g, existParent;
  3968. g = baidu.dom._g;
  3969. newElement = g(newElement);
  3970. existElement = g(existElement);
  3971. existParent = existElement.parentNode;
  3972. if (existParent) {
  3973. existParent.insertBefore(newElement, existElement.nextSibling);
  3974. }
  3975. return newElement;
  3976. };
  3977. /*
  3978. * Tangram
  3979. * Copyright 2009 Baidu Inc. All rights reserved.
  3980. *
  3981. * path: baidu/dom/insertBefore.js
  3982. * author: allstar, erik
  3983. * version: 1.1.0
  3984. * date: 2009/11/17
  3985. */
  3986. /**
  3987. * 将目标元素添加到基准元素之前
  3988. * @name baidu.dom.insertBefore
  3989. * @function
  3990. * @grammar baidu.dom.insertBefore(newElement, existElement)
  3991. * @param {HTMLElement|string} newElement 被添加的目标元素
  3992. * @param {HTMLElement|string} existElement 基准元素
  3993. * @meta standard
  3994. * @see baidu.dom.insertAfter
  3995. *
  3996. * @returns {HTMLElement} 被添加的目标元素
  3997. */
  3998. baidu.dom.insertBefore = function (newElement, existElement) {
  3999. var g, existParent;
  4000. g = baidu.dom._g;
  4001. newElement = g(newElement);
  4002. existElement = g(existElement);
  4003. existParent = existElement.parentNode;
  4004. if (existParent) {
  4005. existParent.insertBefore(newElement, existElement);
  4006. }
  4007. return newElement;
  4008. };
  4009. /*
  4010. * Tangram
  4011. * Copyright 2009 Baidu Inc. All rights reserved.
  4012. *
  4013. * path: baidu/dom/insertHTML.js
  4014. * author: allstar, erik, berg,wenyuxiang,lixiaopeng
  4015. * version: 1.1.2
  4016. * date: 2010-07-13
  4017. */
  4018. /**
  4019. * 在目标元素的指定位置插入HTML代码
  4020. * @name baidu.dom.insertHTML
  4021. * @function
  4022. * @grammar baidu.dom.insertHTML(element, position, html)
  4023. * @param {HTMLElement|string} element 目标元素或目标元素的id
  4024. * @param {string} position 插入html的位置信息,取值为beforeBegin,afterBegin,beforeEnd,afterEnd
  4025. * @param {string} html 要插入的html
  4026. * @remark
  4027. *
  4028. * 对于position参数,大小写不敏感<br>
  4029. * 参数的意思:beforeBegin&lt;span&gt;afterBegin this is span! beforeEnd&lt;/span&gt; afterEnd <br />
  4030. * 此外,如果使用本函数插入带有script标签的HTML字符串,script标签对应的脚本将不会被执行。
  4031. *
  4032. * @shortcut insertHTML
  4033. * @meta standard
  4034. *
  4035. * @returns {HTMLElement} 目标元素
  4036. */
  4037. baidu.dom.insertHTML = function (element, position, html) {
  4038. element = baidu.dom.g(element);
  4039. var range,begin;
  4040. if (element.insertAdjacentHTML) {
  4041. element.insertAdjacentHTML(position, html);
  4042. } else {
  4043. // 这里不做"undefined" != typeof(HTMLElement) && !window.opera判断,其它浏览器将出错?!
  4044. // 但是其实做了判断,其它浏览器下等于这个函数就不能执行了
  4045. range = element.ownerDocument.createRange();
  4046. // FF下range的位置设置错误可能导致创建出来的fragment在插入dom树之后html结构乱掉
  4047. // 改用range.insertNode来插入html, by wenyuxiang @ 2010-12-14.
  4048. position = position.toUpperCase();
  4049. if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {
  4050. range.selectNodeContents(element);
  4051. range.collapse(position == 'AFTERBEGIN');
  4052. } else {
  4053. begin = position == 'BEFOREBEGIN';
  4054. range[begin ? 'setStartBefore' : 'setEndAfter'](element);
  4055. range.collapse(begin);
  4056. }
  4057. range.insertNode(range.createContextualFragment(html));
  4058. }
  4059. return element;
  4060. };
  4061. baidu.insertHTML = baidu.dom.insertHTML;
  4062. /*
  4063. * Tangram
  4064. * Copyright 2009 Baidu Inc. All rights reserved.
  4065. *
  4066. * path: baidu/dom/last.js
  4067. * author: allstar
  4068. * version: 1.1.0
  4069. * date: 2009/11/18
  4070. */
  4071. /**
  4072. * 获取目标元素的最后一个元素节点
  4073. * @name baidu.dom.last
  4074. * @function
  4075. * @grammar baidu.dom.last(element)
  4076. * @param {HTMLElement|string} element 目标元素或目标元素的id
  4077. * @see baidu.dom.first,baidu.dom.prev,baidu.dom.next
  4078. *
  4079. * @returns {HTMLElement|null} 目标元素的最后一个元素节点,查找不到时返回null
  4080. */
  4081. baidu.dom.last = function (element) {
  4082. return baidu.dom._matchNode(element, 'previousSibling', 'lastChild');
  4083. };
  4084. /*
  4085. * Tangram
  4086. * Copyright 2009 Baidu Inc. All rights reserved.
  4087. *
  4088. * path: baidu/dom/next.js
  4089. * author: allstar
  4090. * version: 1.1.0
  4091. * date: 2009/11/18
  4092. */
  4093. /**
  4094. * 获取目标元素的下一个兄弟元素节点
  4095. * @name baidu.dom.next
  4096. * @function
  4097. * @grammar baidu.dom.next(element)
  4098. * @param {HTMLElement|string} element 目标元素或目标元素的id
  4099. * @see baidu.dom.first,baidu.dom.last,baidu.dom.prev
  4100. * @meta standard
  4101. * @returns {HTMLElement|null} 目标元素的下一个兄弟元素节点,查找不到时返回null
  4102. */
  4103. baidu.dom.next = function (element) {
  4104. return baidu.dom._matchNode(element, 'nextSibling', 'nextSibling');
  4105. };
  4106. /*
  4107. * Tangram
  4108. * Copyright 2009 Baidu Inc. All rights reserved.
  4109. *
  4110. * path: baidu/dom/prev.js
  4111. * author: allstar
  4112. * version: 1.1.0
  4113. * date: 2009/11/18
  4114. */
  4115. /**
  4116. * 获取目标元素的上一个兄弟元素节点
  4117. * @name baidu.dom.prev
  4118. * @function
  4119. * @grammar baidu.dom.prev(element)
  4120. * @param {HTMLElement|string} element 目标元素或目标元素的id
  4121. * @see baidu.dom.first,baidu.dom.last,baidu.dom.next
  4122. *
  4123. *
  4124. * @returns {HTMLElement|null} 目标元素的上一个兄弟元素节点,查找不到时返回null
  4125. */
  4126. baidu.dom.prev = function (element) {
  4127. return baidu.dom._matchNode(element, 'previousSibling', 'previousSibling');
  4128. };
  4129. /*
  4130. * Tangram
  4131. * Copyright 2009 Baidu Inc. All rights reserved.
  4132. *
  4133. * path: baidu/string/escapeReg.js
  4134. * author: erik
  4135. * version: 1.1.0
  4136. * date: 2009/11/15
  4137. */
  4138. /**
  4139. * 将目标字符串中可能会影响正则表达式构造的字符串进行转义。
  4140. * @name baidu.string.escapeReg
  4141. * @function
  4142. * @grammar baidu.string.escapeReg(source)
  4143. * @param {string} source 目标字符串
  4144. * @remark
  4145. * 给以下字符前加上“\”进行转义:.*+?^=!:${}()|[]/\
  4146. * @meta standard
  4147. *
  4148. * @returns {string} 转义后的字符串
  4149. */
  4150. baidu.string.escapeReg = function (source) {
  4151. return String(source)
  4152. .replace(new RegExp("([.*+?^=!:\x24{}()|[\\]\/\\\\])", "g"), '\\\x241');
  4153. };
  4154. /*
  4155. * Tangram
  4156. * Copyright 2009 Baidu Inc. All rights reserved.
  4157. *
  4158. * path: baidu/dom/q.js
  4159. * author: allstar, erik
  4160. * version: 1.1.0
  4161. * date: 2009/12/02
  4162. */
  4163. /**
  4164. * 通过className获取元素
  4165. * @name baidu.dom.q
  4166. * @function
  4167. * @grammar baidu.dom.q(className[, element, tagName])
  4168. * @param {string} className 元素的class,只能指定单一的class,如果为空字符串或者纯空白的字符串,返回空数组。
  4169. * @param {string|HTMLElement} [element] 开始搜索的元素,默认是document。
  4170. * @param {string} [tagName] 要获取元素的标签名,如果没有值或者值为空字符串或者纯空白的字符串,表示不限制标签名。
  4171. * @remark 不保证返回数组中DOM节点的顺序和文档中DOM节点的顺序一致。
  4172. * @shortcut q,T.Q
  4173. * @meta standard
  4174. * @see baidu.dom.g
  4175. *
  4176. * @returns {Array} 获取的元素集合,查找不到或className参数错误时返回空数组.
  4177. */
  4178. baidu.dom.q = function (className, element, tagName) {
  4179. var result = [],
  4180. trim = baidu.string.trim,
  4181. len, i, elements, node;
  4182. if (!(className = trim(className))) {
  4183. return result;
  4184. }
  4185. // 初始化element参数
  4186. if ('undefined' == typeof element) {
  4187. element = document;
  4188. } else {
  4189. element = baidu.dom.g(element);
  4190. if (!element) {
  4191. return result;
  4192. }
  4193. }
  4194. // 初始化tagName参数
  4195. tagName && (tagName = trim(tagName).toUpperCase());
  4196. // 查询元素
  4197. if (element.getElementsByClassName) {
  4198. elements = element.getElementsByClassName(className);
  4199. len = elements.length;
  4200. for (i = 0; i < len; i++) {
  4201. node = elements[i];
  4202. if (tagName && node.tagName != tagName) {
  4203. continue;
  4204. }
  4205. result[result.length] = node;
  4206. }
  4207. } else {
  4208. className = new RegExp(
  4209. "(^|\\s)"
  4210. + baidu.string.escapeReg(className)
  4211. + "(\\s|\x24)");
  4212. elements = tagName
  4213. ? element.getElementsByTagName(tagName)
  4214. : (element.all || element.getElementsByTagName("*"));
  4215. len = elements.length;
  4216. for (i = 0; i < len; i++) {
  4217. node = elements[i];
  4218. className.test(node.className) && (result[result.length] = node);
  4219. }
  4220. }
  4221. return result;
  4222. };
  4223. // 声明快捷方法
  4224. baidu.q = baidu.Q = baidu.dom.q;
  4225. /*
  4226. * Tangram query
  4227. *
  4228. * code from https://github.com/hackwaly/Q
  4229. *
  4230. * version: 1.0.0
  4231. * date: 20110801
  4232. * author: wenyuxiang
  4233. */
  4234. /**
  4235. * 提供css选择器功能
  4236. * @name baidu.dom.query
  4237. * @function
  4238. * @grammar baidu.dom.query(selector[, context, results])
  4239. * @param {String} selector 选择器定义
  4240. * @param {HTMLElement | DOMDocument} [context] 查找的上下文
  4241. * @param {Array} [results] 查找的结果会追加到这个数组中
  4242. * @version 1.2
  4243. * @remark
  4244. *
  4245. 选择器支持所有的<a href="http://www.w3.org/TR/css3-selectors/">css3选择器</a> ,核心实现采用sizzle。可参考<a href="http://wiki.github.com/jeresig/sizzle/" target="_blank">sizzle 文档</a>
  4246. * @see baidu.dom.g, baidu.dom.q, baidu.dom.query.matches
  4247. *
  4248. * @returns {Array} 包含所有筛选出的DOM元素的数组
  4249. */
  4250. baidu.dom.query = (function (){
  4251. var d = document;
  4252. d._Q_rev = 0;
  4253. var MUTATION = false;
  4254. var _onMu = function (){
  4255. d._Q_rev ++;
  4256. MUTATION = true;
  4257. };
  4258. if (d.addEventListener) {
  4259. d.addEventListener('DOMNodeInserted', _onMu, false);
  4260. d.addEventListener('DOMNodeRemoved', _onMu, false);
  4261. }
  4262. var BY_ID1;
  4263. var BY_CLASS;
  4264. var IE678 = window.ActiveXObject && !d.addEventListener;
  4265. (function (){
  4266. var div = d.createElement('div');
  4267. div.innerHTML = '<a name="d"></a><div id="d"></div>';
  4268. BY_ID1 = div.getElementsByTagName('*')["d"] === div.lastChild;
  4269. div.innerHTML = '<div class="t e"></div><div class="t"></div>';
  4270. div.lastChild.className = 'e';
  4271. BY_CLASS = div.getElementsByClassName && div.getElementsByClassName('e').length == 2;
  4272. })();
  4273. var BY_NAME = !!d.getElementsByName;
  4274. var BY_ELEMENT = typeof d.documentElement.nextElementSibling !== 'undefined';
  4275. var BY_CHILDREN = !!d.documentElement.children;
  4276. var BY_CHILDREN_TAG = BY_CHILDREN && !!d.documentElement.children.tags;
  4277. var PATTERN = /(?:\s*([ ~+>,])\s*)?(?:([:.#]?)((?:[\w\u00A1-\uFFFF-]|\\.)+|\*)|\[\s*((?:[\w\u00A1-\uFFFF-]|\\.)+)(?:\s*([~^$|*!]?=)\s*((['"]).*?\7|[^\]]*))?\s*\])/g;
  4278. function trim(str){
  4279. return str.replace(/^\s*|\s*$/, '');
  4280. }
  4281. function make(kind, array){
  4282. return (array.kind = kind, array);
  4283. }
  4284. var parse = function (){
  4285. var text;
  4286. var index;
  4287. function match(regex){
  4288. var mc = (regex.lastIndex = index, regex.exec(text));
  4289. return mc && mc.index == index ? (index = regex.lastIndex, mc) : null;
  4290. }
  4291. function dequote(str){
  4292. var ch = str.charAt(0);
  4293. return ch == '"' || ch == "'" ? str.slice(1, -1) : str;
  4294. }
  4295. function error(){ throw ['ParseError', text, index]; }
  4296. function parse(){
  4297. var mc, simple, seq = [], chain = [seq], group = [chain];
  4298. while (mc = match(PATTERN)) {
  4299. if (mc[1]) {
  4300. if (mc[1] == ',') group.push(chain = []);
  4301. if (seq.length) chain.push(seq = []);
  4302. if (mc[1] != ',') seq.comb = mc[1];
  4303. }
  4304. simple = [mc[4] || mc[3]];
  4305. if (mc[6]) simple.push(dequote(mc[6]));
  4306. simple.kind = mc[5] || (mc[4] ? '[' : mc[2] || 'T');
  4307. if (simple[0] == '*' && simple.kind != 'T') error();
  4308. if (mc[2] == ':') {
  4309. simple.kind = ':' + mc[3];
  4310. if (text.charAt(index) == '(') {
  4311. index ++;
  4312. if (mc[3] == 'not' || mc[3] == 'has') {
  4313. var t = index;
  4314. simple[0] = parse();
  4315. simple[1] = text.slice(t, index);
  4316. if (text.charAt(index) == ')') index ++; else error();
  4317. } else {
  4318. var tmpIndex = text.indexOf(')', index);
  4319. if (tmpIndex != -1) {
  4320. simple[0] = trim(text.slice(index, tmpIndex));
  4321. index = tmpIndex + 1;
  4322. } else error();
  4323. if (mc[3].indexOf('nth') == 0) {
  4324. var tmp = simple[0];
  4325. tmp = (tmp == 'even' ? '2n' : tmp == 'odd' ? '2n+1' :
  4326. (tmp.indexOf('n') == -1 ? '0n': '') + tmp.replace(/\s*/g, '')).split('n');
  4327. simple[0] = !tmp[0] ? 1 : Number(tmp[0]) | 0;
  4328. simple[1] = Number(tmp[1]) | 0;
  4329. } else if (mc[3] == 'contains') {
  4330. simple[0] = dequote(simple[0]);
  4331. }
  4332. }
  4333. }
  4334. }
  4335. seq.push(simple);
  4336. }
  4337. return group;
  4338. }
  4339. return function (selector){
  4340. return (text = selector, index = 0, selector = parse(), match(/\s*/g), index < text.length) ? error() : selector;
  4341. };
  4342. }();
  4343. var fRMap = { '#': 9, 'N': BY_NAME ? 7 : 0, '.': BY_CLASS ? 6 : 0, 'T': 5 };
  4344. var tRMap = { '#': 9, '=': 9, '[': 8, 'N': 9, 'T': 8, '.': 5, '~=': 3, '|=': 3, '*=': 3,
  4345. ':not': 6, ':has': 1, ':contains': 3, ':nth-child': 2, ':nth-last-child': 2,
  4346. ':first-child': 3, ':last-child': 3, ':only-child': 3, ':not-ex': 7 };
  4347. var efMap = { id: '#', name: 'N' };
  4348. var testingOrder = function (a, b){ return a.tR - b.tR; };
  4349. var regPos = /:(nth|eq|gt|lt|first|last|even|odd)$/;
  4350. function process(seq){
  4351. var finder, t;
  4352. var k = seq.length;
  4353. while (k --) {
  4354. var simple = seq[k];
  4355. // 转化[id="xxx"][name="xxx"][tagName="xxx"][className~="xxx"]之类的选择器
  4356. // 识别:root,html|head|body|title等全局仅一个的标签的选择器,忽略*选择器
  4357. // 合并类选择器以便于使用getElementsByClassName
  4358. if (simple.kind == ':html') simple = make('T', 'html');
  4359. if (simple.kind == '=') {
  4360. if (efMap[simple[0]]) simple = make(efMap[simple[0]], [simple[1]]);
  4361. } else if (simple.kind == '~=' && simple[0] == 'className') simple = make('.', [simple[1]]);
  4362. if (simple.kind == 'T') {
  4363. if (simple[0] == '*') simple.kind = '*'; else seq.tag = simple;
  4364. t = simple[0].toLowerCase();
  4365. } else if (simple.kind == '.') {
  4366. if (!seq.classes) seq.classes = simple; else {
  4367. seq.classes.push(simple[0]);
  4368. simple.kind = '*';
  4369. }
  4370. }
  4371. if (simple.kind == ':not' && !((t=simple[0],t.length==1)&&(t=t[0],t.length==1))) {
  4372. simple.kind = ':not-ex';
  4373. }
  4374. //remark: 这里是为了支持sizzle的setFilter系列
  4375. if (regPos.test(simple.kind)) {
  4376. simple[0] = Number(simple[0]) | 0;
  4377. var newSimple = make(simple.kind, simple.slice(0));
  4378. simple.kind = '*';
  4379. if (!seq.allPoses) {
  4380. seq.allPoses = [newSimple];
  4381. } else {
  4382. seq.allPoses.push(newSimple);
  4383. }
  4384. }
  4385. // 计算选择器的得分用于优先级排序等策略
  4386. simple.fR = fRMap[simple.kind] | 0;
  4387. simple.tR = tRMap[simple.kind] | 0;
  4388. if (simple.fR && (!finder || simple.fR > finder.fR)) finder = simple;
  4389. seq[k] = simple;
  4390. }
  4391. // 按照优先级对用于测试的选择器进行排序
  4392. seq.sort(testingOrder);
  4393. // 记录用于getElementXXX的最佳的选择器
  4394. seq.$ = finder;
  4395. return seq;
  4396. }
  4397. // 对chain进行处理
  4398. // 注意为了处理方便, 返回的数组是倒序的
  4399. // div p a => [div] [p] [a]
  4400. // div p>a => [div] [p>a]
  4401. function slice(chain){
  4402. var part = [];
  4403. var parts = [part];
  4404. var k = chain.length;
  4405. while (k --) {
  4406. var seq = chain[k];
  4407. seq = process(seq);
  4408. seq.N = 'node' + k;
  4409. //remark: 这里是为了支持sizzle的setFilter.
  4410. if (seq.allPoses) {
  4411. if (!chain.allPoses) {
  4412. chain.allPoses = [];
  4413. }
  4414. chain.allPoses.push.apply(chain.allPoses, seq.allPoses);
  4415. }
  4416. if (seq.$ && (!part.fR || seq.$.fR > part.fR || (seq.$.fR == part.fR && parts.length == 1))) {
  4417. part.fR = seq.$.fR;
  4418. part.fI = part.length;
  4419. }
  4420. part.push(seq);
  4421. if (seq.comb == ' ' && k && part.fI != null) {
  4422. parts.push(part = []);
  4423. part.fR = 0;
  4424. }
  4425. if (k == chain.length - 1 && seq.tag) chain.tag = seq.tag;
  4426. }
  4427. for (var i=0; i<parts.length; i++) {
  4428. part = parts[i];
  4429. var part1 = parts[i + 1];
  4430. if (part1 != null) {
  4431. if (part.fR > part1.fR || (part.fR == part1.fR && part1.fI != 0)){
  4432. parts.splice(i + 1, 1);
  4433. part.push.apply(part, part1);
  4434. i --;
  4435. } else {
  4436. part.R = part1[0].N;
  4437. }
  4438. } else {
  4439. part.R = 'root';
  4440. }
  4441. }
  4442. // 如果没有找到任何一个可以用于find的seq.
  4443. if (parts[0].fI == null) {
  4444. parts[0].fI = 0;
  4445. parts[0][0].$ = make('*', ['*']);
  4446. }
  4447. return parts;
  4448. }
  4449. function format(tpl, params){
  4450. return tpl.replace(/#\{([^}]+)\}/g, function (m, p){
  4451. return params[p] == null ? m : params[p] + '';
  4452. });
  4453. }
  4454. var CTX_NGEN = 0;
  4455. var TPL_DOC = '/*^var doc=root.ownerDocument||root;^*/';
  4456. var TPL_XHTML = TPL_DOC + '/*^var xhtml=Q._isXHTML(doc);^*/';
  4457. var TPL_CONTAINS = IE678 ? '#{0}.contains(#{1})' : '#{0}.compareDocumentPosition(#{1})&16';
  4458. var TPL_QID = '#{N}._Q_id||(#{N}._Q_id=++qid)';
  4459. var TPL_FIND = {
  4460. '#': 'var #{N}=Q._byId("#{P}", #{R});if(#{N}){#{X}}',
  4461. 'N': TPL_DOC + 'var #{N}A=doc.getElementsByName("#{P}");for(var #{N}I=0,#{N};#{N}=#{N}A[#{N}I];#{N}I++){if(#{R}===doc||' + format(TPL_CONTAINS, ['#{R}', '#{N}']) +'){#{X}}}',
  4462. 'T': 'var #{N}A=#{R}.getElementsByTagName("#{P}");for(var #{N}I=0,#{N};#{N}=#{N}A[#{N}I];#{N}I++){#{X}}',
  4463. '.': 'var #{N}A=#{R}.getElementsByClassName("#{P}");for(var #{N}I=0,#{N};#{N}=#{N}A[#{N}I];#{N}I++){#{X}}',
  4464. '*': 'var #{N}A=#{R}.getElementsByTagName("*");for(var #{N}I=0,#{N};#{N}=#{N}A[#{N}I];#{N}I++){#{X}}',
  4465. '+': BY_ELEMENT ? '/*^var #{N};^*/if(#{N}=#{R}.nextElementSibling){#{X}}' : 'var #{N}=#{R};while(#{N}=#{N}.nextSibling){if(#{N}.nodeType==1){#{X}break;}}',
  4466. '~': BY_ELEMENT ? '/*^var #{N}H={};^*/var #{N}=#{R};while(#{N}=#{N}.nextElementSibling){if(#{N}H[' + TPL_QID + '])break;#{N}H[' + TPL_QID + ']=1;#{X}}' : '/*^var #{N}H={};^*/var #{N}=#{R};while(#{N}=#{N}.nextSibling){if(#{N}.nodeType==1){if(#{N}H[' + TPL_QID + '])break;#{N}H[' + TPL_QID + ']=1;#{X}}}',
  4467. '>': 'var #{N}A=#{R}.children||#{R}.childNodes;for(var #{N}I=0,#{N};#{N}=#{N}A[#{N}I];#{N}I++){if(#{N}.nodeType==1){#{X}}}',
  4468. '>T': 'var #{N}A=#{R}.children.tags("#{P}");for(var #{N}I=0,#{N};#{N}=#{N}A[#{N}I];#{N}I++){#{X}}'
  4469. };
  4470. var TPL_LEFT = 'var #{R}V={_:false};NP_#{R}:{P_#{R}:{#{X}break NP_#{R};}#{R}V._=true;#{Y}}';
  4471. var TPL_TOPASS = 'if(t=#{N}H[' + TPL_QID + ']){if(t._){break P_#{R};}else{break NP_#{R};}}#{N}H[' + TPL_QID + ']=#{R}V;#{X}';
  4472. var TPL_TOPASS_UP = format(TPL_TOPASS, { X: 'if(#{N}!==#{R}){#{X}}' });
  4473. var TPL_PASSED = 'break P_#{R};';
  4474. var TPL_PASS = {
  4475. '>': '/*^var #{N}H={};^*/var #{N}=#{C}.parentNode;' + TPL_TOPASS_UP,
  4476. ' ': '/*^var #{N}H={};^*/var #{N}=#{C};while(#{N}=#{N}.parentNode){' + TPL_TOPASS_UP + '}',
  4477. '+': BY_ELEMENT ? '/*^var #{N}H={};var #{N};^*/if(#{N}=#{C}.previousElementSibling){#{X}}' : '/*^var #{N}H={};^*/var #{N}=#{C};while(#{N}=#{N}.previousSibling){#{X}break;}',
  4478. '~': BY_ELEMENT ? '/*^var #{N}H={};^*/var #{N}=#{C};while(#{N}=#{N}.previousElementSibling){' + TPL_TOPASS + '}' : '/*^var #{N}H={};^*/var #{N}=#{C};while(#{N}=#{N}.previousSibling){' + TPL_TOPASS + '}'
  4479. };
  4480. var TPL_MAIN = 'function(root){var result=[];var qid=Q.qid,t,l=result.length;BQ:{#{X}}Q.qid=qid;return result;}';
  4481. var TPL_HELP = '/*^var #{N}L;^*/if(!#{N}L||!(' + format(TPL_CONTAINS, ['#{N}L', '#{N}']) +')){#{X}#{N}L=#{N};}';
  4482. var TPL_PUSH = 'result[l++]=#{N};';
  4483. var TPL_INPUT_T = TPL_XHTML + '/*^var input_t=!xhtml?"INPUT":"input";^*/';
  4484. var TPL_POS = '/*^var pos=-1;^*/';
  4485. var TPL_TEST = {
  4486. 'T': TPL_XHTML +'/*^var #{N}T=!xhtml?("#{0}").toUpperCase():"#{0}";^*/#{N}.nodeName==#{N}T',
  4487. '#': '#{N}.id=="#{0}"',
  4488. 'N': '#{N}.name=="#{0}"',
  4489. '[': IE678 ? '(t=#{N}.getAttributeNode("#{0}"))&&(t.specified)' : '#{N}.hasAttribute("#{0}")',
  4490. '=': '#{A}=="#{1}"',
  4491. '!=': '#{A}!="#{1}"',
  4492. '^=': '(t=#{A})&&t.slice(0,#{L})=="#{1}"',
  4493. '$=': '(t=#{A})&&t.slice(-#{L})=="#{1}"',
  4494. '*=': '(t=#{A})&&t.indexOf("#{1}")!==-1',
  4495. '|=': '(t=#{A})&&(t=="#{1}"||t.slice(0,#{L})=="#{P}")',
  4496. '~=': '(t=#{A})&&(" "+t+" ").indexOf("#{P}")!==-1',
  4497. ':element': '#{N}.nodeType==1',
  4498. ':contains': '(#{N}.textContent||#{N}.innerText).indexOf("#{0}")!==-1',
  4499. ':first-child': BY_ELEMENT ? '#{N}.parentNode.firstElementChild===#{N}' : 'Q._isFirstChild(#{N})',
  4500. ':nth-child': TPL_DOC + '/*^var rev=doc._Q_rev||(doc._Q_rev=Q.qid++);^*/Q._index(#{N},#{0},#{1},rev)',
  4501. ':last-child': BY_ELEMENT ? '#{N}.parentNode.lastElementChild===#{N}' : 'Q._isLastChild(#{N})',
  4502. ':only-child': BY_ELEMENT ? '(t=#{N}.parentNode)&&(t.firstElementChild===#{N}&&t.lastElementChild===#{N})' : 'Q._isOnlyChild(#{N})',
  4503. ':not-ex': '/*^var _#{G}=Q._hash(Q("#{1}",root));qid=Q.qid;^*/!_#{G}[' + TPL_QID + ']',
  4504. ':has': '(t=Q("#{1}", #{N}),qid=Q.qid,t.length>0)',
  4505. ':parent': '!!#{N}.firstChild',
  4506. ':empty': '!#{N}.firstChild',
  4507. ':header': '/h\\d/i.test(#{N}.nodeName)',
  4508. ':input': '/input|select|textarea|button/i.test(#{N}.nodeName)',
  4509. ':enabled': '#{N}.disabled===false&&#{N}.type!=="hidden"',
  4510. ':disabled': '#{N}.disabled===true',
  4511. ':checked': '#{N}.checked===true',
  4512. ':selected': '(#{N}.parentNode.selectedIndex,#{N}.selected===true)',
  4513. // TODO: 这些伪类可以转化成为标签选择器加以优化!
  4514. ':focus': TPL_DOC + '#{N}===doc.activeElement',
  4515. ':button': TPL_INPUT_T + '#{N}.nodeName==="button"||(#{N}.nodeName===input_t&&#{N}.type==="button")',
  4516. ':submit': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="submit"',
  4517. ':reset': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="reset"',
  4518. ':text': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="text"&&(t=#{N}.getAttribute("type"),t==="text"||t===null)',
  4519. ':radio': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="radio"',
  4520. ':checkbox': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="checkbox"',
  4521. ':file': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="file"',
  4522. ':password': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="password"',
  4523. ':image': TPL_INPUT_T + '#{N}.nodeName===input_t&&#{N}.type==="image"'
  4524. };
  4525. function genAttrCode(attr){
  4526. if (attr == 'for') return '#{N}.htmlFor';
  4527. if (attr == 'class') return '#{N}.className';
  4528. if (attr == 'type') return '#{N}.getAttribute("type")';
  4529. if (attr == 'href') return '#{N}.getAttribute("href",2)';
  4530. return '(#{N}["' + attr + '"]||#{N}.getAttribute("' + attr + '"))';
  4531. }
  4532. function genTestCode(simple){
  4533. if (simple.kind.indexOf('=') !== -1) {
  4534. simple.A = genAttrCode(simple[0]);
  4535. }
  4536. var t;
  4537. switch (simple.kind) {
  4538. case '.':
  4539. var k = simple.length;
  4540. var buff = [];
  4541. while (k --) {
  4542. buff.push('t.indexOf(" #{'+ k +'} ")!==-1');
  4543. }
  4544. return format('(t=#{N}.className)&&((t=" "+t+" "),(' + buff.join(' && ') + '))', simple);
  4545. case '^=':
  4546. case '$=':
  4547. simple.L = simple[1].length;
  4548. break;
  4549. case '|=':
  4550. simple.L = simple[1].length + 1;
  4551. simple.P = simple[1] + '-';
  4552. break;
  4553. case '~=':
  4554. simple.P = ' ' + simple[1] + ' ';
  4555. break;
  4556. case ':nth-child':
  4557. // case ':nth-last-child':
  4558. if (simple[0] == 1 && simple[1] == 0) return '';
  4559. break;
  4560. case ':not':
  4561. t = genCondCode(simple[0][0][0]);
  4562. return t ? '!(' + t + ')' : 'false';
  4563. case ':not-ex':
  4564. case ':has':
  4565. simple.G = CTX_NGEN ++;
  4566. break;
  4567. case '*':
  4568. return '';
  4569. }
  4570. return format(TPL_TEST[simple.kind], simple);
  4571. }
  4572. function genCondCode(seq){
  4573. var buff = [];
  4574. var k = seq.length;
  4575. var code;
  4576. while (k --) {
  4577. var simple = seq[k];
  4578. if (code = genTestCode(simple)) {
  4579. buff.push(code);
  4580. }
  4581. }
  4582. return buff.join(' && ');
  4583. }
  4584. function genThenCode(seq){
  4585. var code = genCondCode(seq);
  4586. return code ? format('if('+code+'){#{X}}', { N: seq.N }) : '#{X}';
  4587. }
  4588. var NEEDNOT_ELEMENT_CHECK = { '#': 1, 'T': 1, '.': 1, 'N': 1, ':element': 1 };
  4589. function genFindCode(seq, R, comb){
  4590. comb = comb || seq.comb;
  4591. var tpl;
  4592. if (comb == ' ') {
  4593. var finder = seq.$;
  4594. if (finder) {
  4595. tpl = TPL_FIND[finder.kind];
  4596. // 有hack的嫌疑, 让产生test代码时忽略已经用于find的seq.
  4597. finder.kind = '*';
  4598. } else {
  4599. tpl = TPL_FIND['*'];
  4600. if (IE678 && !NEEDNOT_ELEMENT_CHECK[seq[seq.length - 1].kind]) {
  4601. seq.push(make(':element', []));
  4602. }
  4603. }
  4604. } else if (BY_CHILDREN_TAG && comb == '>' && seq.tag) {
  4605. tpl = TPL_FIND['>T'];
  4606. finder = seq.tag;
  4607. seq.tag.kind = '*';
  4608. } else {
  4609. // if (!BY_ELEMENT && (comb == '+' || comb == '~') && !NEEDNOT_ELEMENT_CHECK[seq[seq.length - 1].kind]) {
  4610. // seq.push(make(':element', []));
  4611. // }
  4612. tpl = TPL_FIND[comb];
  4613. }
  4614. return format(tpl, {
  4615. P: finder && (finder.kind == '.' ? finder.join(' ') : finder[0]),
  4616. N: seq.N,
  4617. R: R,
  4618. X: genThenCode(seq)
  4619. });
  4620. }
  4621. function genNextCode(part, thenCode){
  4622. var code = '#{X}';
  4623. var k = part.fI;
  4624. while (k --) {
  4625. code = format(code, { X: genFindCode(part[k], part[k+1].N) });
  4626. }
  4627. var nextCode;
  4628. if (!thenCode) {
  4629. if (part.fI == 0 && (k = part[0].$.kind) && (k != 'S' && k != '#')) {
  4630. nextCode = format(TPL_HELP, { N: part[0].N });
  4631. code = format(code, { X: nextCode })
  4632. }
  4633. } else {
  4634. nextCode = format(thenCode, { N: part[0].N });
  4635. code = format(code, { X: nextCode });
  4636. }
  4637. return code;
  4638. }
  4639. function genPassCode(seq, C, comb){
  4640. return format(TPL_PASS[comb], {
  4641. N: seq.N,
  4642. C: C,
  4643. X: genThenCode(seq)
  4644. });
  4645. }
  4646. function genLeftCode(part){
  4647. var code = TPL_LEFT;
  4648. for (var i=part.fI+1,l=part.length; i<l; i++) {
  4649. var seq = part[i];
  4650. var lastSeq = part[i-1];
  4651. code = format(code, { X: genPassCode(seq, lastSeq.N, part[i-1].comb) });
  4652. }
  4653. code = format(code, { X: TPL_PASSED });
  4654. code = format(code, { R: part.R });
  4655. return code;
  4656. }
  4657. function genPartCode(part, thenCode){
  4658. var code = genFindCode(part[part.fI], part.R, ' ');
  4659. var nextCode = genNextCode(part, thenCode);
  4660. if (part.fI < part.length - 1) {
  4661. var passCode = genLeftCode(part);
  4662. nextCode = format(passCode, { Y: nextCode });
  4663. }
  4664. return format(code, { X: nextCode });
  4665. }
  4666. function genThatCode(seq){
  4667. var obj = {};
  4668. var k = seq.length;
  4669. while (k --) {
  4670. var simple = seq[k];
  4671. if (simple.kind == ':first') {
  4672. simple = make(':nth', [0]);
  4673. } else if (simple.kind == ':last') {
  4674. obj.last = 1;
  4675. }
  4676. if (simple.kind == ':lt') {
  4677. obj.lt = obj.lt === undefined ? simple[0] : Math.min(obj.lt, simple[0]);
  4678. } else if (simple.kind == ':gt') {
  4679. obj.gt = obj.gt === undefined ? simple[0] : Math.max(obj.gt, simple[0]);
  4680. } else if (simple.kind == ':eq' || simple.kind == ':nth') {
  4681. if (obj.eq && obj.eq !== simple[0]) {
  4682. obj.no = true;
  4683. } else obj.eq = simple[0];
  4684. } else if (simple.kind == ':even' || simple.kind == ':odd') {
  4685. obj[simple.kind.slice(1)] = 1;
  4686. }
  4687. }
  4688. if ((obj.lt != null && obj.eq != null && obj.eq >= obj.lt) || (obj.lt != null && obj.gt != null && obj.lt <= obj.gt) || (obj.even && obj.odd)) {
  4689. obj.no = 1;
  4690. }
  4691. if (obj.no) {
  4692. return '/*^break BQ;^*/';
  4693. }
  4694. var buff = [];
  4695. if (obj.even) {
  4696. buff.push('pos%2===0');
  4697. } else if (obj.odd) {
  4698. buff.push('pos%2===1');
  4699. }
  4700. var code = obj.eq == null ? TPL_PUSH : 'if(pos===' + obj.eq + '){result=[#{N}];break BQ;}';
  4701. if (obj.gt != null) {
  4702. buff.push('pos>'+obj.gt);
  4703. }
  4704. code = buff.length ? 'if (' + buff.join('&&') + '){' + code + '}' : code;
  4705. code = obj.lt != null ? 'if (pos<' + obj.lt + '){' + code + '}else break BQ;' : code;
  4706. if (obj.last) {
  4707. code += '/*$result=result.slice(-1);$*/';
  4708. }
  4709. return code;
  4710. }
  4711. function genCode(chain){
  4712. var parts = slice(chain);
  4713. var thenCode = chain.allPoses ? TPL_POS + 'pos++;' + genThatCode(chain.allPoses) : TPL_PUSH;
  4714. CTX_NGEN = 0;
  4715. var code = '#{X}';
  4716. var k = parts.length;
  4717. while (k --) {
  4718. var part = parts[k];
  4719. code = format(code, { X: genPartCode(part, k == 0 ? thenCode : false ) });
  4720. }
  4721. return code;
  4722. }
  4723. var documentOrder;
  4724. if (d.documentElement.sourceIndex) {
  4725. documentOrder = function (nodeA, nodeB){ return nodeA === nodeB ? 0 : nodeA.sourceIndex - nodeB.sourceIndex; };
  4726. } else if (d.compareDocumentPosition) {
  4727. documentOrder = function (nodeA, nodeB){ return nodeA === nodeB ? 0 : nodeB.compareDocumentPosition(nodeA) & 0x02 ? -1 : 1; };
  4728. }
  4729. function uniqueSort(nodeSet, notUnique){
  4730. if (!nodeSet.length) return nodeSet;
  4731. nodeSet.sort(documentOrder);
  4732. if (notUnique) return nodeSet;
  4733. var resultSet = [nodeSet[0]];
  4734. var node, j = 0;
  4735. for (var i=1, l=nodeSet.length; i<l; i++) {
  4736. if (resultSet[j] !== (node = nodeSet[i])) {
  4737. resultSet[++ j] = node;
  4738. }
  4739. }
  4740. return resultSet;
  4741. }
  4742. function compile(expr){
  4743. var group = parse(expr);
  4744. var tags = {};
  4745. var k = group.length;
  4746. while (k --) {
  4747. var chain = group[k];
  4748. var code = genCode(chain);
  4749. if (tags && chain.tag && !tags[chain.tag[0]]) {
  4750. tags[chain.tag[0]] = 1;
  4751. } else {
  4752. tags = null;
  4753. }
  4754. var hash = {};
  4755. var pres = [];
  4756. var posts = [];
  4757. code = code.replace(/\/\*\^(.*?)\^\*\//g, function (m, p){
  4758. return (hash[p] || (hash[p] = pres.push(p)), '');
  4759. });
  4760. code = code.replace(/\/\*\$(.*?)\$\*\//g, function (m, p){
  4761. return (hash[p] || (hash[p] = posts.push(p)), '');
  4762. });
  4763. code = format(TPL_MAIN, { X: pres.join('') + code + posts.join('') });
  4764. group[k] = new Function('Q', 'return(' + code + ')')(Q);
  4765. }
  4766. if (group.length == 1) {
  4767. return group[0];
  4768. }
  4769. return function (root){
  4770. var k = group.length;
  4771. var result = [];
  4772. while (k --) {
  4773. result.push.apply(result, group[k](root));
  4774. }
  4775. return uniqueSort(result, tags != null);
  4776. };
  4777. }
  4778. Q._hash = function (result){
  4779. var hash = result._Q_hash;
  4780. if (hash == null) {
  4781. hash = result._Q_hash = {};
  4782. var k = result.length;
  4783. var qid = Q.qid;
  4784. while (k --) {
  4785. var el = result[k];
  4786. hash[el._Q_id||(el._Q_id=++qid)] = 1;
  4787. }
  4788. Q.qid = qid;
  4789. }
  4790. return hash;
  4791. };
  4792. var _slice = Array.prototype.slice;
  4793. Q._toArray1 = function (staticNodeList){
  4794. var k = staticNodeList.length;
  4795. var a = new Array(k);
  4796. while (k --) {
  4797. a[k] = staticNodeList[k];
  4798. }
  4799. return a;
  4800. };
  4801. Q._toArray = function (staticNodeList){
  4802. try {
  4803. return _slice.call(staticNodeList, 0);
  4804. } catch(ex){}
  4805. return (Q._toArray = Q._toArray1)(staticNodeList);
  4806. };
  4807. function queryXML(expr, root){
  4808. throw ['NotImpl'];
  4809. }
  4810. var cache = {};
  4811. var inQuery = false;
  4812. function query(expr, root){
  4813. var doc = root.ownerDocument || root;
  4814. var ret;
  4815. if (!doc.getElementById) {
  4816. return queryXML(expr, root);
  4817. }
  4818. if (root === doc && doc.querySelectorAll && !/#/.test(expr)) {
  4819. try { return Q._toArray(doc.querySelectorAll(expr)); } catch(ex){}
  4820. }
  4821. var fn = cache[expr] || (cache[expr] = compile(expr));
  4822. if (!inQuery) {
  4823. inQuery = true;
  4824. if (!MUTATION) {
  4825. doc._Q_rev = Q.qid ++;
  4826. }
  4827. ret = fn(root);
  4828. inQuery = false;
  4829. } else {
  4830. ret = fn(root);
  4831. }
  4832. return ret;
  4833. }
  4834. Q.qid = 1;
  4835. Q._byId = function (id, root){
  4836. if (BY_ID1) {
  4837. return root.getElementsByTagName('*')[id];
  4838. }
  4839. var doc = root.ownerDocument || root;
  4840. var node = doc.getElementById(id);
  4841. if (node && ((root === doc) || Q.contains(root, node)) && (!IE678 || (node.id === id || node.getAttributeNode('id').nodeValue === id))) {
  4842. return node;
  4843. }
  4844. return null;
  4845. };
  4846. Q._in = function (nodes, nodeSet){
  4847. var hash = Q._hash(nodeSet);
  4848. var ret = [];
  4849. for (var i=0; i<nodes.length; i++) {
  4850. var node = nodes[i];
  4851. if (hash[node._Q_id||(node._Q_id=++Q.qid)]) {
  4852. ret.push(node);
  4853. }
  4854. }
  4855. return ret;
  4856. };
  4857. Q.matches = function (expr, set){
  4858. return Q(expr, null, null, set);
  4859. };
  4860. Q.contains = d.documentElement.contains ? function (a, b){
  4861. return a !== b && a.contains(b);
  4862. } : function (a, b) {
  4863. return a !== b && a.compareDocumentPosition(b) & 16;
  4864. };
  4865. Q._has = function (node, nodes){
  4866. for (var i=0, tnode; tnode=nodes[i++];) {
  4867. if (!Q.contains(node, tnode)) return false;
  4868. }
  4869. return true;
  4870. };
  4871. Q._index = function (node, a, b, rev){
  4872. var parent = node.parentNode;
  4873. if (parent._Q_magic !== rev) {
  4874. var tnode;
  4875. var count = 1;
  4876. if (BY_ELEMENT) {
  4877. tnode = parent.firstElementChild;
  4878. while (tnode) {
  4879. tnode._Q_index = count ++;
  4880. tnode = tnode.nextElementSibling;
  4881. }
  4882. } else {
  4883. var nodes = parent.children || parent.childNodes;
  4884. for (var i=0; tnode=nodes[i]; i++) {
  4885. if (tnode.nodeType == 1) {
  4886. tnode._Q_index = count ++;
  4887. }
  4888. tnode = tnode.nextSibling;
  4889. }
  4890. }
  4891. parent._Q_count1 = count;
  4892. parent._Q_magic = rev;
  4893. }
  4894. return a ? (node._Q_index - b) % a == 0 : node._Q_index == b;
  4895. };
  4896. Q._isOnlyChild = function (node){
  4897. return Q._isFirstChild(node) && Q._isLastChild(node);
  4898. };
  4899. Q._isFirstChild = function (node){
  4900. while (node = node.previousSibling) {
  4901. if (node.nodeType == 1) return false;
  4902. }
  4903. return true;
  4904. };
  4905. Q._isLastChild = function (node){
  4906. while (node = node.nextSibling) {
  4907. if (node.nodeType == 1) return false;
  4908. }
  4909. return true;
  4910. };
  4911. Q._isXHTML = function (doc){
  4912. return doc.documentElement.nodeName == 'html';
  4913. };
  4914. function Q(expr, root, result, seed){
  4915. root = root || d;
  4916. var ret = query(expr, root);
  4917. if (seed) {
  4918. ret = Q._in(seed, ret);
  4919. }
  4920. if (result) {
  4921. ret.push.apply(result, ret);
  4922. } else {
  4923. result = ret;
  4924. }
  4925. return result;
  4926. }
  4927. return Q;
  4928. })();
  4929. /*
  4930. * Tangram
  4931. * Copyright 2009 Baidu Inc. All rights reserved.
  4932. */
  4933. /**
  4934. * 使函数在页面dom节点加载完毕时调用
  4935. * @author allstar
  4936. * @name baidu.dom.ready
  4937. * @function
  4938. * @grammar baidu.dom.ready(callback)
  4939. * @param {Function} callback 页面加载完毕时调用的函数.
  4940. * @remark
  4941. * 如果有条件将js放在页面最底部, 也能达到同样效果,不必使用该方法。
  4942. * @meta standard
  4943. */
  4944. (function() {
  4945. var ready = baidu.dom.ready = function() {
  4946. var readyBound = false,
  4947. readyList = [],
  4948. DOMContentLoaded;
  4949. if (document.addEventListener) {
  4950. DOMContentLoaded = function() {
  4951. document.removeEventListener('DOMContentLoaded', DOMContentLoaded, false);
  4952. ready();
  4953. };
  4954. } else if (document.attachEvent) {
  4955. DOMContentLoaded = function() {
  4956. if (document.readyState === 'complete') {
  4957. document.detachEvent('onreadystatechange', DOMContentLoaded);
  4958. ready();
  4959. }
  4960. };
  4961. }
  4962. function ready() {
  4963. if (!ready.isReady) {
  4964. ready.isReady = true;
  4965. for (var i = 0, j = readyList.length; i < j; i++) {
  4966. readyList[i]();
  4967. }
  4968. }
  4969. }
  4970. function doScrollCheck(){
  4971. try {
  4972. document.documentElement.doScroll("left");
  4973. } catch(e) {
  4974. setTimeout( doScrollCheck, 1 );
  4975. return;
  4976. }
  4977. ready();
  4978. }
  4979. function bindReady() {
  4980. if (readyBound) {
  4981. return;
  4982. }
  4983. readyBound = true;
  4984. if (document.addEventListener) {
  4985. document.addEventListener('DOMContentLoaded', DOMContentLoaded, false);
  4986. window.addEventListener('load', ready, false);
  4987. } else if (document.attachEvent) {
  4988. document.attachEvent('onreadystatechange', DOMContentLoaded);
  4989. window.attachEvent('onload', ready);
  4990. var toplevel = false;
  4991. try {
  4992. toplevel = window.frameElement == null;
  4993. } catch (e) {}
  4994. if (document.documentElement.doScroll && toplevel) {
  4995. doScrollCheck();
  4996. }
  4997. }
  4998. }
  4999. bindReady();
  5000. return function(callback) {
  5001. ready.isReady ? callback() : readyList.push(callback);
  5002. };
  5003. }();
  5004. ready.isReady = false;
  5005. })();
  5006. /*
  5007. * Tangram
  5008. * Copyright 2009 Baidu Inc. All rights reserved.
  5009. *
  5010. * path: baidu/dom/remove.js
  5011. * author: allstar,berg
  5012. * version: 1.1.0
  5013. * date: 2009/11/17
  5014. */
  5015. /**
  5016. * 从DOM树上移除目标元素
  5017. * @name baidu.dom.remove
  5018. * @function
  5019. * @grammar baidu.dom.remove(element)
  5020. * @param {HTMLElement|string} element 需要移除的元素或元素的id
  5021. * @remark
  5022. * <b>注意:</b>对于移除的dom元素,IE下会释放该元素的空间,继续使用该元素的引用进行操作将会引发不可预料的问题。
  5023. * @meta standard
  5024. */
  5025. baidu.dom.remove = function (element) {
  5026. element = baidu.dom._g(element);
  5027. var tmpEl = element.parentNode;
  5028. //去掉了对ie下的特殊处理:创建一个div,appendChild,然后div.innerHTML = ""
  5029. tmpEl && tmpEl.removeChild(element);
  5030. };
  5031. /*
  5032. * Tangram
  5033. * Copyright 2009 Baidu Inc. All rights reserved.
  5034. *
  5035. * path: baidu/dom/removeClass.js
  5036. * author: allstar, erik
  5037. * version: 1.1.0
  5038. * date: 2009/12/02
  5039. */
  5040. /**
  5041. * 移除目标元素的className
  5042. * @name baidu.dom.removeClass
  5043. * @function
  5044. * @grammar baidu.dom.removeClass(element, className)
  5045. * @param {HTMLElement|string} element 目标元素或目标元素的id
  5046. * @param {string} className 要移除的className,允许同时移除多个class,中间使用空白符分隔
  5047. * @remark
  5048. * 使用者应保证提供的className合法性,不应包含不合法字符,className合法字符参考:http://www.w3.org/TR/CSS2/syndata.html。
  5049. * @shortcut removeClass
  5050. * @meta standard
  5051. * @see baidu.dom.addClass
  5052. *
  5053. * @returns {HTMLElement} 目标元素
  5054. */
  5055. baidu.dom.removeClass = function (element, className) {
  5056. element = baidu.dom.g(element);
  5057. var oldClasses = element.className.split(/\s+/),
  5058. newClasses = className.split(/\s+/),
  5059. lenOld,
  5060. lenDel = newClasses.length,
  5061. j,
  5062. i = 0;
  5063. //考虑到同时删除多个className的应用场景概率较低,故放弃进一步性能优化
  5064. // by rocy @1.3.4
  5065. for (; i < lenDel; ++i){
  5066. for(j = 0, lenOld = oldClasses.length; j < lenOld; ++j){
  5067. if(oldClasses[j] == newClasses[i]){
  5068. oldClasses.splice(j, 1);
  5069. break;
  5070. }
  5071. }
  5072. }
  5073. element.className = oldClasses.join(' ');
  5074. return element;
  5075. };
  5076. // 声明快捷方法
  5077. baidu.removeClass = baidu.dom.removeClass;
  5078. /*
  5079. * Tangram
  5080. * Copyright 2010 Baidu Inc. All rights reserved.
  5081. *
  5082. * path: baidu/dom/removeStyle.js
  5083. * author: wenyuxiang, berg
  5084. * version: 1.0.1
  5085. * date: 2010/9/10
  5086. */
  5087. /**
  5088. * 删除元素的某个样式
  5089. * @name baidu.dom.removeStyle
  5090. * @function
  5091. * @grammar baidu.dom.removeStyle(element, styleName)
  5092. * @param {HTMLElement|String} element 需要删除样式的元素或者元素id
  5093. * @param {string} styleName 需要删除的样式名字
  5094. * @version 1.3
  5095. * @see baidu.dom.setStyle
  5096. *
  5097. * @returns {HTMLElement} 目标元素
  5098. */
  5099. // todo: 1. 只支持现代浏览器,有一些老浏览器可能不支持; 2. 有部分属性无法被正常移除
  5100. baidu.dom.removeStyle = function (){
  5101. var ele = document.createElement("DIV"),
  5102. fn,
  5103. _g = baidu.dom._g;
  5104. if (ele.style.removeProperty) {// W3C, (gecko, opera, webkit)
  5105. fn = function (el, st){
  5106. el = _g(el);
  5107. el.style.removeProperty(st);
  5108. return el;
  5109. };
  5110. } else if (ele.style.removeAttribute) { // IE
  5111. fn = function (el, st){
  5112. el = _g(el);
  5113. el.style.removeAttribute(baidu.string.toCamelCase(st));
  5114. return el;
  5115. };
  5116. }
  5117. ele = null;
  5118. return fn;
  5119. }();
  5120. /*
  5121. * Tangram
  5122. * Copyright 2009 Baidu Inc. All rights reserved.
  5123. *
  5124. * path: baidu/object/each.js
  5125. * author: berg
  5126. * version: 1.1.1
  5127. * date: 2010-04-19
  5128. */
  5129. /**
  5130. * 遍历Object中所有元素,1.1.1增加
  5131. * @name baidu.object.each
  5132. * @function
  5133. * @grammar baidu.object.each(source, iterator)
  5134. * @param {Object} source 需要遍历的Object
  5135. * @param {Function} iterator 对每个Object元素进行调用的函数,function (item, key)
  5136. * @version 1.1.1
  5137. *
  5138. * @returns {Object} 遍历的Object
  5139. */
  5140. baidu.object.each = function (source, iterator) {
  5141. var returnValue, key, item;
  5142. if ('function' == typeof iterator) {
  5143. for (key in source) {
  5144. if (source.hasOwnProperty(key)) {
  5145. item = source[key];
  5146. returnValue = iterator.call(source, item, key);
  5147. if (returnValue === false) {
  5148. break;
  5149. }
  5150. }
  5151. }
  5152. }
  5153. return source;
  5154. };
  5155. /*
  5156. * Tangram
  5157. * Copyright 2009 Baidu Inc. All rights reserved.
  5158. */
  5159. /**
  5160. * 判断目标参数是否number类型或Number对象
  5161. * @name baidu.lang.isNumber
  5162. * @function
  5163. * @grammar baidu.lang.isNumber(source)
  5164. * @param {Any} source 目标参数
  5165. * @meta standard
  5166. * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate
  5167. *
  5168. * @returns {boolean} 类型判断结果
  5169. * @remark 用本函数判断NaN会返回false,尽管在Javascript中是Number类型。
  5170. */
  5171. baidu.lang.isNumber = function (source) {
  5172. return '[object Number]' == Object.prototype.toString.call(source) && isFinite(source);
  5173. };
  5174. /*
  5175. * Tangram
  5176. * Copyright 2009 Baidu Inc. All rights reserved.
  5177. *
  5178. * path: baidu/event/getTarget.js
  5179. * author: erik
  5180. * version: 1.1.0
  5181. * date: 2009/11/17
  5182. */
  5183. /**
  5184. * 获取事件的触发元素
  5185. * @name baidu.event.getTarget
  5186. * @function
  5187. * @grammar baidu.event.getTarget(event)
  5188. * @param {Event} event 事件对象
  5189. * @meta standard
  5190. * @returns {HTMLElement} 事件的触发元素
  5191. */
  5192. baidu.event.getTarget = function (event) {
  5193. return event.target || event.srcElement;
  5194. };
  5195. /*
  5196. * Tangram
  5197. * Copyright 2009 Baidu Inc. All rights reserved.
  5198. */
  5199. /**
  5200. * 按照border-box模型设置元素的height和width值。只支持元素的padding/border/height/width使用同一种计量单位的情况。<br/> 不支持:<br/> 1. 非数字值(medium)<br/> 2. em/px在不同的属性中混用
  5201. * @name baidu.dom.setBorderBoxSize
  5202. * @author berg
  5203. * @function
  5204. * @grammar baidu.dom.setBorderBoxSize(element, size)
  5205. * @param {HTMLElement|string} element 元素或DOM元素的id
  5206. * @param {object} size 包含height和width键名的对象
  5207. *
  5208. * @see baidu.dom.setBorderBoxWidth, baidu.dom.setBorderBoxHeight
  5209. *
  5210. * @return {HTMLElement} 设置好的元素
  5211. */
  5212. baidu.dom.setBorderBoxSize= function (element, size) {
  5213. var result = {};
  5214. size.width && (result.width = parseFloat(size.width));
  5215. size.height && (result.height = parseFloat(size.height));
  5216. function getNumericalStyle(element, name){
  5217. return parseFloat(baidu.getStyle(element, name)) || 0;
  5218. }
  5219. if(baidu.browser.isStrict){
  5220. if(size.width){
  5221. result.width = parseFloat(size.width) -
  5222. getNumericalStyle(element, 'paddingLeft') -
  5223. getNumericalStyle(element, 'paddingRight') -
  5224. getNumericalStyle(element, 'borderLeftWidth') -
  5225. getNumericalStyle(element, 'borderRightWidth');
  5226. result.width < 0 && (result.width = 0);
  5227. }
  5228. if(size.height){
  5229. result.height = parseFloat(size.height) -
  5230. getNumericalStyle(element, 'paddingTop') -
  5231. getNumericalStyle(element, 'paddingBottom') -
  5232. getNumericalStyle(element, 'borderTopWidth') -
  5233. getNumericalStyle(element, 'borderBottomWidth');
  5234. result.height < 0 && (result.height = 0);
  5235. }
  5236. }
  5237. return baidu.dom.setStyles(element, result);
  5238. };
  5239. /*
  5240. * Tangram
  5241. * Copyright 2009 Baidu Inc. All rights reserved.
  5242. */
  5243. /**
  5244. * 按照border-box模型设置元素的height值
  5245. *
  5246. * @author berg
  5247. * @name baidu.dom.setBorderBoxHeight
  5248. * @function
  5249. * @grammar baidu.dom.setBorderBoxHeight(element, height)
  5250. *
  5251. * @param {HTMLElement|string} element DOM元素或元素的id
  5252. * @param {number|string} height 要设置的height
  5253. *
  5254. * @return {HTMLElement} 设置好的元素
  5255. * @see baidu.dom.setBorderBoxWidth, baidu.dom.setBorderBoxSize
  5256. * @shortcut dom.setOuterHeight
  5257. */
  5258. baidu.dom.setOuterHeight =
  5259. baidu.dom.setBorderBoxHeight = function (element, height) {
  5260. return baidu.dom.setBorderBoxSize(element, {height : height});
  5261. };
  5262. /*
  5263. * Tangram
  5264. * Copyright 2009 Baidu Inc. All rights reserved.
  5265. */
  5266. /**
  5267. * 按照border-box模型设置元素的width值
  5268. *
  5269. * @author berg
  5270. * @name baidu.dom.setBorderBoxWidth
  5271. * @function
  5272. * @grammar baidu.dom.setBorderBoxWidth(element, width)
  5273. *
  5274. * @param {HTMLElement|string} element DOM元素或元素的id
  5275. * @param {number|string} width 要设置的width
  5276. *
  5277. * @return {HTMLElement} 设置好的元素
  5278. * @see baidu.dom.setBorderBoxHeight, baidu.dom.setBorderBoxSize
  5279. * @shortcut dom.setOuterWidth
  5280. */
  5281. baidu.dom.setOuterWidth =
  5282. baidu.dom.setBorderBoxWidth = function (element, width) {
  5283. return baidu.dom.setBorderBoxSize(element, {width : width});
  5284. };
  5285. /*
  5286. * Tangram
  5287. * Copyright 2010 Baidu Inc. All rights reserved.
  5288. */
  5289. /**
  5290. * 绘制可以根据鼠标行为改变HTMLElement大小的resize handle
  5291. * @name baidu.dom.resizable
  5292. * @function
  5293. * @grammar baidu.dom.resizable(element[, options])
  5294. * @param {HTMLElement|string} element 需要改变大小的元素或者元素的id.
  5295. * @param {Object} [options] resizable参数配置
  5296. * @config {Array} [direction] 可以改变的方向[e,se,s,ws,w,wn,n,en]
  5297. * @config {Function} [onresizestart] 开始改变大小时触发
  5298. * @config {Function} [onresizeend] 大小改变结束时触发
  5299. * @config {Function} [onresize] 大小改变后时触发
  5300. * @config {Number|String} [maxWidth] 可改变的最大宽度
  5301. * @config {Number|String} [maxHeight] 可改变的最大高度
  5302. * @config {Number|String} [minWidth] 可改变的最小宽度
  5303. * @config {Number|String} [minHeight] 可改变的最小高度
  5304. * @config {String} [classPrefix] className 前缀
  5305. * @config {Object} [directionHandlePosition] resizHandle的位置参数
  5306. * @return {Object} {cancel:Function} cancel函数
  5307. * @remark 需要将元素的定位设置为absolute
  5308. * @author lixiaopeng
  5309. * @version 1.3
  5310. */
  5311. baidu.dom.resizable = function(element,options) {
  5312. var target,
  5313. op,
  5314. resizeHandle = {},
  5315. directionHandlePosition,
  5316. orgStyles = {},
  5317. range, mozUserSelect,
  5318. orgCursor,
  5319. offsetParent,
  5320. currentEle,
  5321. handlePosition,
  5322. timer,
  5323. isCancel = false,
  5324. defaultOptions = {
  5325. direction: ['e', 's', 'se'],
  5326. minWidth: 16,
  5327. minHeight: 16,
  5328. classPrefix: 'tangram',
  5329. directionHandlePosition: {}
  5330. };
  5331. if (!(target = baidu.dom.g(element)) && baidu.getStyle(target, 'position') == 'static') {
  5332. return false;
  5333. }
  5334. offsetParent = target.offsetParent;
  5335. var orgPosition = baidu.getStyle(target,'position');
  5336. /*
  5337. * 必要参数的扩展
  5338. * resize handle以方向命名
  5339. * 顺时针的顺序为
  5340. * north northwest west southwest south southeast east northeast
  5341. */
  5342. op = baidu.extend(defaultOptions, options);
  5343. /*
  5344. * 必要参数转换
  5345. */
  5346. baidu.each(['minHeight', 'minWidth', 'maxHeight', 'maxWidth'], function(style) {
  5347. op[style] && (op[style] = parseFloat(op[style]));
  5348. });
  5349. /*
  5350. * {Array[Number]} rangeObject
  5351. * minWidth,maxWidth,minHeight,maxHeight
  5352. */
  5353. range = [
  5354. op.minWidth || 0,
  5355. op.maxWidth || Number.MAX_VALUE,
  5356. op.minHeight || 0,
  5357. op.maxHeight || Number.MAX_VALUE
  5358. ];
  5359. render();
  5360. /**
  5361. * 绘制resizable handle
  5362. */
  5363. function render(){
  5364. //位置属性
  5365. handlePosition = baidu.extend({
  5366. 'e' : {'right': '-5px', 'top': '0px', 'width': '7px', 'height': target.offsetHeight},
  5367. 's' : {'left': '0px', 'bottom': '-5px', 'height': '7px', 'width': target.offsetWidth},
  5368. 'n' : {'left': '0px', 'top': '-5px', 'height': '7px', 'width': target.offsetWidth},
  5369. 'w' : {'left': '-5px', 'top': '0px', 'height':target.offsetHeight , 'width': '7px'},
  5370. 'se': {'right': '1px', 'bottom': '1px', 'height': '16px', 'width': '16px'},
  5371. 'sw': {'left': '1px', 'bottom': '1px', 'height': '16px', 'width': '16px'},
  5372. 'ne': {'right': '1px', 'top': '1px', 'height': '16px', 'width': '16px'},
  5373. 'nw': {'left': '1px', 'top': '1px', 'height': '16px', 'width': '16px'}
  5374. },op.directionHandlePosition);
  5375. //创建resizeHandle
  5376. baidu.each(op.direction, function(key) {
  5377. var className = op.classPrefix.split(' ');
  5378. className[0] = className[0] + '-resizable-' + key;
  5379. var ele = baidu.dom.create('div', {
  5380. className: className.join(' ')
  5381. }),
  5382. styles = handlePosition[key];
  5383. styles['cursor'] = key + '-resize';
  5384. styles['position'] = 'absolute';
  5385. baidu.setStyles(ele, styles);
  5386. ele.key = key;
  5387. ele.style.MozUserSelect = 'none';
  5388. target.appendChild(ele);
  5389. resizeHandle[key] = ele;
  5390. baidu.on(ele, 'mousedown', start);
  5391. });
  5392. isCancel = false;
  5393. }
  5394. /**
  5395. * cancel resizeHandle
  5396. * @public
  5397. * @return void
  5398. */
  5399. function cancel(){
  5400. currentEle && stop();
  5401. baidu.object.each(resizeHandle,function(item){
  5402. baidu.un(item,"mousedown",start);
  5403. baidu.dom.remove(item);
  5404. });
  5405. isCancel = true;
  5406. }
  5407. /**
  5408. * update resizable
  5409. * @public
  5410. * @param {Object} options
  5411. * @return null
  5412. */
  5413. function update(options){
  5414. if(!isCancel){
  5415. op = baidu.extend(op,options || {});
  5416. cancel();
  5417. render();
  5418. }
  5419. }
  5420. /**
  5421. * resizeHandle相应mousedown事件的函数
  5422. * @param {Event} e
  5423. * @return void
  5424. */
  5425. function start(e){
  5426. var ele = baidu.event.getTarget(e),
  5427. key = ele.key;
  5428. currentEle = ele;
  5429. if (ele.setCapture) {
  5430. ele.setCapture();
  5431. } else if (window.captureEvents) {
  5432. window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP);
  5433. }
  5434. /*
  5435. * 给body设置相应的css属性
  5436. * 添加事件监听
  5437. */
  5438. orgCursor = baidu.getStyle(document.body, 'cursor');
  5439. baidu.setStyle(document.body, 'cursor', key + '-resize');
  5440. baidu.on(ele, 'mouseup',stop);
  5441. baidu.on(document.body, 'selectstart', unselect);
  5442. mozUserSelect = document.body.style.MozUserSelect;
  5443. document.body.style.MozUserSelect = 'none';
  5444. /*
  5445. * 获取鼠标坐标
  5446. * 偏移量计算
  5447. */
  5448. var orgMousePosition = baidu.page.getMousePosition();
  5449. orgStyles = _getOrgStyle();
  5450. timer = setInterval(function(){
  5451. resize(key,orgMousePosition);
  5452. }, 20);
  5453. baidu.lang.isFunction(op.onresizestart) && op.onresizestart();
  5454. baidu.event.preventDefault(e);
  5455. }
  5456. /**
  5457. * 当鼠标按键抬起时终止对鼠标事件的监听
  5458. * @private
  5459. * @return void
  5460. */
  5461. function stop() {
  5462. if (currentEle.releaseCapture) {
  5463. currentEle.releaseCapture();
  5464. } else if (window.releaseEvents) {
  5465. window.releaseEvents(Event.MOUSEMOVE | Event.MOUSEUP);
  5466. }
  5467. /*
  5468. * 删除事件监听
  5469. * 还原css属性设置
  5470. */
  5471. baidu.un(currentEle, 'mouseup',stop);
  5472. baidu.un(document, 'selectstart', unselect);
  5473. document.body.style.MozUserSelect = mozUserSelect;
  5474. baidu.un(document.body, 'selectstart', unselect);
  5475. clearInterval(timer);
  5476. baidu.setStyle(document.body, 'cursor',orgCursor);
  5477. currentEle = null;
  5478. baidu.lang.isFunction(op.onresizeend) && op.onresizeend();
  5479. }
  5480. /**
  5481. * 根据鼠标移动的距离来绘制target
  5482. * @private
  5483. * @param {String} key handle的direction字符串
  5484. * @param {Object} orgMousePosition 鼠标坐标{x,y}
  5485. * @return void
  5486. */
  5487. function resize(key,orgMousePosition) {
  5488. var xy = baidu.page.getMousePosition(),
  5489. width = orgStyles['width'],
  5490. height = orgStyles['height'],
  5491. top = orgStyles['top'],
  5492. left = orgStyles['left'],
  5493. styles;
  5494. if (key.indexOf('e') >= 0) {
  5495. width = Math.max(xy.x - orgMousePosition.x + orgStyles['width'], range[0]);
  5496. width = Math.min(width, range[1]);
  5497. }else if (key.indexOf('w') >= 0) {
  5498. width = Math.max(orgMousePosition.x - xy.x + orgStyles['width'], range[0]);
  5499. width = Math.min(width, range[1]);
  5500. left -= width - orgStyles['width'];
  5501. }
  5502. if (key.indexOf('s') >= 0) {
  5503. height = Math.max(xy.y - orgMousePosition.y + orgStyles['height'], range[2]);
  5504. height = Math.min(height, range[3]);
  5505. }else if (key.indexOf('n') >= 0) {
  5506. height = Math.max(orgMousePosition.y - xy.y + orgStyles['height'], range[2]);
  5507. height = Math.min(height, range[3]);
  5508. top -= height - orgStyles['height'];
  5509. }
  5510. styles = {'width': width, 'height': height, 'top': top, 'left': left};
  5511. baidu.dom.setOuterHeight(target,height);
  5512. baidu.dom.setOuterWidth(target,width);
  5513. baidu.setStyles(target,{"top":top,"left":left});
  5514. resizeHandle['n'] && baidu.setStyle(resizeHandle['n'], 'width', width);
  5515. resizeHandle['s'] && baidu.setStyle(resizeHandle['s'], 'width', width);
  5516. resizeHandle['e'] && baidu.setStyle(resizeHandle['e'], 'height', height);
  5517. resizeHandle['w'] && baidu.setStyle(resizeHandle['w'], 'height', height);
  5518. baidu.lang.isFunction(op.onresize) && op.onresize({current:styles,original:orgStyles});
  5519. }
  5520. /**
  5521. * 阻止文字被选中
  5522. * @private
  5523. * @param {Event} e
  5524. * @return {Boolean}
  5525. */
  5526. function unselect(e) {
  5527. return baidu.event.preventDefault(e, false);
  5528. }
  5529. /**
  5530. * 获取target的原始宽高
  5531. * @private
  5532. * @return {Object} {width,height,top,left}
  5533. */
  5534. function _getOrgStyle() {
  5535. var offset_parent = baidu.dom.getPosition(target.offsetParent),
  5536. offset_target = baidu.dom.getPosition(target),
  5537. top,
  5538. left;
  5539. if(orgPosition == "absolute"){
  5540. top = offset_target.top - (target.offsetParent == document.body ? 0 : offset_parent.top);
  5541. left = offset_target.left - (target.offsetParent == document.body ? 0 :offset_parent.left);
  5542. }else{
  5543. top = parseFloat(baidu.getStyle(target,"top")) || -parseFloat(baidu.getStyle(target,"bottom")) || 0;
  5544. left = parseFloat(baidu.getStyle(target,"left")) || -parseFloat(baidu.getStyle(target,"right")) || 0;
  5545. }
  5546. baidu.setStyles(target,{top:top,left:left});
  5547. return {
  5548. width:target.offsetWidth,
  5549. height:target.offsetHeight,
  5550. top:top,
  5551. left:left
  5552. };
  5553. }
  5554. return {cancel:cancel,update:update,enable:render};
  5555. };
  5556. /*
  5557. * Tangram
  5558. * Copyright 2009 Baidu Inc. All rights reserved.
  5559. *
  5560. * path: baidu/dom/setPosition.js
  5561. * author: berg
  5562. * version: 1.0.0
  5563. * date: 2010/12/14
  5564. */
  5565. /**
  5566. * 设置目标元素的top和left值到用户指定的位置
  5567. *
  5568. * @name baidu.dom.setPosition
  5569. * @function
  5570. * @grammar baidu.dom.setPosition(element, position)
  5571. *
  5572. * @param {HTMLElement|string} element 目标元素或目标元素的id
  5573. * @param {object} position 位置对象 {top: {number}, left : {number}}
  5574. *
  5575. * @return {HTMLElement} 进行设置的元素
  5576. */
  5577. baidu.dom.setPosition = function (element, position) {
  5578. return baidu.dom.setStyles(element, {
  5579. left : position.left - (parseFloat(baidu.dom.getStyle(element, "margin-left")) || 0),
  5580. top : position.top - (parseFloat(baidu.dom.getStyle(element, "margin-top")) || 0)
  5581. });
  5582. };
  5583. /*
  5584. * Tangram
  5585. * Copyright 2009 Baidu Inc. All rights reserved.
  5586. */
  5587. /**
  5588. * 显示目标元素,即将目标元素的display属性还原成默认值。默认值可能在stylesheet中定义,或者是继承了浏览器的默认样式值
  5589. * @author allstar, berg
  5590. * @name baidu.dom.show
  5591. * @function
  5592. * @grammar baidu.dom.show(element)
  5593. * @param {HTMLElement|string} element 目标元素或目标元素的id
  5594. * @remark
  5595. * 注意1:如果在CSS中定义此元素的样式为display:none
  5596. * 在调用本函数以后,会将display属性仍然还原成none,元素仍然无法显示。
  5597. * 注意2:如果这个元素的display属性被设置成inline
  5598. * (由element.style.display或者HTML中的style属性设置)
  5599. * 调用本方法将清除此inline属性,导致元素的display属性变成继承值
  5600. * 因此,针对上面两种情况,建议使用dom.setStyle("display", "something")
  5601. * 来明确指定要设置的display属性值。
  5602. *
  5603. * @shortcut show
  5604. * @meta standard
  5605. * @see baidu.dom.hide,baidu.dom.toggle
  5606. *
  5607. * @returns {HTMLElement} 目标元素
  5608. */
  5609. baidu.dom.show = function (element) {
  5610. element = baidu.dom.g(element);
  5611. element.style.display = "";
  5612. return element;
  5613. };
  5614. // 声明快捷方法
  5615. baidu.show = baidu.dom.show;
  5616. /*
  5617. * Tangram
  5618. * Copyright 2009 Baidu Inc. All rights reserved.
  5619. *
  5620. * path: baidu/dom/toggle.js
  5621. * author: allstar
  5622. * version: 1.1.0
  5623. * date: 2009/11/17
  5624. */
  5625. /**
  5626. * 改变目标元素的显示/隐藏状态
  5627. * @name baidu.dom.toggle
  5628. * @function
  5629. * @grammar baidu.dom.toggle(element)
  5630. * @param {HTMLElement|string} element 目标元素或目标元素的id
  5631. * @meta standard
  5632. * @see baidu.dom.show,baidu.dom.hide
  5633. *
  5634. * @returns {HTMLElement} 目标元素
  5635. */
  5636. baidu.dom.toggle = function (element) {
  5637. element = baidu.dom.g(element);
  5638. element.style.display = element.style.display == "none" ? "" : "none";
  5639. return element;
  5640. };
  5641. /*
  5642. * Tangram
  5643. * Copyright 2009 Baidu Inc. All rights reserved.
  5644. *
  5645. * path: baidu/dom/toggleClass.js
  5646. * author: berg
  5647. * version: 1.0
  5648. * date: 2010-07-06
  5649. */
  5650. /**
  5651. * 添加或者删除一个节点中的指定class,如果已经有就删除,否则添加
  5652. * @name baidu.dom.toggleClass
  5653. * @function
  5654. * @grammar baidu.dom.toggleClass(element, className)
  5655. * @param {HTMLElement|string} element 目标元素或目标元素的id
  5656. * @param {String} className 指定的className。允许同时添加多个class,中间使用空白符分隔
  5657. * @version 1.3
  5658. * @remark
  5659. *
  5660. * 传入多个class时,只要其中有一个class不在当前元素中,则添加所有class,否则删除所有class。
  5661. */
  5662. baidu.dom.toggleClass = function (element, className) {
  5663. if(baidu.dom.hasClass(element, className)){
  5664. baidu.dom.removeClass(element, className);
  5665. }else{
  5666. baidu.dom.addClass(element, className);
  5667. }
  5668. };
  5669. /*
  5670. * Tangram
  5671. * Copyright 2009 Baidu Inc. All rights reserved.
  5672. *
  5673. * path: baidu/dom/_styleFilter/color.js
  5674. * author: allstar, erik
  5675. * version: 1.1.0
  5676. * date: 2009/12/02
  5677. */
  5678. /**
  5679. * 提供给setStyle与getStyle使用
  5680. * @meta standard
  5681. */
  5682. baidu.dom._styleFilter[baidu.dom._styleFilter.length] = {
  5683. get: function (key, value) {
  5684. if (/color/i.test(key) && value.indexOf("rgb(") != -1) {
  5685. var array = value.split(",");
  5686. value = "#";
  5687. for (var i = 0, color; color = array[i]; i++){
  5688. color = parseInt(color.replace(/[^\d]/gi, ''), 10).toString(16);
  5689. value += color.length == 1 ? "0" + color : color;
  5690. }
  5691. value = value.toUpperCase();
  5692. }
  5693. return value;
  5694. }
  5695. };
  5696. /*
  5697. * Tangram
  5698. * Copyright 2009 Baidu Inc. All rights reserved.
  5699. *
  5700. * path: baidu/dom/_styleFixer/display.js
  5701. * author: allstar
  5702. * version: 1.1.0
  5703. * date: 2009/11/24
  5704. */
  5705. /**
  5706. * 提供给setStyle与getStyle使用
  5707. * @meta standard
  5708. */
  5709. baidu.dom._styleFixer.display = baidu.browser.ie && baidu.browser.ie < 8 ? { // berg: 修改到<8,因为ie7同样存在这个问题,from 先伟
  5710. set: function (element, value) {
  5711. element = element.style;
  5712. if (value == 'inline-block') {
  5713. element.display = 'inline';
  5714. element.zoom = 1;
  5715. } else {
  5716. element.display = value;
  5717. }
  5718. }
  5719. } : baidu.browser.firefox && baidu.browser.firefox < 3 ? {
  5720. set: function (element, value) {
  5721. element.style.display = value == 'inline-block' ? '-moz-inline-box' : value;
  5722. }
  5723. } : null;
  5724. /*
  5725. * Tangram
  5726. * Copyright 2009 Baidu Inc. All right reserved.
  5727. *
  5728. * path: baidu/dom/_styleFixer/float.js
  5729. * author: allstar
  5730. * version: 1.1.0
  5731. * date: 2009/11/17
  5732. */
  5733. /**
  5734. * 提供给setStyle与getStyle使用
  5735. * @meta standard
  5736. */
  5737. baidu.dom._styleFixer["float"] = baidu.browser.ie ? "styleFloat" : "cssFloat";
  5738. /*
  5739. * Tangram
  5740. * Copyright 2009 Baidu Inc. All rights reserved.
  5741. *
  5742. * path: baidu/dom/_styleFixer/opacity.js
  5743. * author: allstar
  5744. * version: 1.1.0
  5745. * date: 2009/11/17
  5746. */
  5747. /**
  5748. * 提供给setStyle与getStyle使用
  5749. * @meta standard
  5750. */
  5751. baidu.dom._styleFixer.opacity = baidu.browser.ie ? {
  5752. get: function (element) {
  5753. var filter = element.style.filter;
  5754. return filter && filter.indexOf("opacity=") >= 0 ? (parseFloat(filter.match(/opacity=([^)]*)/)[1]) / 100) + "" : "1";
  5755. },
  5756. set: function (element, value) {
  5757. var style = element.style;
  5758. // 只能Quirks Mode下面生效??
  5759. style.filter = (style.filter || "").replace(/alpha\([^\)]*\)/gi, "") + (value == 1 ? "" : "alpha(opacity=" + value * 100 + ")");
  5760. // IE filters only apply to elements with "layout."
  5761. style.zoom = 1;
  5762. }
  5763. } : null;
  5764. /*
  5765. * Tangram
  5766. * Copyright 2009 Baidu Inc. All rights reserved.
  5767. *
  5768. * path: baidu/dom/_styleFixer/textOverflow.js
  5769. * author: allstar
  5770. * version: 1.1.0
  5771. * date: 2009/11/17
  5772. */
  5773. /**
  5774. * 提供给setStyle与getStyle使用,在做textOverflow时会向element对象中添加,_baiduOverflow, _baiduHTML两个属性保存原始的innerHTML信息
  5775. */
  5776. baidu.dom._styleFixer.textOverflow = (function () {
  5777. var fontSizeCache = {};
  5778. function pop(list) {
  5779. var o = list.length;
  5780. if (o > 0) {
  5781. o = list[o - 1];
  5782. list.length--;
  5783. } else {
  5784. o = null;
  5785. }
  5786. return o;
  5787. }
  5788. function setText(element, text) {
  5789. element[baidu.browser.firefox ? "textContent" : "innerText"] = text;
  5790. }
  5791. function count(element, width, ellipsis) {
  5792. /* 计算cache的名称 */
  5793. var o = baidu.browser.ie ? element.currentStyle || element.style : getComputedStyle(element, null),
  5794. fontWeight = o.fontWeight,
  5795. cacheName =
  5796. "font-family:" + o.fontFamily + ";font-size:" + o.fontSize
  5797. + ";word-spacing:" + o.wordSpacing + ";font-weight:" + ((parseInt(fontWeight) || 0) == 401 ? 700 : fontWeight)
  5798. + ";font-style:" + o.fontStyle + ";font-variant:" + o.fontVariant,
  5799. cache = fontSizeCache[cacheName];
  5800. if (!cache) {
  5801. o = element.appendChild(document.createElement("div"));
  5802. o.style.cssText = "float:left;" + cacheName;
  5803. cache = fontSizeCache[cacheName] = [];
  5804. /* 计算ASCII字符的宽度cache */
  5805. for (var i=0; i < 256; i++) {
  5806. i == 32 ? (o.innerHTML = "&nbsp;") : setText(o, String.fromCharCode(i));
  5807. cache[i] = o.offsetWidth;
  5808. }
  5809. /* 计算非ASCII字符的宽度、字符间距、省略号的宽度,\u4e00是汉字一的编码*/
  5810. setText(o, "\u4e00");
  5811. cache[256] = o.offsetWidth;
  5812. setText(o, "\u4e00\u4e00");
  5813. cache[257] = o.offsetWidth - cache[256] * 2;
  5814. cache[258] = cache[".".charCodeAt(0)] * 3 + cache[257] * 3;
  5815. element.removeChild(o);
  5816. }
  5817. for (
  5818. /* wordWidth是每个字符或子节点计算之前的宽度序列 */
  5819. var node = element.firstChild, charWidth = cache[256], wordSpacing = cache[257], ellipsisWidth = cache[258],
  5820. wordWidth = [], ellipsis = ellipsis ? ellipsisWidth : 0;
  5821. node;
  5822. node = node.nextSibling
  5823. ) {
  5824. if (width < ellipsis) {
  5825. element.removeChild(node);
  5826. }
  5827. else if (node.nodeType == 3) {
  5828. for (var i = 0, text = node.nodeValue, length = text.length; i < length; i++) {
  5829. o = text.charCodeAt(i);
  5830. /* 计算增加字符后剩余的长度 */
  5831. wordWidth[wordWidth.length] = [width, node, i];
  5832. width -= (i ? wordSpacing : 0) + (o < 256 ? cache[o] : charWidth);
  5833. if (width < ellipsis) {
  5834. break;
  5835. }
  5836. }
  5837. }
  5838. else {
  5839. o = node.tagName;
  5840. if (o == "IMG" || o == "TABLE") {
  5841. /* 特殊元素直接删除 */
  5842. o = node;
  5843. node = node.previousSibling;
  5844. element.removeChild(o);
  5845. }
  5846. else {
  5847. wordWidth[wordWidth.length] = [width, node];
  5848. width -= node.offsetWidth;
  5849. }
  5850. }
  5851. }
  5852. if (width < ellipsis) {
  5853. /* 过滤直到能得到大于省略号宽度的位置 */
  5854. while (o = pop(wordWidth)) {
  5855. width = o[0];
  5856. node = o[1];
  5857. o = o[2];
  5858. if (node.nodeType == 3) {
  5859. if (width >= ellipsisWidth) {
  5860. node.nodeValue = node.nodeValue.substring(0, o) + "...";
  5861. return true;
  5862. }
  5863. else if (!o) {
  5864. element.removeChild(node);
  5865. }
  5866. }
  5867. else if (count(node, width, true)) {
  5868. return true;
  5869. }
  5870. else {
  5871. element.removeChild(node);
  5872. }
  5873. }
  5874. /* 能显示的宽度小于省略号的宽度,直接不显示 */
  5875. element.innerHTML = "";
  5876. }
  5877. }
  5878. return {
  5879. get: function (element) {
  5880. var browser = baidu.browser,
  5881. getStyle = dom.getStyle;
  5882. return (browser.opera ?
  5883. getStyle("OTextOverflow") :
  5884. browser.firefox ?
  5885. element._baiduOverflow :
  5886. getStyle("textOverflow")) ||
  5887. "clip";
  5888. },
  5889. set: function (element, value) {
  5890. var browser = baidu.browser;
  5891. if (element.tagName == "TD" || element.tagName == "TH" || browser.firefox) {
  5892. element._baiduHTML && (element.innerHTML = element._baiduHTML);
  5893. if (value == "ellipsis") {
  5894. element._baiduHTML = element.innerHTML;
  5895. var o = document.createElement("div"), width = element.appendChild(o).offsetWidth;
  5896. element.removeChild(o);
  5897. count(element, width);
  5898. }
  5899. else {
  5900. element._baiduHTML = "";
  5901. }
  5902. }
  5903. o = element.style;
  5904. browser.opera ? (o.OTextOverflow = value) : browser.firefox ? (element._baiduOverflow = value) : (o.textOverflow = value);
  5905. }
  5906. };
  5907. })();
  5908. /*
  5909. * Tangram
  5910. * Copyright 2009 Baidu Inc. All rights reserved.
  5911. *
  5912. * path: baidu/lang/isArray.js
  5913. * author: erik
  5914. * version: 1.1.0
  5915. * date: 2009/12/30
  5916. */
  5917. /**
  5918. * 判断目标参数是否Array对象
  5919. * @name baidu.lang.isArray
  5920. * @function
  5921. * @grammar baidu.lang.isArray(source)
  5922. * @param {Any} source 目标参数
  5923. * @meta standard
  5924. * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate
  5925. *
  5926. * @returns {boolean} 类型判断结果
  5927. */
  5928. baidu.lang.isArray = function (source) {
  5929. return '[object Array]' == Object.prototype.toString.call(source);
  5930. };
  5931. /*
  5932. * Tangram
  5933. * Copyright 2010 Baidu Inc. All rights reserved.
  5934. *
  5935. * path: baidu/lang/toArray.js
  5936. * author: berg
  5937. * version: 1.0
  5938. * date: 2010-07-05
  5939. */
  5940. /**
  5941. * 将一个变量转换成array
  5942. * @name baidu.lang.toArray
  5943. * @function
  5944. * @grammar baidu.lang.toArray(source)
  5945. * @param {mix} source 需要转换成array的变量
  5946. * @version 1.3
  5947. * @meta standard
  5948. * @returns {array} 转换后的array
  5949. */
  5950. baidu.lang.toArray = function (source) {
  5951. if (source === null || source === undefined)
  5952. return [];
  5953. if (baidu.lang.isArray(source))
  5954. return source;
  5955. // The strings and functions also have 'length'
  5956. if (typeof source.length !== 'number' || typeof source === 'string' || baidu.lang.isFunction(source)) {
  5957. return [source];
  5958. }
  5959. //nodeList, IE 下调用 [].slice.call(nodeList) 会报错
  5960. if (source.item) {
  5961. var l = source.length, array = new Array(l);
  5962. while (l--)
  5963. array[l] = source[l];
  5964. return array;
  5965. }
  5966. return [].slice.call(source);
  5967. };
  5968. /*
  5969. * Tangram
  5970. * Copyright 2009 Baidu Inc. All rights reserved.
  5971. *
  5972. * path: baidu/fn/methodize.js
  5973. * author: berg
  5974. * version: 1.0.0
  5975. * date: 2010/11/02
  5976. */
  5977. /**
  5978. * 将一个静态函数变换成一个对象的方法,使其的第一个参数为this,或this[attr]
  5979. * @name baidu.fn.methodize
  5980. * @function
  5981. * @grammar baidu.fn.methodize(func[, attr])
  5982. * @param {Function} func 要方法化的函数
  5983. * @param {string} [attr] 属性
  5984. * @version 1.3
  5985. * @returns {Function} 已方法化的函数
  5986. */
  5987. baidu.fn.methodize = function (func, attr) {
  5988. return function(){
  5989. return func.apply(this, [(attr ? this[attr] : this)].concat([].slice.call(arguments)));
  5990. };
  5991. };
  5992. /*
  5993. * Tangram
  5994. * Copyright 2009 Baidu Inc. All rights reserved.
  5995. */
  5996. /**
  5997. * 包装函数的返回值,使其在能按照index指定的方式返回。<br/>如果其值为-1,直接返回返回值。 <br/>如果其值为0,返回"返回值"的包装结果。<br/> 如果其值大于0,返回第i个位置的参数的包装结果(从1开始计数)
  5998. * @author berg
  5999. * @name baidu.fn.wrapReturnValue
  6000. * @function
  6001. * @grammar baidu.fn.wrapReturnValue(func, wrapper, mode)
  6002. * @param {function} func 需要包装的函数
  6003. * @param {function} wrapper 包装器
  6004. * @param {number} 包装第几个参数
  6005. * @version 1.3.5
  6006. * @return {function} 包装后的函数
  6007. */
  6008. baidu.fn.wrapReturnValue = function (func, wrapper, mode) {
  6009. mode = mode | 0;
  6010. return function(){
  6011. var ret = func.apply(this, arguments);
  6012. if(mode > 0){
  6013. return new wrapper(arguments[mode - 1]);
  6014. }
  6015. if(!mode){
  6016. return new wrapper(ret);
  6017. }
  6018. return ret;
  6019. }
  6020. };
  6021. /*
  6022. * Tangram
  6023. * Copyright 2009 Baidu Inc. All rights reserved.
  6024. *
  6025. * path: baidu/fn/multize.js
  6026. * author: berg
  6027. * version: 1.0.0
  6028. * date: 2010/11/02
  6029. */
  6030. /**
  6031. * 对函数进行集化,使其在第一个参数为array时,结果也返回一个数组
  6032. * @name baidu.fn.multize
  6033. * @function
  6034. * @grammar baidu.fn.multize(func[, recursive])
  6035. * @param {Function} func 需要包装的函数
  6036. * @param {Boolean} [recursive] 是否递归包装(如果数组里面一项仍然是数组,递归),可选
  6037. * @param {Boolean} [joinArray] 将操作的结果展平后返回(如果返回的结果是数组,则将多个数组合成一个),可选
  6038. * @version 1.3
  6039. *
  6040. * @returns {Function} 已集化的函数
  6041. */
  6042. baidu.fn.multize = function (func, recursive, joinArray) {
  6043. var newFunc = function(){
  6044. var list = arguments[0],
  6045. fn = recursive ? newFunc : func,
  6046. ret = [],
  6047. moreArgs = [].slice.call(arguments,0),
  6048. i = 0,
  6049. len,
  6050. r;
  6051. if(list instanceof Array){
  6052. for(len = list.length; i < len; i++){
  6053. moreArgs[0]=list[i];
  6054. r = fn.apply(this, moreArgs);
  6055. if (joinArray) {
  6056. if (r) {
  6057. //TODO: 需要去重吗?
  6058. ret = ret.concat(r);
  6059. }
  6060. } else {
  6061. ret.push(r);
  6062. }
  6063. }
  6064. return ret;
  6065. }else{
  6066. return func.apply(this, arguments);
  6067. }
  6068. }
  6069. return newFunc;
  6070. };
  6071. /*
  6072. * Tangram
  6073. * Copyright 2010 Baidu Inc. All right reserved.
  6074. *
  6075. * path: baidu/dom/element.js
  6076. * author: berg
  6077. * version: 1.0.0
  6078. * date: 2010-07-12
  6079. */
  6080. /**
  6081. * @namespace baidu.element 通过该方法封装的对象可使用dom、event方法集合以及each方法进行链式调用。
  6082. */
  6083. baidu.element = baidu.e = function(node){
  6084. var gNode = baidu._g(node);
  6085. if(!gNode && baidu.dom.query){
  6086. gNode = baidu.dom.query(node);
  6087. }
  6088. return new baidu.element.Element(gNode);
  6089. };
  6090. /**
  6091. * Element类,所有扩展到链条上的方法都会被放在这里面
  6092. * @name baidu.element.Element
  6093. * @grammar baidu.element.Element(node)
  6094. * @param {DOMElement|NodeList} node 目标元素,可以是数组或者单个node节点
  6095. * @returns {ElementObj} 包装后的DOM对象
  6096. * @version 1.3
  6097. */
  6098. baidu.element.Element = function(node){
  6099. if(!baidu.element._init){
  6100. //由于element可能会在其他代码之前加载,因此用这个方法来延迟加载
  6101. baidu.element._makeChain();
  6102. baidu.element._init = true;
  6103. }
  6104. /**
  6105. * @private
  6106. * @type {Array.<Node>}
  6107. */
  6108. this._dom = (node.tagName || '').toLowerCase() == 'select' ?
  6109. [node] : baidu.lang.toArray(node);
  6110. };
  6111. /**
  6112. * 以每一个匹配的元素作为上下文执行传递进来的函数,方便用户自行遍历dom。
  6113. * @name baidu.element.each
  6114. * @function
  6115. * @grammar baidu.element(node).each(iterator)
  6116. * @param {Function} iterator 遍历Dom时调用的方法
  6117. * @version 1.3
  6118. */
  6119. baidu.element.Element.prototype.each = function(iterator) {
  6120. // 每一个iterator接受到的都是封装好的node
  6121. baidu.array.each(this._dom, function(node, i){
  6122. iterator.call(node, node, i);
  6123. });
  6124. };
  6125. /*
  6126. * 包装静态方法,使其变成一个链条方法。
  6127. * 先把静态方法multize化,让其支持接受数组参数,
  6128. * 然后包装返回值,返回值是一个包装类
  6129. * 最后把静态方法methodize化,让其变成一个对象方法。
  6130. *
  6131. * @param {Function} func 要包装的静态方法
  6132. * @param {number} index 包装函数的第几个返回值
  6133. *
  6134. * @return {function} 包装后的方法,能直接挂到Element的prototype上。
  6135. * @private
  6136. */
  6137. baidu.element._toChainFunction = function(func, index, joinArray){
  6138. return baidu.fn.methodize(baidu.fn.wrapReturnValue(baidu.fn.multize(func, 0, 1), baidu.element.Element, index), '_dom');
  6139. };
  6140. /**
  6141. * element对象包装了dom包下的除了drag和ready,create,ddManager之外的大部分方法。这样做的目的是提供更为方便的链式调用操作。其中doms代指dom包下的方法名。
  6142. * @name baidu.element.doms
  6143. * @function
  6144. * @grammar baidu.element(node).doms
  6145. * @param 详见dom包下相应方法的参数。
  6146. * @version 1.3
  6147. * @private
  6148. */
  6149. baidu.element._makeChain = function(){ //将dom/event包下的东西挂到prototype里面
  6150. var proto = baidu.element.Element.prototype,
  6151. fnTransformer = baidu.element._toChainFunction;
  6152. //返回值是第一个参数的包装
  6153. baidu.each(("draggable droppable resizable").split(' '),
  6154. function(fn){
  6155. proto[fn] = fnTransformer(baidu.dom[fn], 1);
  6156. });
  6157. //直接返回返回值
  6158. baidu.each(("remove getText contains getAttr getPosition getStyle hasClass intersect hasAttr getComputedStyle").split(' '),
  6159. function(fn){
  6160. proto[fn] = proto[fn.replace(/^get[A-Z]/g, stripGet)] = fnTransformer(baidu.dom[fn], -1);
  6161. });
  6162. //包装返回值
  6163. //包含
  6164. //1. methodize
  6165. //2. multize,结果如果是数组会被展平
  6166. //3. getXx == xx
  6167. baidu.each(("addClass empty hide show insertAfter insertBefore insertHTML removeClass " +
  6168. "setAttr setAttrs setStyle setStyles show toggleClass toggle next first " +
  6169. "getAncestorByClass getAncestorBy getAncestorByTag getDocument getParent getWindow " +
  6170. "last next prev g removeStyle setBorderBoxSize setOuterWidth setOuterHeight " +
  6171. "setBorderBoxWidth setBorderBoxHeight setPosition children query").split(' '),
  6172. function(fn){
  6173. proto[fn] = proto[fn.replace(/^get[A-Z]/g, stripGet)] = fnTransformer(baidu.dom[fn], 0);
  6174. });
  6175. //对于baidu.dom.q这种特殊情况,将前两个参数调转
  6176. //TODO:需要将这种特殊情况归纳到之前的情况中
  6177. proto['q'] = proto['Q'] = fnTransformer(function(arg1, arg2){
  6178. return baidu.dom.q.apply(this, [arg2, arg1].concat([].slice.call(arguments, 2)));
  6179. }, 0);
  6180. //包装event中的on 和 un
  6181. baidu.each(("on un").split(' '), function(fn){
  6182. proto[fn] = fnTransformer(baidu.event[fn], 0);
  6183. });
  6184. /**
  6185. * 方法提供了事件绑定的快捷方式,事件发生时会触发传递进来的函数。events代指事件方法的总和。
  6186. * @name baidu.element.events
  6187. * @function
  6188. * @grammar baidu.element(node).events(fn)
  6189. * @param {Function} fn 事件触发时要调用的方法
  6190. * @version 1.3
  6191. * @remark 包装event的快捷方式具体包括blur、focus、focusin、focusout、load 、resize 、scroll 、unload 、click、 dblclick、mousedown 、mouseup 、mousemove、 mouseover 、mouseout 、mouseenter、 mouseleave、change 、select 、submit 、keydown、 keypress 、keyup、 error。
  6192. * @returns {baidu.element} Element对象
  6193. */
  6194. //包装event的快捷方式
  6195. baidu.each(("blur focus focusin focusout load resize scroll unload click dblclick " +
  6196. "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  6197. "change select submit keydown keypress keyup error").split(' '), function(fnName){
  6198. proto[fnName] = function(fn){
  6199. return this.on(fnName, fn);
  6200. };
  6201. });
  6202. /**
  6203. * 把get去掉
  6204. * 链里面的方法可以不以get开头调用
  6205. * 如 baidu.element("myDiv").parent() == baidu.element("myDiv").getParent();
  6206. * TODO: 合并getter和setter. baidu.e('myDiv').style() & baidu.e('myDiv').style('width', '100');
  6207. */
  6208. function stripGet(match) {
  6209. return match.charAt(3).toLowerCase();
  6210. }
  6211. };
  6212. /*
  6213. * Tangram
  6214. * Copyright 2009 Baidu Inc. All rights reserved.
  6215. *
  6216. * path: baidu/element/extend.js
  6217. * author: berg
  6218. * version: 1.0.0
  6219. * date: 2010/12/16
  6220. */
  6221. /**
  6222. * 为element对象扩展一个方法。
  6223. * @name baidu.element.extend
  6224. * @function
  6225. * @grammar baidu.element.extend(json)
  6226. * @param {Object} json 要扩展的方法名以及方法
  6227. * @version 1.3
  6228. * @shortcut e
  6229. * @returns {baidu.element.Element} Element对象
  6230. *
  6231. */
  6232. baidu.element.extend = function(json){
  6233. var e = baidu.element;
  6234. baidu.object.each(json, function(item, key){
  6235. e.Element.prototype[key] = baidu.element._toChainFunction(item, -1);
  6236. });
  6237. };
  6238. /*
  6239. * Tangram
  6240. * Copyright 2009 Baidu Inc. All rights reserved.
  6241. *
  6242. * path: baidu/event/EventArg.js
  6243. * author: erik
  6244. * version: 1.1.0
  6245. * date: 2010/01/11
  6246. */
  6247. /**
  6248. * 事件对象构造器,屏蔽浏览器差异的事件类
  6249. * @name baidu.event.EventArg
  6250. * @function
  6251. * @grammar baidu.event.EventArg(event[, win])
  6252. * @param {Event} event 事件对象
  6253. * @param {Window} [win] 窗口对象,默认为window
  6254. * @meta standard
  6255. * @remark 1.1.0开始支持
  6256. * @see baidu.event.get
  6257. * @constructor
  6258. */
  6259. baidu.event.EventArg = function (event, win) {
  6260. win = win || window;
  6261. event = event || win.event;
  6262. var doc = win.document;
  6263. this.target = /** @type {Node} */ (event.target) || event.srcElement;
  6264. this.keyCode = event.which || event.keyCode;
  6265. for (var k in event) {
  6266. var item = event[k];
  6267. // 避免拷贝preventDefault等事件对象方法
  6268. if ('function' != typeof item) {
  6269. this[k] = item;
  6270. }
  6271. }
  6272. if (!this.pageX && this.pageX !== 0) {
  6273. this.pageX = (event.clientX || 0)
  6274. + (doc.documentElement.scrollLeft
  6275. || doc.body.scrollLeft);
  6276. this.pageY = (event.clientY || 0)
  6277. + (doc.documentElement.scrollTop
  6278. || doc.body.scrollTop);
  6279. }
  6280. this._event = event;
  6281. };
  6282. /**
  6283. * 阻止事件的默认行为
  6284. * @name preventDefault
  6285. * @grammar eventArgObj.preventDefault()
  6286. * @returns {baidu.event.EventArg} EventArg对象
  6287. */
  6288. baidu.event.EventArg.prototype.preventDefault = function () {
  6289. if (this._event.preventDefault) {
  6290. this._event.preventDefault();
  6291. } else {
  6292. this._event.returnValue = false;
  6293. }
  6294. return this;
  6295. };
  6296. /**
  6297. * 停止事件的传播
  6298. * @name stopPropagation
  6299. * @grammar eventArgObj.stopPropagation()
  6300. * @returns {baidu.event.EventArg} EventArg对象
  6301. */
  6302. baidu.event.EventArg.prototype.stopPropagation = function () {
  6303. if (this._event.stopPropagation) {
  6304. this._event.stopPropagation();
  6305. } else {
  6306. this._event.cancelBubble = true;
  6307. }
  6308. return this;
  6309. };
  6310. /**
  6311. * 停止事件
  6312. * @name stop
  6313. * @grammar eventArgObj.stop()
  6314. * @returns {baidu.event.EventArg} EventArg对象
  6315. */
  6316. baidu.event.EventArg.prototype.stop = function () {
  6317. return this.stopPropagation().preventDefault();
  6318. };
  6319. /*
  6320. * Tangram
  6321. * Copyright 2009 Baidu Inc. All rights reserved.
  6322. *
  6323. * path: baidu/object/values.js
  6324. * author: erik
  6325. * version: 1.1.0
  6326. * date: 2009/11/15
  6327. */
  6328. /**
  6329. * 获取目标对象的值列表
  6330. * @name baidu.object.values
  6331. * @function
  6332. * @grammar baidu.object.values(source)
  6333. * @param {Object} source 目标对象
  6334. * @see baidu.object.keys
  6335. *
  6336. * @returns {Array} 值列表
  6337. */
  6338. baidu.object.values = function (source) {
  6339. var result = [], resultLen = 0, k;
  6340. for (k in source) {
  6341. if (source.hasOwnProperty(k)) {
  6342. result[resultLen++] = source[k];
  6343. }
  6344. }
  6345. return result;
  6346. };
  6347. /*
  6348. * Tangram
  6349. * Copyright 2009 Baidu Inc. All rights reserved.
  6350. *
  6351. * path: baidu/event/fire.js
  6352. * author: linlingyu
  6353. * version: 1.1.0
  6354. * date: 2010/10/28
  6355. */
  6356. /**
  6357. * 触发已经注册的事件。注:在ie下不支持load和unload事件
  6358. * @name baidu.event.fire
  6359. * @function
  6360. * @grammar baidu.event.fire(element, type, options)
  6361. * @param {HTMLElement|string|window} element 目标元素或目标元素id
  6362. * @param {string} type 事件类型
  6363. * @param {Object} options 触发的选项
  6364. * @param {Boolean} options.bubbles 是否冒泡
  6365. * @param {Boolean} options.cancelable 是否可以阻止事件的默认操作
  6366. * @param {window|null} options.view 指定 Event 的 AbstractView
  6367. * @param {1|Number} options.detail 指定 Event 的鼠标单击量
  6368. * @param {Number} options.screenX 指定 Event 的屏幕 x 坐标
  6369. * @param {Number} options.screenY number 指定 Event 的屏幕 y 坐标
  6370. * @param {Number} options.clientX 指定 Event 的客户端 x 坐标
  6371. * @param {Number} options.clientY 指定 Event 的客户端 y 坐标
  6372. * @param {Boolean} options.ctrlKey 指定是否在 Event 期间按下 ctrl 键
  6373. * @param {Boolean} options.altKey 指定是否在 Event 期间按下 alt 键
  6374. * @param {Boolean} options.shiftKey 指定是否在 Event 期间按下 shift 键
  6375. * @param {Boolean} options.metaKey 指定是否在 Event 期间按下 meta 键
  6376. * @param {Number} options.button 指定 Event 的鼠标按键
  6377. * @param {Number} options.keyCode 指定 Event 的键盘按键
  6378. * @param {Number} options.charCode 指定 Event 的字符编码
  6379. * @param {HTMLElement} options.relatedTarget 指定 Event 的相关 EventTarget
  6380. * @version 1.3
  6381. *
  6382. * @returns {HTMLElement} 目标元素
  6383. */
  6384. (function(){
  6385. var browser = baidu.browser,
  6386. keys = {
  6387. keydown : 1,
  6388. keyup : 1,
  6389. keypress : 1
  6390. },
  6391. mouses = {
  6392. click : 1,
  6393. dblclick : 1,
  6394. mousedown : 1,
  6395. mousemove : 1,
  6396. mouseup : 1,
  6397. mouseover : 1,
  6398. mouseout : 1
  6399. },
  6400. htmls = {
  6401. abort : 1,
  6402. blur : 1,
  6403. change : 1,
  6404. error : 1,
  6405. focus : 1,
  6406. load : browser.ie ? 0 : 1,
  6407. reset : 1,
  6408. resize : 1,
  6409. scroll : 1,
  6410. select : 1,
  6411. submit : 1,
  6412. unload : browser.ie ? 0 : 1
  6413. },
  6414. bubblesEvents = {
  6415. scroll : 1,
  6416. resize : 1,
  6417. reset : 1,
  6418. submit : 1,
  6419. change : 1,
  6420. select : 1,
  6421. error : 1,
  6422. abort : 1
  6423. },
  6424. parameters = {
  6425. "KeyEvents" : ["bubbles", "cancelable", "view", "ctrlKey", "altKey", "shiftKey", "metaKey", "keyCode", "charCode"],
  6426. "MouseEvents" : ["bubbles", "cancelable", "view", "detail", "screenX", "screenY", "clientX", "clientY", "ctrlKey", "altKey", "shiftKey", "metaKey", "button", "relatedTarget"],
  6427. "HTMLEvents" : ["bubbles", "cancelable"],
  6428. "UIEvents" : ["bubbles", "cancelable", "view", "detail"],
  6429. "Events" : ["bubbles", "cancelable"]
  6430. };
  6431. baidu.object.extend(bubblesEvents, keys);
  6432. baidu.object.extend(bubblesEvents, mouses);
  6433. function parse(array, source){//按照array的项在source中找到值生成新的obj并把source中对应的array的项删除
  6434. var i = 0, size = array.length, obj = {};
  6435. for(; i < size; i++){
  6436. obj[array[i]] = source[array[i]];
  6437. delete source[array[i]];
  6438. }
  6439. return obj;
  6440. };
  6441. function eventsHelper(type, eventType, options){//非IE内核的事件辅助
  6442. options = baidu.object.extend({}, options);
  6443. var param = baidu.object.values(parse(parameters[eventType], options)),
  6444. evnt = document.createEvent(eventType);
  6445. param.unshift(type);
  6446. if("KeyEvents" == eventType){
  6447. evnt.initKeyEvent.apply(evnt, param);
  6448. }else if("MouseEvents" == eventType){
  6449. evnt.initMouseEvent.apply(evnt, param);
  6450. }else if("UIEvents" == eventType){
  6451. evnt.initUIEvent.apply(evnt, param);
  6452. }else{//HTMMLEvents, Events
  6453. evnt.initEvent.apply(evnt, param);
  6454. }
  6455. baidu.object.extend(evnt, options);//把多出来的options再附加上去,这是为解决当创建一个其它event时,当用Events代替后需要把参数附加到对象上
  6456. return evnt;
  6457. };
  6458. function eventObject(options){//ie内核的构建方式
  6459. var evnt;
  6460. if(document.createEventObject){
  6461. evnt = document.createEventObject();
  6462. baidu.object.extend(evnt, options);
  6463. }
  6464. return evnt;
  6465. };
  6466. function keyEvents(type, options){//keyEvents
  6467. options = parse(parameters["KeyEvents"], options);
  6468. var evnt;
  6469. if(document.createEvent){
  6470. try{//opera对keyEvents的支持极差
  6471. evnt = eventsHelper(type, "KeyEvents", options);
  6472. }catch(keyError){
  6473. try{
  6474. evnt = eventsHelper(type, "Events", options);
  6475. }catch(evtError){
  6476. evnt = eventsHelper(type, "UIEvents", options);
  6477. }
  6478. }
  6479. }else{
  6480. options.keyCode = options.charCode > 0 ? options.charCode : options.keyCode;
  6481. evnt = eventObject(options);
  6482. }
  6483. return evnt;
  6484. };
  6485. function mouseEvents(type, options){//mouseEvents
  6486. options = parse(parameters["MouseEvents"], options);
  6487. var evnt;
  6488. if(document.createEvent){
  6489. evnt = eventsHelper(type, "MouseEvents", options);//mouseEvents基本浏览器都支持
  6490. if(options.relatedTarget && !evnt.relatedTarget){
  6491. if("mouseout" == type.toLowerCase()){
  6492. evnt.toElement = options.relatedTarget;
  6493. }else if("mouseover" == type.toLowerCase()){
  6494. evnt.fromElement = options.relatedTarget;
  6495. }
  6496. }
  6497. }else{
  6498. options.button = options.button == 0 ? 1
  6499. : options.button == 1 ? 4
  6500. : baidu.lang.isNumber(options.button) ? options.button : 0;
  6501. evnt = eventObject(options);
  6502. }
  6503. return evnt;
  6504. };
  6505. function htmlEvents(type, options){//htmlEvents
  6506. options.bubbles = bubblesEvents.hasOwnProperty(type);
  6507. options = parse(parameters["HTMLEvents"], options);
  6508. var evnt;
  6509. if(document.createEvent){
  6510. try{
  6511. evnt = eventsHelper(type, "HTMLEvents", options);
  6512. }catch(htmlError){
  6513. try{
  6514. evnt = eventsHelper(type, "UIEvents", options);
  6515. }catch(uiError){
  6516. evnt = eventsHelper(type, "Events", options);
  6517. }
  6518. }
  6519. }else{
  6520. evnt = eventObject(options);
  6521. }
  6522. return evnt;
  6523. };
  6524. baidu.event.fire = function(element, type, options){
  6525. var evnt;
  6526. type = type.replace(/^on/i, "");
  6527. element = baidu.dom._g(element);
  6528. options = baidu.object.extend({
  6529. bubbles : true,
  6530. cancelable : true,
  6531. view : window,
  6532. detail : 1,
  6533. screenX : 0,
  6534. screenY : 0,
  6535. clientX : 0,
  6536. clientY : 0,
  6537. ctrlKey : false,
  6538. altKey : false,
  6539. shiftKey: false,
  6540. metaKey : false,
  6541. keyCode : 0,
  6542. charCode: 0,
  6543. button : 0,
  6544. relatedTarget : null
  6545. }, options);
  6546. if(keys[type]){
  6547. evnt = keyEvents(type, options);
  6548. }else if(mouses[type]){
  6549. evnt = mouseEvents(type, options);
  6550. }else if(htmls[type]){
  6551. evnt = htmlEvents(type, options);
  6552. }else{
  6553. throw(new Error(type + " is not support!"));
  6554. }
  6555. if(evnt){//tigger event
  6556. if(element.dispatchEvent){
  6557. element.dispatchEvent(evnt);
  6558. }else if(element.fireEvent){
  6559. element.fireEvent("on" + type, evnt);
  6560. }
  6561. }
  6562. }
  6563. })();
  6564. /*
  6565. * Tangram
  6566. * Copyright 2009 Baidu Inc. All rights reserved.
  6567. *
  6568. * path: baidu/event/get.js
  6569. * author: erik
  6570. * version: 1.1.0
  6571. * date: 2009/11/23
  6572. */
  6573. /**
  6574. * 获取扩展的EventArg对象
  6575. * @name baidu.event.get
  6576. * @function
  6577. * @grammar baidu.event.get(event[, win])
  6578. * @param {Event} event 事件对象
  6579. * @param {window} [win] 触发事件元素所在的window
  6580. * @meta standard
  6581. * @see baidu.event.EventArg
  6582. *
  6583. * @returns {EventArg} 扩展的事件对象
  6584. */
  6585. baidu.event.get = function (event, win) {
  6586. return new baidu.event.EventArg(event, win);
  6587. };
  6588. /*
  6589. * Tangram
  6590. * Copyright 2009 Baidu Inc. All rights reserved.
  6591. *
  6592. * path: baidu/event/getKeyCode.js
  6593. * author: erik
  6594. * version: 1.1.0
  6595. * date: 2009/11/23
  6596. */
  6597. /**
  6598. * 获取键盘事件的键值
  6599. * @name baidu.event.getKeyCode
  6600. * @function
  6601. * @grammar baidu.event.getKeyCode(event)
  6602. * @param {Event} event 事件对象
  6603. *
  6604. * @returns {number} 键盘事件的键值
  6605. */
  6606. baidu.event.getKeyCode = function (event) {
  6607. return event.which || event.keyCode;
  6608. };
  6609. /*
  6610. * Tangram
  6611. * Copyright 2009 Baidu Inc. All rights reserved.
  6612. *
  6613. * path: baidu/event/getPageX.js
  6614. * author: erik
  6615. * version: 1.1.0
  6616. * date: 2009/12/16
  6617. */
  6618. /**
  6619. * 获取鼠标事件的鼠标x坐标
  6620. * @name baidu.event.getPageX
  6621. * @function
  6622. * @grammar baidu.event.getPageX(event)
  6623. * @param {Event} event 事件对象
  6624. * @see baidu.event.getPageY
  6625. *
  6626. * @returns {number} 鼠标事件的鼠标x坐标
  6627. */
  6628. baidu.event.getPageX = function (event) {
  6629. var result = event.pageX,
  6630. doc = document;
  6631. if (!result && result !== 0) {
  6632. result = (event.clientX || 0)
  6633. + (doc.documentElement.scrollLeft
  6634. || doc.body.scrollLeft);
  6635. }
  6636. return result;
  6637. };
  6638. /*
  6639. * Tangram
  6640. * Copyright 2009 Baidu Inc. All rights reserved.
  6641. *
  6642. * path: baidu/event/getPageY.js
  6643. * author: erik
  6644. * version: 1.1.0
  6645. * date: 2009/12/16
  6646. */
  6647. /**
  6648. * 获取鼠标事件的鼠标y坐标
  6649. * @name baidu.event.getPageY
  6650. * @function
  6651. * @grammar baidu.event.getPageY(event)
  6652. * @param {Event} event 事件对象
  6653. * @see baidu.event.getPageX
  6654. *
  6655. * @returns {number} 鼠标事件的鼠标y坐标
  6656. */
  6657. baidu.event.getPageY = function (event) {
  6658. var result = event.pageY,
  6659. doc = document;
  6660. if (!result && result !== 0) {
  6661. result = (event.clientY || 0)
  6662. + (doc.documentElement.scrollTop
  6663. || doc.body.scrollTop);
  6664. }
  6665. return result;
  6666. };
  6667. /*
  6668. * Tangram
  6669. * Copyright 2009 Baidu Inc. All rights reserved.
  6670. *
  6671. * path: baidu/event/once.js
  6672. * author: wangcheng
  6673. * version: 1.1.0
  6674. * date: 2010/10/29
  6675. */
  6676. /**
  6677. * 为目标元素添加一次事件绑定
  6678. * @name baidu.event.once
  6679. * @function
  6680. * @grammar baidu.event.once(element, type, listener)
  6681. * @param {HTMLElement|string} element 目标元素或目标元素id
  6682. * @param {string} type 事件类型
  6683. * @param {Function} listener 需要添加的监听器
  6684. * @version 1.3
  6685. * @see baidu.event.un,baidu.event.on
  6686. *
  6687. * @returns {HTMLElement} 目标元素
  6688. */
  6689. baidu.event.once = function(element, type, listener){
  6690. element = baidu.dom._g(element);
  6691. function onceListener(event){
  6692. listener.call(element,event);
  6693. baidu.event.un(element, type, onceListener);
  6694. }
  6695. baidu.event.on(element, type, onceListener);
  6696. return element;
  6697. };
  6698. /*
  6699. * Tangram
  6700. * Copyright 2009 Baidu Inc. All rights reserved.
  6701. *
  6702. * path: baidu/event/stopPropagation.js
  6703. * author: erik
  6704. * version: 1.1.0
  6705. * date: 2009/11/23
  6706. */
  6707. /**
  6708. * 阻止事件传播
  6709. * @name baidu.event.stopPropagation
  6710. * @function
  6711. * @grammar baidu.event.stopPropagation(event)
  6712. * @param {Event} event 事件对象
  6713. * @see baidu.event.stop,baidu.event.preventDefault
  6714. */
  6715. baidu.event.stopPropagation = function (event) {
  6716. if (event.stopPropagation) {
  6717. event.stopPropagation();
  6718. } else {
  6719. event.cancelBubble = true;
  6720. }
  6721. };
  6722. /*
  6723. * Tangram
  6724. * Copyright 2009 Baidu Inc. All rights reserved.
  6725. *
  6726. * path: baidu/event/stop.js
  6727. * author: erik
  6728. * version: 1.1.0
  6729. * date: 2009/11/23
  6730. */
  6731. /**
  6732. * 停止事件
  6733. * @name baidu.event.stop
  6734. * @function
  6735. * @grammar baidu.event.stop(event)
  6736. * @param {Event} event 事件对象
  6737. * @see baidu.event.stopPropagation,baidu.event.preventDefault
  6738. */
  6739. baidu.event.stop = function (event) {
  6740. var e = baidu.event;
  6741. e.stopPropagation(event);
  6742. e.preventDefault(event);
  6743. };
  6744. /*
  6745. * Tangram
  6746. * Copyright 2009 Baidu Inc. All rights reserved.
  6747. *
  6748. * path: baidu/event/_eventFilter.js
  6749. * author: rocy
  6750. * version: 1.0.0
  6751. * date: 2010/10/29
  6752. */
  6753. baidu.event._eventFilter = baidu.event._eventFilter || {};
  6754. /*
  6755. * Tangram
  6756. * Copyright 2009 Baidu Inc. All rights reserved.
  6757. *
  6758. * path: baidu/event/_eventFilter/_crossElementBoundary.js
  6759. * author: Rocy, berg
  6760. * version: 1.0.0
  6761. * date: 2010/12/16
  6762. */
  6763. /**
  6764. * 事件仅在鼠标进入/离开元素区域触发一次,当鼠标在元素区域内部移动的时候不会触发,用于为非IE浏览器添加mouseleave/mouseenter支持。
  6765. *
  6766. * @name baidu.event._eventFilter._crossElementBoundary
  6767. * @function
  6768. * @grammar baidu.event._eventFilter._crossElementBoundary(listener, e)
  6769. *
  6770. * @param {function} listener 要触发的函数
  6771. * @param {DOMEvent} e DOM事件
  6772. */
  6773. baidu.event._eventFilter._crossElementBoundary = function(listener, e){
  6774. var related = e.relatedTarget,
  6775. current = e.currentTarget;
  6776. if(
  6777. related === false ||
  6778. // 如果current和related都是body,contains函数会返回false
  6779. current == related ||
  6780. // Firefox有时会把XUL元素作为relatedTarget
  6781. // 这些元素不能访问parentNode属性
  6782. // thanks jquery & mootools
  6783. (related && (related.prefix == 'xul' ||
  6784. //如果current包含related,说明没有经过current的边界
  6785. baidu.dom.contains(current, related)))
  6786. ){
  6787. return ;
  6788. }
  6789. return listener.call(current, e);
  6790. };
  6791. /*
  6792. * Tangram
  6793. * Copyright 2009 Baidu Inc. All rights reserved.
  6794. *
  6795. * path: baidu/fn/bind.js
  6796. * author: berg
  6797. * version: 1.0.0
  6798. * date: 2010/11/02
  6799. */
  6800. /**
  6801. * 为对象绑定方法和作用域
  6802. * @name baidu.fn.bind
  6803. * @function
  6804. * @grammar baidu.fn.bind(handler[, obj, args])
  6805. * @param {Function|String} handler 要绑定的函数,或者一个在作用域下可用的函数名
  6806. * @param {Object} obj 执行运行时this,如果不传入则运行时this为函数本身
  6807. * @param {args* 0..n} args 函数执行时附加到执行时函数前面的参数
  6808. * @version 1.3
  6809. *
  6810. * @returns {Function} 封装后的函数
  6811. */
  6812. baidu.fn.bind = function(func, scope) {
  6813. var xargs = arguments.length > 2 ? [].slice.call(arguments, 2) : null;
  6814. return function () {
  6815. var fn = baidu.lang.isString(func) ? scope[func] : func,
  6816. args = (xargs) ? xargs.concat([].slice.call(arguments, 0)) : arguments;
  6817. return fn.apply(scope || fn, args);
  6818. };
  6819. };
  6820. /*
  6821. * Tangram
  6822. * Copyright 2009 Baidu Inc. All rights reserved.
  6823. *
  6824. * path: baidu/event/_eventFilter/mouseenter.js
  6825. * author: Rocy
  6826. * version: 1.0.0
  6827. * date: 2010/11/09
  6828. */
  6829. /**
  6830. * 用于为非IE浏览器添加mouseenter的支持;
  6831. * mouseenter事件仅在鼠标进入元素区域触发一次,
  6832. * 当鼠标在元素内部移动的时候不会多次触发.
  6833. */
  6834. baidu.event._eventFilter.mouseenter = window.attachEvent ? null : function(element,type, listener){
  6835. return {
  6836. type: "mouseover",
  6837. listener: baidu.fn.bind(baidu.event._eventFilter._crossElementBoundary, this, listener)
  6838. }
  6839. };
  6840. /*
  6841. * Tangram
  6842. * Copyright 2009 Baidu Inc. All rights reserved.
  6843. *
  6844. * path: baidu/event/_eventFilter/mouseleave.js
  6845. * author: Rocy, berg
  6846. * version: 1.0.0
  6847. * date: 2010/11/09
  6848. */
  6849. /**
  6850. * 用于为非IE浏览器添加mouseleave的支持;
  6851. * mouseleave事件仅在鼠标移出元素区域触发一次,
  6852. * 当鼠标在元素区域内部移动的时候不会触发.
  6853. */
  6854. baidu.event._eventFilter.mouseleave = window.attachEvent ? null : function(element,type, listener){
  6855. return {
  6856. type: "mouseout",
  6857. listener: baidu.fn.bind(baidu.event._eventFilter._crossElementBoundary, this, listener)
  6858. }
  6859. };
  6860. /*
  6861. * Tangram
  6862. * Copyright 2009 Baidu Inc. All rights reserved.
  6863. *
  6864. * path: baidu/event/_unload.js
  6865. * author: erik, berg
  6866. * version: 1.1.0
  6867. * date: 2009/12/16
  6868. */
  6869. /**
  6870. * 卸载所有事件监听器
  6871. * @private
  6872. */
  6873. baidu.event._unload = function() {
  6874. var lis = baidu.event._listeners,
  6875. len = lis.length,
  6876. standard = !!window.removeEventListener,
  6877. item, el;
  6878. while (len--) {
  6879. item = lis[len];
  6880. //20100409 berg: 不解除unload的绑定,保证用户的事件一定会被执行
  6881. //否则用户挂载进入的unload事件也可能会在这里被删除
  6882. if (item[1] == 'unload') {
  6883. continue;
  6884. }
  6885. //如果el被移除,不做判断将导致js报错
  6886. if (!(el = item[0])) {
  6887. continue;
  6888. }
  6889. if (el.removeEventListener) {
  6890. el.removeEventListener(item[1], item[3], false);
  6891. } else if (el.detachEvent) {
  6892. el.detachEvent('on' + item[1], item[3]);
  6893. }
  6894. }
  6895. if (standard) {
  6896. window.removeEventListener('unload', baidu.event._unload, false);
  6897. } else {
  6898. window.detachEvent('onunload', baidu.event._unload);
  6899. }
  6900. };
  6901. // 在页面卸载的时候,将所有事件监听器移除
  6902. if (window.attachEvent) {
  6903. window.attachEvent('onunload', baidu.event._unload);
  6904. } else {
  6905. window.addEventListener('unload', baidu.event._unload, false);
  6906. }
  6907. /*
  6908. * Tangram
  6909. * Copyright 2011 Baidu Inc. All rights reserved.
  6910. *
  6911. * path: baidu/fn/abstractMethod.js
  6912. * author: leeight
  6913. * version: 1.0.0
  6914. * date: 2011/04/29
  6915. */
  6916. /**
  6917. * 定义一个抽象方法
  6918. * @type {!Function}
  6919. * @throws {Error} when invoked to indicate the method should be
  6920. * overridden.
  6921. * @see goog.abstractMethod
  6922. */
  6923. baidu.fn.abstractMethod = function() {
  6924. throw Error('unimplemented abstract method');
  6925. };
  6926. /* vim: set ts=4 sw=4 sts=4 tw=100 noet: */
  6927. /*
  6928. * Tangram
  6929. * Copyright 2009 Baidu Inc. All rights reserved.
  6930. *
  6931. * path: baidu/json.js
  6932. * author: erik
  6933. * version: 1.1.0
  6934. * date: 2009/12/02
  6935. */
  6936. /**
  6937. * @namespace baidu.json 操作json对象的方法。
  6938. */
  6939. baidu.json = baidu.json || {};
  6940. /*
  6941. * Tangram
  6942. * Copyright 2009 Baidu Inc. All rights reserved.
  6943. *
  6944. * path: baidu/json/parse.js
  6945. * author: erik, berg
  6946. * version: 1.2
  6947. * date: 2009/11/23
  6948. */
  6949. /**
  6950. * 将字符串解析成json对象。注:不会自动祛除空格
  6951. * @name baidu.json.parse
  6952. * @function
  6953. * @grammar baidu.json.parse(data)
  6954. * @param {string} source 需要解析的字符串
  6955. * @remark
  6956. * 该方法的实现与ecma-262第五版中规定的JSON.parse不同,暂时只支持传入一个参数。后续会进行功能丰富。
  6957. * @meta standard
  6958. * @see baidu.json.stringify,baidu.json.decode
  6959. *
  6960. * @returns {JSON} 解析结果json对象
  6961. */
  6962. baidu.json.parse = function (data) {
  6963. //2010/12/09:更新至不使用原生parse,不检测用户输入是否正确
  6964. return (new Function("return (" + data + ")"))();
  6965. };
  6966. /*
  6967. * Tangram
  6968. * Copyright 2009 Baidu Inc. All rights reserved.
  6969. *
  6970. * path: baidu/json/decode.js
  6971. * author: erik, cat
  6972. * version: 1.3.4
  6973. * date: 2010/12/23
  6974. */
  6975. /**
  6976. * 将字符串解析成json对象,为过时接口,今后会被baidu.json.parse代替
  6977. * @name baidu.json.decode
  6978. * @function
  6979. * @grammar baidu.json.decode(source)
  6980. * @param {string} source 需要解析的字符串
  6981. * @meta out
  6982. * @see baidu.json.encode,baidu.json.parse
  6983. *
  6984. * @returns {JSON} 解析结果json对象
  6985. */
  6986. baidu.json.decode = baidu.json.parse;
  6987. /*
  6988. * Tangram
  6989. * Copyright 2009 Baidu Inc. All rights reserved.
  6990. *
  6991. * path: baidu/json/stringify.js
  6992. * author: erik
  6993. * version: 1.1.0
  6994. * date: 2010/01/11
  6995. */
  6996. /**
  6997. * 将json对象序列化
  6998. * @name baidu.json.stringify
  6999. * @function
  7000. * @grammar baidu.json.stringify(value)
  7001. * @param {JSON} value 需要序列化的json对象
  7002. * @remark
  7003. * 该方法的实现与ecma-262第五版中规定的JSON.stringify不同,暂时只支持传入一个参数。后续会进行功能丰富。
  7004. * @meta standard
  7005. * @see baidu.json.parse,baidu.json.encode
  7006. *
  7007. * @returns {string} 序列化后的字符串
  7008. */
  7009. baidu.json.stringify = (function () {
  7010. /**
  7011. * 字符串处理时需要转义的字符表
  7012. * @private
  7013. */
  7014. var escapeMap = {
  7015. "\b": '\\b',
  7016. "\t": '\\t',
  7017. "\n": '\\n',
  7018. "\f": '\\f',
  7019. "\r": '\\r',
  7020. '"' : '\\"',
  7021. "\\": '\\\\'
  7022. };
  7023. /**
  7024. * 字符串序列化
  7025. * @private
  7026. */
  7027. function encodeString(source) {
  7028. if (/["\\\x00-\x1f]/.test(source)) {
  7029. source = source.replace(
  7030. /["\\\x00-\x1f]/g,
  7031. function (match) {
  7032. var c = escapeMap[match];
  7033. if (c) {
  7034. return c;
  7035. }
  7036. c = match.charCodeAt();
  7037. return "\\u00"
  7038. + Math.floor(c / 16).toString(16)
  7039. + (c % 16).toString(16);
  7040. });
  7041. }
  7042. return '"' + source + '"';
  7043. }
  7044. /**
  7045. * 数组序列化
  7046. * @private
  7047. */
  7048. function encodeArray(source) {
  7049. var result = ["["],
  7050. l = source.length,
  7051. preComma, i, item;
  7052. for (i = 0; i < l; i++) {
  7053. item = source[i];
  7054. switch (typeof item) {
  7055. case "undefined":
  7056. case "function":
  7057. case "unknown":
  7058. break;
  7059. default:
  7060. if(preComma) {
  7061. result.push(',');
  7062. }
  7063. result.push(baidu.json.stringify(item));
  7064. preComma = 1;
  7065. }
  7066. }
  7067. result.push("]");
  7068. return result.join("");
  7069. }
  7070. /**
  7071. * 处理日期序列化时的补零
  7072. * @private
  7073. */
  7074. function pad(source) {
  7075. return source < 10 ? '0' + source : source;
  7076. }
  7077. /**
  7078. * 日期序列化
  7079. * @private
  7080. */
  7081. function encodeDate(source){
  7082. return '"' + source.getFullYear() + "-"
  7083. + pad(source.getMonth() + 1) + "-"
  7084. + pad(source.getDate()) + "T"
  7085. + pad(source.getHours()) + ":"
  7086. + pad(source.getMinutes()) + ":"
  7087. + pad(source.getSeconds()) + '"';
  7088. }
  7089. return function (value) {
  7090. switch (typeof value) {
  7091. case 'undefined':
  7092. return 'undefined';
  7093. case 'number':
  7094. return isFinite(value) ? String(value) : "null";
  7095. case 'string':
  7096. return encodeString(value);
  7097. case 'boolean':
  7098. return String(value);
  7099. default:
  7100. if (value === null) {
  7101. return 'null';
  7102. } else if (value instanceof Array) {
  7103. return encodeArray(value);
  7104. } else if (value instanceof Date) {
  7105. return encodeDate(value);
  7106. } else {
  7107. var result = ['{'],
  7108. encode = baidu.json.stringify,
  7109. preComma,
  7110. item;
  7111. for (var key in value) {
  7112. if (Object.prototype.hasOwnProperty.call(value, key)) {
  7113. item = value[key];
  7114. switch (typeof item) {
  7115. case 'undefined':
  7116. case 'unknown':
  7117. case 'function':
  7118. break;
  7119. default:
  7120. if (preComma) {
  7121. result.push(',');
  7122. }
  7123. preComma = 1;
  7124. result.push(encode(key) + ':' + encode(item));
  7125. }
  7126. }
  7127. }
  7128. result.push('}');
  7129. return result.join('');
  7130. }
  7131. }
  7132. };
  7133. })();
  7134. /*
  7135. * Tangram
  7136. * Copyright 2009 Baidu Inc. All rights reserved.
  7137. *
  7138. * path: baidu/json/encode.js
  7139. * author: erik, cat
  7140. * version: 1.3.4
  7141. * date: 2010/12/23
  7142. */
  7143. /**
  7144. * 将json对象序列化,为过时接口,今后会被baidu.json.stringify代替
  7145. * @name baidu.json.encode
  7146. * @function
  7147. * @grammar baidu.json.encode(value)
  7148. * @param {JSON} value 需要序列化的json对象
  7149. * @meta out
  7150. * @see baidu.json.decode,baidu.json.stringify
  7151. *
  7152. * @returns {string} 序列化后的字符串
  7153. */
  7154. baidu.json.encode = baidu.json.stringify;
  7155. /*
  7156. * Tangram
  7157. * Copyright 2010 Baidu Inc. All rights reserved.
  7158. *
  7159. * path: baidu/lang/Class/addEventListeners.js
  7160. * author: berg
  7161. * version: 1.0
  7162. * date: 2010-07-05
  7163. */
  7164. /**
  7165. * 添加多个自定义事件。
  7166. * @grammar obj.addEventListeners(events, fn)
  7167. * @param {object} events json对象,key为事件名称,value为事件被触发时应该调用的回调函数
  7168. * @param {Function} fn 要挂载的函数
  7169. * @version 1.3
  7170. */
  7171. /* addEventListeners("onmyevent,onmyotherevent", fn);
  7172. * addEventListeners({
  7173. * "onmyevent" : fn,
  7174. * "onmyotherevent" : fn1
  7175. * });
  7176. */
  7177. baidu.lang.Class.prototype.addEventListeners = function (events, fn) {
  7178. if(typeof fn == 'undefined'){
  7179. for(var i in events){
  7180. this.addEventListener(i, events[i]);
  7181. }
  7182. }else{
  7183. events = events.split(',');
  7184. var i = 0, len = events.length, event;
  7185. for(; i < len; i++){
  7186. this.addEventListener(baidu.trim(events[i]), fn);
  7187. }
  7188. }
  7189. };
  7190. /*
  7191. * Tangram
  7192. * Copyright 2010 Baidu Inc. All rights reserved.
  7193. *
  7194. * @author: meizz
  7195. * @namespace: baidu.lang.createClass
  7196. * @version: 2010-05-13
  7197. */
  7198. /**
  7199. * 创建一个类,包括创造类的构造器、继承基类Class
  7200. * @name baidu.lang.createClass
  7201. * @function
  7202. * @grammar baidu.lang.createClass(constructor[, options])
  7203. * @param {Function} constructor 类的构造器函数
  7204. * @param {Object} [options]
  7205. * @config {string} [className] 类名
  7206. * @config {Function} [superClass] 父类,默认为baidu.lang.Class
  7207. * @version 1.2
  7208. * @remark
  7209. *
  7210. 使用createClass能方便的创建一个带有继承关系的类。同时会为返回的类对象添加extend方法,使用obj.extend({});可以方便的扩展原型链上的方法和属性
  7211. * @see baidu.lang.Class,baidu.lang.inherits
  7212. *
  7213. * @returns {Object} 一个类对象
  7214. */
  7215. baidu.lang.createClass = function(constructor, options) {
  7216. options = options || {};
  7217. var superClass = options.superClass || baidu.lang.Class;
  7218. // 创建新类的真构造器函数
  7219. var fn = function(){
  7220. // 继承父类的构造器
  7221. if(superClass != baidu.lang.Class){
  7222. superClass.apply(this, arguments);
  7223. }else{
  7224. superClass.call(this);
  7225. }
  7226. constructor.apply(this, arguments);
  7227. };
  7228. fn.options = options.options || {};
  7229. var C = function(){},
  7230. cp = constructor.prototype;
  7231. C.prototype = superClass.prototype;
  7232. // 继承父类的原型(prototype)链
  7233. var fp = fn.prototype = new C();
  7234. // 继承传参进来的构造器的 prototype 不会丢
  7235. for (var i in cp) fp[i] = cp[i];
  7236. typeof options.className == "string" && (fp._className = options.className);
  7237. // 修正这种继承方式带来的 constructor 混乱的问题
  7238. fp.constructor = cp.constructor;
  7239. // 给类扩展出一个静态方法,以代替 baidu.object.extend()
  7240. fn.extend = function(json){
  7241. for (var i in json) {
  7242. fn.prototype[i] = json[i];
  7243. }
  7244. return fn; // 这个静态方法也返回类对象本身
  7245. };
  7246. return fn;
  7247. };
  7248. /*
  7249. * Tangram
  7250. * Copyright 2010 Baidu Inc. All rights reserved.
  7251. *
  7252. * path: baidu/lang/decontrol.js
  7253. * author: meizz
  7254. * version: 1.1.0
  7255. * $date$
  7256. */
  7257. /**
  7258. * 解除instance中对指定类实例的引用关系。
  7259. * @name baidu.lang.decontrol
  7260. * @function
  7261. * @grammar baidu.lang.decontrol(guid)
  7262. * @param {string} guid 类的唯一标识
  7263. * @version 1.1.1
  7264. * @see baidu.lang.instance
  7265. */
  7266. baidu.lang.decontrol = function(guid) {
  7267. var m = window[baidu.guid];
  7268. m._instances && (delete m._instances[guid]);
  7269. };
  7270. /*
  7271. * Tangram
  7272. * Copyright 2009 Baidu Inc. All rights reserved.
  7273. */
  7274. /**
  7275. * 事件中心
  7276. * @class 事件中心
  7277. * @name baidu.lang.eventCenter
  7278. * @author rocy
  7279. */
  7280. baidu.lang.eventCenter = baidu.lang.eventCenter || baidu.lang.createSingle();
  7281. /**
  7282. * 注册全局事件监听器。
  7283. * @name baidu.lang.eventCenter.addEventListener
  7284. * @function
  7285. * @grammar baidu.lang.eventCenter.addEventListener(type, handler[, key])
  7286. * @param {string} type 自定义事件的名称
  7287. * @param {Function} handler 自定义事件被触发时应该调用的回调函数
  7288. * @param {string} [key] 为事件监听函数指定的名称,可在移除时使用。如果不提供,方法会默认为它生成一个全局唯一的key。
  7289. * @remark 事件类型区分大小写。如果自定义事件名称不是以小写"on"开头,该方法会给它加上"on"再进行判断,即"click"和"onclick"会被认为是同一种事件。
  7290. */
  7291. /**
  7292. * 移除全局事件监听器。
  7293. * @grammar baidu.lang.eventCenter.removeEventListener(type, handler)
  7294. * @param {string} type 事件类型
  7295. * @param {Function|string} handler 要移除的事件监听函数或者监听函数的key
  7296. * @remark 如果第二个参数handler没有被绑定到对应的自定义事件中,什么也不做。
  7297. */
  7298. /**
  7299. * 派发全局自定义事件,使得绑定到全局自定义事件上面的函数都会被执行。
  7300. * @grammar baidu.lang.eventCenter.dispatchEvent(event, options)
  7301. * @param {baidu.lang.Event|String} event Event对象,或事件名称(1.1.1起支持)
  7302. * @param {Object} options 扩展参数,所含属性键值会扩展到Event对象上(1.2起支持)
  7303. */
  7304. /*
  7305. * tangram
  7306. * copyright 2011 baidu inc. all rights reserved.
  7307. *
  7308. * path: baidu/lang/getModule.js
  7309. * author: leeight
  7310. * version: 1.1.0
  7311. * date: 2011/04/29
  7312. */
  7313. /**
  7314. * 根据变量名或者命名空间来查找对象
  7315. * @param {string} name 变量或者命名空间的名字.
  7316. * @param {Object=} opt_obj 从这个对象开始查找,默认是window;
  7317. * @return {?Object} 返回找到的对象,如果没有找到返回null.
  7318. * @see goog.getObjectByName
  7319. */
  7320. baidu.lang.getModule = function(name, opt_obj) {
  7321. var parts = name.split('.'),
  7322. cur = opt_obj || window,
  7323. part;
  7324. for (; part = parts.shift(); ) {
  7325. if (cur[part] != null) {
  7326. cur = cur[part];
  7327. } else {
  7328. return null;
  7329. }
  7330. }
  7331. return cur;
  7332. };
  7333. /* vim: set ts=4 sw=4 sts=4 tw=100 noet: */
  7334. /*
  7335. * Tangram
  7336. * Copyright 2009 Baidu Inc. All rights reserved.
  7337. *
  7338. * path: baidu/lang/inherits.js
  7339. * author: erik
  7340. * version: 1.1.0
  7341. * date: 2009/11/24
  7342. */
  7343. /**
  7344. * 为类型构造器建立继承关系
  7345. * @name baidu.lang.inherits
  7346. * @function
  7347. * @grammar baidu.lang.inherits(subClass, superClass[, className])
  7348. * @param {Function} subClass 子类构造器
  7349. * @param {Function} superClass 父类构造器
  7350. * @param {string} className 类名标识
  7351. * @remark
  7352. *
  7353. 使subClass继承superClass的prototype,因此subClass的实例能够使用superClass的prototype中定义的所有属性和方法。<br>
  7354. 这个函数实际上是建立了subClass和superClass的原型链集成,并对subClass进行了constructor修正。<br>
  7355. <strong>注意:如果要继承构造函数,需要在subClass里面call一下,具体见下面的demo例子</strong>
  7356. * @shortcut inherits
  7357. * @meta standard
  7358. * @see baidu.lang.Class
  7359. */
  7360. baidu.lang.inherits = function (subClass, superClass, className) {
  7361. var key, proto,
  7362. selfProps = subClass.prototype,
  7363. clazz = new Function();
  7364. clazz.prototype = superClass.prototype;
  7365. proto = subClass.prototype = new clazz();
  7366. for (key in selfProps) {
  7367. proto[key] = selfProps[key];
  7368. }
  7369. subClass.prototype.constructor = subClass;
  7370. subClass.superClass = superClass.prototype;
  7371. // 类名标识,兼容Class的toString,基本没用
  7372. if ("string" == typeof className) {
  7373. proto._className = className;
  7374. }
  7375. };
  7376. // 声明快捷方法
  7377. baidu.inherits = baidu.lang.inherits;
  7378. /*
  7379. * Tangram
  7380. * Copyright 2009 Baidu Inc. All rights reserved.
  7381. *
  7382. * path: baidu/lang/instance.js
  7383. * author: meizz, erik
  7384. * version: 1.1.0
  7385. * date: 2009/12/1
  7386. */
  7387. /**
  7388. * 根据参数(guid)的指定,返回对应的实例对象引用
  7389. * @name baidu.lang.instance
  7390. * @function
  7391. * @grammar baidu.lang.instance(guid)
  7392. * @param {string} guid 需要获取实例的guid
  7393. * @meta standard
  7394. *
  7395. * @returns {Object|null} 如果存在的话,返回;否则返回null。
  7396. */
  7397. baidu.lang.instance = function (guid) {
  7398. return window[baidu.guid]._instances[guid] || null;
  7399. };
  7400. /*
  7401. * Tangram
  7402. * Copyright 2009 Baidu Inc. All rights reserved.
  7403. *
  7404. * path: baidu/lang/isBoolean.js
  7405. * author: berg
  7406. * version: 1.0.0
  7407. * date: 2010/10/12
  7408. */
  7409. /**
  7410. * 判断目标参数是否Boolean对象
  7411. * @name baidu.lang.isBoolean
  7412. * @function
  7413. * @grammar baidu.lang.isBoolean(source)
  7414. * @param {Any} source 目标参数
  7415. * @version 1.3
  7416. * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isElement,baidu.lang.isArray,baidu.lang.isDate
  7417. *
  7418. * @returns {boolean} 类型判断结果
  7419. */
  7420. baidu.lang.isBoolean = function(o) {
  7421. return typeof o === 'boolean';
  7422. };
  7423. /*
  7424. * Tangram
  7425. * Copyright 2009 Baidu Inc. All rights reserved.
  7426. *
  7427. * path: baidu/lang/isDate.js
  7428. * author: berg
  7429. * version: 1.0.0
  7430. * date: 2010/10/12
  7431. */
  7432. /**
  7433. * 判断目标参数是否为Date对象
  7434. * @name baidu.lang.isDate
  7435. * @function
  7436. * @grammar baidu.lang.isDate(source)
  7437. * @param {Any} source 目标参数
  7438. * @version 1.3
  7439. * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isBoolean,baidu.lang.isElement
  7440. *
  7441. * @returns {boolean} 类型判断结果
  7442. */
  7443. baidu.lang.isDate = function(o) {
  7444. // return o instanceof Date;
  7445. return {}.toString.call(o) === "[object Date]" && o.toString() !== 'Invalid Date' && !isNaN(o);
  7446. };
  7447. /*
  7448. * Tangram
  7449. * Copyright 2009 Baidu Inc. All rights reserved.
  7450. *
  7451. * path: baidu/lang/isElement.js
  7452. * author: erik
  7453. * version: 1.1.0
  7454. * date: 2009/12/30
  7455. */
  7456. /**
  7457. * 判断目标参数是否为Element对象
  7458. * @name baidu.lang.isElement
  7459. * @function
  7460. * @grammar baidu.lang.isElement(source)
  7461. * @param {Any} source 目标参数
  7462. * @meta standard
  7463. * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isBoolean,baidu.lang.isDate
  7464. *
  7465. * @returns {boolean} 类型判断结果
  7466. */
  7467. baidu.lang.isElement = function (source) {
  7468. return !!(source && source.nodeName && source.nodeType == 1);
  7469. };
  7470. /*
  7471. * Tangram
  7472. * Copyright 2009 Baidu Inc. All rights reserved.
  7473. *
  7474. * path: baidu/lang/isObject.js
  7475. * author: erik
  7476. * version: 1.1.0
  7477. * date: 2009/12/30
  7478. */
  7479. /**
  7480. * 判断目标参数是否为Object对象
  7481. * @name baidu.lang.isObject
  7482. * @function
  7483. * @grammar baidu.lang.isObject(source)
  7484. * @param {Any} source 目标参数
  7485. * @shortcut isObject
  7486. * @meta standard
  7487. * @see baidu.lang.isString,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate
  7488. *
  7489. * @returns {boolean} 类型判断结果
  7490. */
  7491. baidu.lang.isObject = function (source) {
  7492. return 'function' == typeof source || !!(source && 'object' == typeof source);
  7493. };
  7494. // 声明快捷方法
  7495. baidu.isObject = baidu.lang.isObject;
  7496. /*
  7497. * Tangram
  7498. * Copyright 2009 Baidu Inc. All rights reserved.
  7499. */
  7500. /**
  7501. * 增加自定义模块扩展,默认创建在当前作用域
  7502. * @author erik, berg
  7503. * @name baidu.lang.module
  7504. * @function
  7505. * @grammar baidu.lang.module(name, module[, owner])
  7506. * @param {string} name 需要创建的模块名.
  7507. * @param {Any} module 需要创建的模块对象.
  7508. * @param {Object} [owner] 模块创建的目标环境,默认为window.
  7509. * @remark
  7510. *
  7511. 从1.1.1开始,module方法会优先在当前作用域下寻找模块,如果无法找到,则寻找window下的模块
  7512. * @meta standard
  7513. */
  7514. baidu.lang.module = function(name, module, owner) {
  7515. var packages = name.split('.'),
  7516. len = packages.length - 1,
  7517. packageName,
  7518. i = 0;
  7519. // 如果没有owner,找当前作用域,如果当前作用域没有此变量,在window创建
  7520. if (!owner) {
  7521. try {
  7522. if (!(new RegExp('^[a-zA-Z_\x24][a-zA-Z0-9_\x24]*\x24')).test(packages[0])) {
  7523. throw '';
  7524. }
  7525. owner = eval(packages[0]);
  7526. i = 1;
  7527. }catch (e) {
  7528. owner = window;
  7529. }
  7530. }
  7531. for (; i < len; i++) {
  7532. packageName = packages[i];
  7533. if (!owner[packageName]) {
  7534. owner[packageName] = {};
  7535. }
  7536. owner = owner[packageName];
  7537. }
  7538. if (!owner[packages[len]]) {
  7539. owner[packages[len]] = module;
  7540. }
  7541. };
  7542. /*
  7543. * Tangram
  7544. * Copyright 2009 Baidu Inc. All rights reserved.
  7545. *
  7546. * path: baidu/number/comma.js
  7547. * author: dron, erik, berg
  7548. * version: 1.2.0
  7549. * date: 2010/09/07
  7550. */
  7551. /**
  7552. * 为目标数字添加逗号分隔
  7553. * @name baidu.number.comma
  7554. * @function
  7555. * @grammar baidu.number.comma(source[, length])
  7556. * @param {number} source 需要处理的数字
  7557. * @param {number} [length] 两次逗号之间的数字位数,默认为3位
  7558. *
  7559. * @returns {string} 添加逗号分隔后的字符串
  7560. */
  7561. baidu.number.comma = function (source, length) {
  7562. if (!length || length < 1) {
  7563. length = 3;
  7564. }
  7565. source = String(source).split(".");
  7566. source[0] = source[0].replace(new RegExp('(\\d)(?=(\\d{'+length+'})+$)','ig'),"$1,");
  7567. return source.join(".");
  7568. };
  7569. /*
  7570. * Tangram
  7571. * Copyright 2009 Baidu Inc. All rights reserved.
  7572. *
  7573. * path: baidu/number/randomInt.js
  7574. * author: berg
  7575. * version: 1.0.0
  7576. * date: 2010/12/14
  7577. */
  7578. /**
  7579. * 生成随机整数,范围是[min, max]
  7580. * @name baidu.number.randomInt
  7581. * @function
  7582. * @grammar baidu.number.randomInt(min, max)
  7583. *
  7584. * @param {number} min 随机整数的最小值
  7585. * @param {number} max 随机整数的最大值
  7586. * @return {number} 生成的随机整数
  7587. */
  7588. baidu.number.randomInt = function(min, max){
  7589. return Math.floor(Math.random() * (max - min + 1) + min);
  7590. };
  7591. /*
  7592. * Tangram
  7593. * Copyright 2009 Baidu Inc. All rights reserved.
  7594. */
  7595. /**
  7596. * 判断一个对象是不是字面量对象,即判断这个对象是不是由{}或者new Object类似方式创建
  7597. *
  7598. * @name baidu.object.isPlain
  7599. * @function
  7600. * @grammar baidu.object.isPlain(source)
  7601. * @param {Object} source 需要检查的对象
  7602. * @remark
  7603. * 事实上来说,在Javascript语言中,任何判断都一定会有漏洞,因此本方法只针对一些最常用的情况进行了判断
  7604. *
  7605. * @returns {Boolean} 检查结果
  7606. */
  7607. baidu.object.isPlain = function(obj){
  7608. var hasOwnProperty = Object.prototype.hasOwnProperty,
  7609. key;
  7610. if ( !obj ||
  7611. //一般的情况,直接用toString判断
  7612. Object.prototype.toString.call(obj) !== "[object Object]" ||
  7613. //IE下,window/document/document.body/HTMLElement/HTMLCollection/NodeList等DOM对象上一个语句为true
  7614. //isPrototypeOf挂在Object.prototype上的,因此所有的字面量都应该会有这个属性
  7615. //对于在window上挂了isPrototypeOf属性的情况,直接忽略不考虑
  7616. !('isPrototypeOf' in obj)
  7617. ) {
  7618. return false;
  7619. }
  7620. //判断new fun()自定义对象的情况
  7621. //constructor不是继承自原型链的
  7622. //并且原型中有isPrototypeOf方法才是Object
  7623. if ( obj.constructor &&
  7624. !hasOwnProperty.call(obj, "constructor") &&
  7625. !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
  7626. return false;
  7627. }
  7628. //判断有继承的情况
  7629. //如果有一项是继承过来的,那么一定不是字面量Object
  7630. //OwnProperty会首先被遍历,为了加速遍历过程,直接看最后一项
  7631. for ( key in obj ) {}
  7632. return key === undefined || hasOwnProperty.call( obj, key );
  7633. };
  7634. /*
  7635. * Tangram
  7636. * Copyright 2009 Baidu Inc. All rights reserved.
  7637. */
  7638. /**
  7639. * 对一个object进行深度拷贝
  7640. *
  7641. * @author berg
  7642. * @name baidu.object.clone
  7643. * @function
  7644. * @grammar baidu.object.clone(source)
  7645. * @param {Object} source 需要进行拷贝的对象
  7646. * @remark
  7647. * 对于Object来说,只拷贝自身成员,不拷贝prototype成员
  7648. * @meta standard
  7649. *
  7650. * @returns {Object} 拷贝后的新对象
  7651. */
  7652. baidu.object.clone = function (source) {
  7653. var result = source, i, len;
  7654. if (!source
  7655. || source instanceof Number
  7656. || source instanceof String
  7657. || source instanceof Boolean) {
  7658. return result;
  7659. } else if (baidu.lang.isArray(source)) {
  7660. result = [];
  7661. var resultLen = 0;
  7662. for (i = 0, len = source.length; i < len; i++) {
  7663. result[resultLen++] = baidu.object.clone(source[i]);
  7664. }
  7665. } else if (baidu.object.isPlain(source)) {
  7666. result = {};
  7667. for (i in source) {
  7668. if (source.hasOwnProperty(i)) {
  7669. result[i] = baidu.object.clone(source[i]);
  7670. }
  7671. }
  7672. }
  7673. return result;
  7674. };
  7675. /*
  7676. * tangram
  7677. * copyright 2011 baidu inc. all rights reserved.
  7678. *
  7679. * path: baidu/object/isEmpty.js
  7680. * author: leeight
  7681. * version: 1.1.0
  7682. * date: 2011/04/30
  7683. */
  7684. /**
  7685. * 检测一个对象是否是空的.
  7686. * 需要注意的是:
  7687. * 如果污染了Object.prototype或者Array.prototype,那么
  7688. * baidu.object.isEmpty({})或者
  7689. * baidu.object.isEmpty([])可能返回的就是false.
  7690. * @param {Object} obj 需要检测的对象.
  7691. * @return {boolean} 如果是空的对象就返回true.
  7692. */
  7693. baidu.object.isEmpty = function(obj) {
  7694. for (var key in obj) {
  7695. return false;
  7696. }
  7697. return true;
  7698. };
  7699. /* vim: set ts=4 sw=4 sts=4 tw=100 noet: */
  7700. /*
  7701. * Tangram
  7702. * Copyright 2009 Baidu Inc. All rights reserved.
  7703. *
  7704. * path: baidu/object/keys.js
  7705. * author: erik
  7706. * version: 1.1.0
  7707. * date: 2009/11/15
  7708. */
  7709. /**
  7710. * 获取目标对象的键名列表
  7711. * @name baidu.object.keys
  7712. * @function
  7713. * @grammar baidu.object.keys(source)
  7714. * @param {Object} source 目标对象
  7715. * @see baidu.object.values
  7716. *
  7717. * @returns {Array} 键名列表
  7718. */
  7719. baidu.object.keys = function (source) {
  7720. var result = [], resultLen = 0, k;
  7721. for (k in source) {
  7722. if (source.hasOwnProperty(k)) {
  7723. result[resultLen++] = k;
  7724. }
  7725. }
  7726. return result;
  7727. };
  7728. /*
  7729. * Tangram
  7730. * Copyright 2009 Baidu Inc. All rights reserved.
  7731. *
  7732. * path: baidu/object/map.js
  7733. * author: berg
  7734. * version: 1.1.0
  7735. * date: 2010/12/14
  7736. */
  7737. /**
  7738. * 遍历object中所有元素,将每一个元素应用方法进行转换,返回转换后的新object。
  7739. * @name baidu.object.map
  7740. * @function
  7741. * @grammar baidu.object.map(source, iterator)
  7742. *
  7743. * @param {Array} source 需要遍历的object
  7744. * @param {Function} iterator 对每个object元素进行处理的函数
  7745. * @return {Array} map后的object
  7746. */
  7747. baidu.object.map = function (source, iterator) {
  7748. var results = {};
  7749. for (var key in source) {
  7750. if (source.hasOwnProperty(key)) {
  7751. results[key] = iterator(source[key], key);
  7752. }
  7753. }
  7754. return results;
  7755. };
  7756. /*
  7757. * Tangram
  7758. * Copyright 2009 Baidu Inc. All rights reserved.
  7759. */
  7760. /*
  7761. * 默认情况下,所有在源对象上的属性都会被非递归地合并到目标对象上
  7762. * 并且如果目标对象上已有此属性,不会被覆盖
  7763. */
  7764. /**
  7765. * 合并源对象的属性到目标对象。
  7766. *
  7767. * @name baidu.object.merge
  7768. * @function
  7769. * @grammar baidu.object.merge(target, source[, opt_options])
  7770. *
  7771. * @param {Function} target 目标对象.
  7772. * @param {Function} source 源对象.
  7773. * @param {Object} opt_options optional merge选项.
  7774. * @config {boolean} overwrite optional 如果为真,源对象属性会覆盖掉目标对象上的已有属性,默认为假.
  7775. * @config {string[]} whiteList optional 白名单,默认为空,如果存在,只有在这里的属性才会被处理.
  7776. * @config {boolean} recursive optional 是否递归合并对象里面的object,默认为否.
  7777. * @return {object} merge后的object.
  7778. * @see baidu.object.extend
  7779. * @author berg
  7780. */
  7781. (function() {
  7782. var isPlainObject = function(source) {
  7783. return baidu.lang.isObject(source) && !baidu.lang.isFunction(source);
  7784. };
  7785. function mergeItem(target, source, index, overwrite, recursive) {
  7786. if (source.hasOwnProperty(index)) {
  7787. if (recursive && isPlainObject(target[index])) {
  7788. // 如果需要递归覆盖,就递归调用merge
  7789. baidu.object.merge(
  7790. target[index],
  7791. source[index],
  7792. {
  7793. 'overwrite': overwrite,
  7794. 'recursive': recursive
  7795. }
  7796. );
  7797. } else if (overwrite || !(index in target)) {
  7798. // 否则只处理overwrite为true,或者在目标对象中没有此属性的情况
  7799. target[index] = source[index];
  7800. }
  7801. }
  7802. }
  7803. baidu.object.merge = function(target, source, opt_options) {
  7804. var i = 0,
  7805. options = opt_options || {},
  7806. overwrite = options['overwrite'],
  7807. whiteList = options['whiteList'],
  7808. recursive = options['recursive'],
  7809. len;
  7810. // 只处理在白名单中的属性
  7811. if (whiteList && whiteList.length) {
  7812. len = whiteList.length;
  7813. for (; i < len; ++i) {
  7814. mergeItem(target, source, whiteList[i], overwrite, recursive);
  7815. }
  7816. } else {
  7817. for (i in source) {
  7818. mergeItem(target, source, i, overwrite, recursive);
  7819. }
  7820. }
  7821. return target;
  7822. };
  7823. })();
  7824. /*
  7825. * Tangram
  7826. * Copyright 2010 Baidu Inc. All rights reserved.
  7827. *
  7828. * @author: meizz
  7829. * @namespace: baidu.page.createStyleSheet
  7830. * @version: 2010-06-12
  7831. */
  7832. /**
  7833. * 在页面中创建样式表对象
  7834. * @name baidu.page.createStyleSheet
  7835. * @function
  7836. * @grammar baidu.page.createStyleSheet(options)
  7837. * @param {Object} options 配置信息
  7838. * @param {Document} options.document 指定在哪个document下创建,默认是当前文档
  7839. * @param {String} options.url css文件的URL
  7840. * @param {Number} options.index 在文档里的排序索引(注意,仅IE下有效)
  7841. * @version 1.2
  7842. * @remark
  7843. * ie 下返回值styleSheet的addRule方法不支持添加逗号分隔的css rule.
  7844. *
  7845. * @see baidu.page.createStyleSheet.StyleSheet
  7846. *
  7847. * @returns {baidu.page.createStyleSheet.StyleSheet} styleSheet对象(注意: 仅IE下,其他浏览器均返回null)
  7848. */
  7849. baidu.page.createStyleSheet = function(options){
  7850. var op = options || {},
  7851. doc = op.document || document,
  7852. s;
  7853. if (baidu.browser.ie) {
  7854. //修复ie下会请求一个undefined的bug berg 2010/08/27
  7855. if(!op.url)
  7856. op.url = "";
  7857. return doc.createStyleSheet(op.url, op.index);
  7858. } else {
  7859. s = "<style type='text/css'></style>";
  7860. op.url && (s="<link type='text/css' rel='stylesheet' href='"+op.url+"'/>");
  7861. baidu.dom.insertHTML(doc.getElementsByTagName("HEAD")[0],"beforeEnd",s);
  7862. //如果用户传入了url参数,下面访问sheet.rules的时候会报错
  7863. if(op.url){
  7864. return null;
  7865. }
  7866. var sheet = doc.styleSheets[doc.styleSheets.length - 1],
  7867. rules = sheet.rules || sheet.cssRules;
  7868. return {
  7869. self : sheet
  7870. ,rules : sheet.rules || sheet.cssRules
  7871. ,addRule : function(selector, style, i) {
  7872. if (sheet.addRule) {
  7873. return sheet.addRule(selector, style, i);
  7874. } else if (sheet.insertRule) {
  7875. isNaN(i) && (i = rules.length);
  7876. return sheet.insertRule(selector +"{"+ style +"}", i);
  7877. }
  7878. }
  7879. ,removeRule : function(i) {
  7880. if (sheet.removeRule) {
  7881. sheet.removeRule(i);
  7882. } else if (sheet.deleteRule) {
  7883. isNaN(i) && (i = 0);
  7884. sheet.deleteRule(i);
  7885. }
  7886. }
  7887. }
  7888. }
  7889. };
  7890. /*
  7891. * styleSheet对象 有两个方法
  7892. * addRule(selector, style, i)
  7893. * removeRule(i)
  7894. * 这两个方法已经做了浏览器兼容处理
  7895. * 一个集合
  7896. * rules
  7897. */
  7898. /*
  7899. * Tangram
  7900. * Copyright 2009 Baidu Inc. All rights reserved.
  7901. *
  7902. * path: baidu/page/getHeight.js
  7903. * author: allstar, erik
  7904. * version: 1.1.0
  7905. * date: 2009/12/03
  7906. */
  7907. /**
  7908. * 获取页面高度
  7909. * @name baidu.page.getHeight
  7910. * @function
  7911. * @grammar baidu.page.getHeight()
  7912. * @see baidu.page.getWidth
  7913. *
  7914. * @returns {number} 页面高度
  7915. */
  7916. baidu.page.getHeight = function () {
  7917. var doc = document,
  7918. body = doc.body,
  7919. html = doc.documentElement,
  7920. client = doc.compatMode == 'BackCompat' ? body : doc.documentElement;
  7921. return Math.max(html.scrollHeight, body.scrollHeight, client.clientHeight);
  7922. };
  7923. /*
  7924. * Tangram
  7925. * Copyright 2009 Baidu Inc. All rights reserved.
  7926. *
  7927. * path: baidu/page/getWidth.js
  7928. * author: allstar, erik
  7929. * version: 1.1.0
  7930. * date: 2009/12/03
  7931. */
  7932. /**
  7933. * 获取页面宽度
  7934. * @name baidu.page.getWidth
  7935. * @function
  7936. * @grammar baidu.page.getWidth()
  7937. * @see baidu.page.getHeight
  7938. * @meta standard
  7939. * @returns {number} 页面宽度
  7940. */
  7941. baidu.page.getWidth = function () {
  7942. var doc = document,
  7943. body = doc.body,
  7944. html = doc.documentElement,
  7945. client = doc.compatMode == 'BackCompat' ? body : doc.documentElement;
  7946. return Math.max(html.scrollWidth, body.scrollWidth, client.clientWidth);
  7947. };
  7948. /*
  7949. * Tangram
  7950. * Copyright 2010 Baidu Inc. All rights reserved.
  7951. */
  7952. /**
  7953. * 延迟加载图片. 默认只加载可见高度以上的图片, 随着窗口滚动加载剩余图片.注意: 仅支持垂直方向.
  7954. * @name baidu.page.lazyLoadImage
  7955. * @function
  7956. * @grammar baidu.page.lazyLoadImage([options])
  7957. * @param {Object} options
  7958. * @param {String} [options.className] 延迟加载的IMG的className,如果不传入该值将延迟加载所有IMG.
  7959. * @param {Number} [options.preloadHeight] 预加载的高度, 可见窗口下该高度内的图片将被加载.
  7960. * @param {String} [options.placeHolder] 占位图url.
  7961. * @param {Function} [options.onlazyload] 延迟加载回调函数,在实际加载时触发.
  7962. * @author rocy
  7963. */
  7964. baidu.page.lazyLoadImage = function(options) {
  7965. options = options || {};
  7966. options.preloadHeight = options.preloadHeight || 0;
  7967. baidu.dom.ready(function() {
  7968. var imgs = document.getElementsByTagName('IMG'),
  7969. targets = imgs,
  7970. len = imgs.length,
  7971. i = 0,
  7972. viewOffset = getLoadOffset(),
  7973. srcAttr = 'data-tangram-ori-src',
  7974. target;
  7975. //避免循环中每次都判断className
  7976. if (options.className) {
  7977. targets = [];
  7978. for (; i < len; ++i) {
  7979. if (baidu.dom.hasClass(imgs[i], options.className)) {
  7980. targets.push(imgs[i]);
  7981. }
  7982. }
  7983. }
  7984. //计算需要加载图片的页面高度
  7985. function getLoadOffset() {
  7986. return baidu.page.getScrollTop() + baidu.page.getViewHeight() + options.preloadHeight;
  7987. }
  7988. //加载可视图片
  7989. for (i = 0, len = targets.length; i < len; ++i) {
  7990. target = targets[i];
  7991. if (baidu.dom.getPosition(target).top > viewOffset) {
  7992. target.setAttribute(srcAttr, target.src);
  7993. options.placeHolder ? target.src = options.placeHolder : target.removeAttribute('src');
  7994. }
  7995. }
  7996. //处理延迟加载
  7997. var loadNeeded = function() {
  7998. var viewOffset = getLoadOffset(),
  7999. imgSrc,
  8000. finished = true,
  8001. i = 0,
  8002. len = targets.length;
  8003. for (; i < len; ++i) {
  8004. target = targets[i];
  8005. imgSrc = target.getAttribute(srcAttr);
  8006. imgSrc && (finished = false);
  8007. if (baidu.dom.getPosition(target).top < viewOffset && imgSrc) {
  8008. target.src = imgSrc;
  8009. target.removeAttribute(srcAttr);
  8010. baidu.lang.isFunction(options.onlazyload) && options.onlazyload(target);
  8011. }
  8012. }
  8013. //当全部图片都已经加载, 去掉事件监听
  8014. finished && baidu.un(window, 'scroll', loadNeeded);
  8015. };
  8016. baidu.on(window, 'scroll', loadNeeded);
  8017. });
  8018. };
  8019. /*
  8020. * Tangram
  8021. * Copyright 2009 Baidu Inc. All rights reserved.
  8022. *
  8023. * path: baidu/page/load.js
  8024. * author: rocy
  8025. * version: 1.0.0
  8026. * date: 2010/11/29
  8027. */
  8028. /**
  8029. *
  8030. * 加载一组资源,支持多种格式资源的串/并行加载,支持每个文件有单独回调函数。
  8031. *
  8032. * @name baidu.page.load
  8033. * @function
  8034. * @grammar baidu.page.load(resources[, options])
  8035. *
  8036. * @param {Array} resources 资源描述数组,单个resource含如下属性.
  8037. * @param {String} resources.url 链接地址.
  8038. * @param {String} [resources.type] 取值["css","js","html"],默认参考文件后缀.
  8039. * @param {String} [resources.requestType] 取值["dom","ajax"],默认js和css用dom标签,html用ajax.
  8040. * @param {Function} resources.onload 当前resource加载完成的回调函数,若requestType为ajax,参数为xhr(可能失效),responseText;若requestType为dom,无参数,执行时this为相应dom标签。.
  8041. *
  8042. * @param {Object} [options] 可选参数.
  8043. * @param {Function} [options.onload] 资源全部加载完成的回调函数,无参数。.
  8044. * @param {Boolean} [options.parallel] 是否并行加载,默认为false,串行。.
  8045. * @param {Boolean} [ignoreAllLoaded] 全部加载之后不触发回调事件.主要用于内部实现.
  8046. *
  8047. *
  8048. * @remark
  8049. * //串行实例
  8050. * baidu.page.load([
  8051. * { url : "http://img.baidu.com/js/tangram-1.3.2.js" },
  8052. * {url : "http://xxx.baidu.com/xpath/logicRequire.js",
  8053. * onload : fnOnRequireLoaded
  8054. * },
  8055. * { url : "http://xxx.baidu.com/xpath/target.js" }
  8056. * ],{
  8057. * onload : fnWhenTargetOK
  8058. * });
  8059. * //并行实例
  8060. * baidu.page.load([
  8061. * {
  8062. * url : "http://xxx.baidu.com/xpath/template.html",
  8063. * onload : fnExtractTemplate
  8064. * },
  8065. * { url : "http://xxx.baidu.com/xpath/style.css"},
  8066. * {
  8067. * url : "http://xxx.baidu.com/xpath/import.php?f=baidu.*",
  8068. * type : "js"
  8069. * },
  8070. * {
  8071. * url : "http://xxx.baidu.com/xpath/target.js",
  8072. * },
  8073. * {
  8074. * url : "http://xxx.baidu.com/xpath/jsonData.js",
  8075. * requestType : "ajax",
  8076. * onload : fnExtractData
  8077. * }
  8078. * ],{
  8079. * parallel : true,
  8080. * onload : fnWhenEverythingIsOK
  8081. * });
  8082. */
  8083. baidu.page.load = function(resources, options, ignoreAllLoaded) {
  8084. //TODO failure, 整体onload能不能每个都调用; resources.charset
  8085. options = options || {};
  8086. var self = baidu.page.load,
  8087. cache = self._cache = self._cache || {},
  8088. loadingCache = self._loadingCache = self._loadingCache || {},
  8089. parallel = options.parallel;
  8090. function allLoadedChecker() {
  8091. for (var i = 0, len = resources.length; i < len; ++i) {
  8092. if (! cache[resources[i].url]) {
  8093. setTimeout(arguments.callee, 10);
  8094. return;
  8095. }
  8096. }
  8097. options.onload();
  8098. };
  8099. function loadByDom(res, callback) {
  8100. var node, loaded, onready;
  8101. switch (res.type.toLowerCase()) {
  8102. case 'css' :
  8103. node = document.createElement('link');
  8104. node.setAttribute('rel', 'stylesheet');
  8105. node.setAttribute('type', 'text/css');
  8106. break;
  8107. case 'js' :
  8108. node = document.createElement('script');
  8109. node.setAttribute('type', 'text/javascript');
  8110. node.setAttribute('charset', res.charset || self.charset);
  8111. break;
  8112. case 'html' :
  8113. node = document.createElement('iframe');
  8114. node.frameBorder = 'none';
  8115. break;
  8116. default :
  8117. return;
  8118. }
  8119. // HTML,JS works on all browsers, CSS works only on IE.
  8120. onready = function() {
  8121. if (!loaded && (!this.readyState ||
  8122. this.readyState === 'loaded' ||
  8123. this.readyState === 'complete')) {
  8124. loaded = true;
  8125. // 防止内存泄露
  8126. baidu.un(node, 'load', onready);
  8127. baidu.un(node, 'readystatechange', onready);
  8128. //node.onload = node.onreadystatechange = null;
  8129. callback.call(window, node);
  8130. }
  8131. };
  8132. baidu.on(node, 'load', onready);
  8133. baidu.on(node, 'readystatechange', onready);
  8134. //CSS has no onload event on firefox and webkit platform, so hack it.
  8135. if (res.type == 'css') {
  8136. (function() {
  8137. //避免重复加载
  8138. if (loaded) return;
  8139. try {
  8140. node.sheet.cssRule;
  8141. } catch (e) {
  8142. setTimeout(arguments.callee, 20);
  8143. return;
  8144. }
  8145. loaded = true;
  8146. callback.call(window, node);
  8147. })();
  8148. }
  8149. node.href = node.src = res.url;
  8150. document.getElementsByTagName('head')[0].appendChild(node);
  8151. }
  8152. //兼容第一个参数直接是资源地址.
  8153. baidu.lang.isString(resources) && (resources = [{url: resources}]);
  8154. //避免递归出错,添加容错.
  8155. if (! (resources && resources.length)) return;
  8156. function loadResources(res) {
  8157. var url = res.url,
  8158. shouldContinue = !!parallel,
  8159. cacheData,
  8160. callback = function(textOrNode) {
  8161. //ajax存入responseText,dom存入节点,用于保证onload的正确执行.
  8162. cache[res.url] = textOrNode;
  8163. delete loadingCache[res.url];
  8164. if (baidu.lang.isFunction(res.onload)) {
  8165. //若返回false, 则停止接下来的加载.
  8166. if (false === res.onload.call(window, textOrNode)) {
  8167. return;
  8168. }
  8169. }
  8170. //串行时递归执行
  8171. !parallel && self(resources.slice(1), options, true);
  8172. if ((! ignoreAllLoaded) && baidu.lang.isFunction(options.onload)) {
  8173. allLoadedChecker();
  8174. }
  8175. };
  8176. //默认用后缀名, 并防止后缀名大写
  8177. res.type = res.type || url.substr(url.lastIndexOf('.') + 1);
  8178. //默认html格式用ajax请求,其他都使用dom标签方式请求.
  8179. res.requestType = res.requestType || (res.type == 'html' ? 'ajax' : 'dom');
  8180. if (cacheData = cache[res.url]) {
  8181. callback(cacheData);
  8182. return shouldContinue;
  8183. }
  8184. if (!options.refresh && loadingCache[res.url]) {
  8185. setTimeout(function() {loadResources(res);}, 10);
  8186. return shouldContinue;
  8187. }
  8188. loadingCache[res.url] = true;
  8189. if (res.requestType.toLowerCase() == 'dom') {
  8190. loadByDom(res, callback);
  8191. }else {//ajax
  8192. baidu.ajax.get(res.url, function(xhr, responseText) {callback(responseText);});
  8193. }
  8194. //串行模式,通过callback方法执行后续
  8195. return shouldContinue;
  8196. };
  8197. baidu.each(resources, loadResources);
  8198. };
  8199. //默认编码设置为UTF8
  8200. baidu.page.load.charset = 'UTF8';
  8201. /*
  8202. * Tangram
  8203. * Copyright 2009 Baidu Inc. All rights reserved.
  8204. *
  8205. * path: baidu/page/loadCssFile.js
  8206. * author: allstar
  8207. * version: 1.1.0
  8208. * date: 2009/11/20
  8209. */
  8210. /**
  8211. * 动态在页面上加载一个外部css文件
  8212. * @name baidu.page.loadCssFile
  8213. * @function
  8214. * @grammar baidu.page.loadCssFile(path)
  8215. * @param {string} path css文件路径
  8216. * @see baidu.page.loadJsFile
  8217. */
  8218. baidu.page.loadCssFile = function (path) {
  8219. var element = document.createElement("link");
  8220. element.setAttribute("rel", "stylesheet");
  8221. element.setAttribute("type", "text/css");
  8222. element.setAttribute("href", path);
  8223. document.getElementsByTagName("head")[0].appendChild(element);
  8224. };
  8225. /*
  8226. * Tangram
  8227. * Copyright 2009 Baidu Inc. All rights reserved.
  8228. *
  8229. * path: baidu/page/loadJsFile.js
  8230. * author: allstar
  8231. * version: 1.1.0
  8232. * date: 2009/11/20
  8233. */
  8234. /**
  8235. * 动态在页面上加载一个外部js文件
  8236. * @name baidu.page.loadJsFile
  8237. * @function
  8238. * @grammar baidu.page.loadJsFile(path)
  8239. * @param {string} path js文件路径
  8240. * @see baidu.page.loadCssFile
  8241. */
  8242. baidu.page.loadJsFile = function (path) {
  8243. var element = document.createElement('script');
  8244. element.setAttribute('type', 'text/javascript');
  8245. element.setAttribute('src', path);
  8246. element.setAttribute('defer', 'defer');
  8247. document.getElementsByTagName("head")[0].appendChild(element);
  8248. };
  8249. /*
  8250. * Tangram
  8251. * Copyright 2009 Baidu Inc. All rights reserved.
  8252. */
  8253. /**
  8254. * @namespace baidu.platform 判断平台类型和特性的属性。
  8255. * @author jz
  8256. */
  8257. baidu.platform = baidu.platform || {};
  8258. /*
  8259. * Tangram
  8260. * Copyright 2009 Baidu Inc. All rights reserved.
  8261. */
  8262. /**
  8263. * 判断是否为android平台
  8264. * @property android 是否为android平台
  8265. * @grammar baidu.platform.android
  8266. * @meta standard
  8267. * @see baidu.platform.x11,baidu.platform.windows,baidu.platform.macintosh,baidu.platform.iphone,baidu.platform.ipad
  8268. * @author jz
  8269. */
  8270. baidu.platform.isAndroid = /android/i.test(navigator.userAgent);
  8271. /*
  8272. * Tangram
  8273. * Copyright 2009 Baidu Inc. All rights reserved.
  8274. */
  8275. /**
  8276. * 判断是否为ipad平台
  8277. * @property ipad 是否为ipad平台
  8278. * @grammar baidu.platform.ipad
  8279. * @meta standard
  8280. * @see baidu.platform.x11,baidu.platform.windows,baidu.platform.macintosh,baidu.platform.iphone,baidu.platform.android
  8281. * @author jz
  8282. */
  8283. baidu.platform.isIpad = /ipad/i.test(navigator.userAgent);
  8284. /*
  8285. * Tangram
  8286. * Copyright 2009 Baidu Inc. All rights reserved.
  8287. */
  8288. /**
  8289. * 判断是否为iphone平台
  8290. * @property iphone 是否为iphone平台
  8291. * @grammar baidu.platform.iphone
  8292. * @meta standard
  8293. * @see baidu.platform.x11,baidu.platform.windows,baidu.platform.macintosh,baidu.platform.ipad,baidu.platform.android
  8294. * @author jz
  8295. */
  8296. baidu.platform.isIphone = /iphone/i.test(navigator.userAgent);
  8297. /*
  8298. * Tangram
  8299. * Copyright 2009 Baidu Inc. All rights reserved.
  8300. */
  8301. /**
  8302. * 判断是否为macintosh平台
  8303. * @property macintosh 是否为macintosh平台
  8304. * @grammar baidu.platform.macintosh
  8305. * @meta standard
  8306. * @see baidu.platform.x11,baidu.platform.windows,baidu.platform.iphone,baidu.platform.ipad,baidu.platform.android
  8307. * @author jz
  8308. */
  8309. baidu.platform.isMacintosh = /macintosh/i.test(navigator.userAgent);
  8310. /*
  8311. * Tangram
  8312. * Copyright 2009 Baidu Inc. All rights reserved.
  8313. */
  8314. /**
  8315. * 判断是否为windows平台
  8316. * @property windows 是否为windows平台
  8317. * @grammar baidu.platform.windows
  8318. * @meta standard
  8319. * @see baidu.platform.x11,baidu.platform.macintosh,baidu.platform.iphone,baidu.platform.ipad,baidu.platform.android
  8320. * @author jz
  8321. */
  8322. baidu.platform.isWindows = /windows/i.test(navigator.userAgent);
  8323. /*
  8324. * Tangram
  8325. * Copyright 2009 Baidu Inc. All rights reserved.
  8326. */
  8327. /**
  8328. * 判断是否为x11平台
  8329. * @property x11 是否为x11平台
  8330. * @grammar baidu.platform.x11
  8331. * @meta standard
  8332. * @see baidu.platform.windows,baidu.platform.macintosh,baidu.platform.iphone,baidu.platform.ipad,baidu.platform.android
  8333. * @author jz
  8334. */
  8335. baidu.platform.isX11 = /x11/i.test(navigator.userAgent);
  8336. /*
  8337. * Tangram
  8338. * Copyright 2009 Baidu Inc. All rights reserved.
  8339. *
  8340. * path: baidu/sio.js
  8341. * author: erik
  8342. * version: 1.1.0
  8343. * date: 2009/12/16
  8344. */
  8345. /**
  8346. * @namespace baidu.sio 使用动态script标签请求服务器资源,包括由服务器端的回调和浏览器端的回调。
  8347. */
  8348. baidu.sio = baidu.sio || {};
  8349. /*
  8350. * Tangram
  8351. * Copyright 2009 Baidu Inc. All rights reserved.
  8352. */
  8353. /**
  8354. *
  8355. * @param {HTMLElement} src script节点
  8356. * @param {String} url script节点的地址
  8357. * @param {String} [charset] 编码
  8358. */
  8359. baidu.sio._createScriptTag = function(scr, url, charset){
  8360. scr.setAttribute('type', 'text/javascript');
  8361. charset && scr.setAttribute('charset', charset);
  8362. scr.setAttribute('src', url);
  8363. document.getElementsByTagName('head')[0].appendChild(scr);
  8364. };
  8365. /*
  8366. * Tangram
  8367. * Copyright 2009 Baidu Inc. All rights reserved.
  8368. */
  8369. /**
  8370. * 删除script的属性,再删除script标签,以解决修复内存泄漏的问题
  8371. *
  8372. * @param {HTMLElement} src script节点
  8373. */
  8374. baidu.sio._removeScriptTag = function(scr){
  8375. if (scr.clearAttributes) {
  8376. scr.clearAttributes();
  8377. } else {
  8378. for (var attr in scr) {
  8379. if (scr.hasOwnProperty(attr)) {
  8380. delete scr[attr];
  8381. }
  8382. }
  8383. }
  8384. if(scr && scr.parentNode){
  8385. scr.parentNode.removeChild(scr);
  8386. }
  8387. scr = null;
  8388. };
  8389. /*
  8390. * Tangram
  8391. * Copyright 2009 Baidu Inc. All rights reserved.
  8392. */
  8393. /**
  8394. * 通过script标签加载数据,加载完成由浏览器端触发回调
  8395. * @name baidu.sio.callByBrowser
  8396. * @function
  8397. * @grammar baidu.sio.callByBrowser(url, opt_callback, opt_options)
  8398. * @param {string} url 加载数据的url
  8399. * @param {Function|string} opt_callback 数据加载结束时调用的函数或函数名
  8400. * @param {Object} opt_options 其他可选项
  8401. * @config {String} [charset] script的字符集
  8402. * @config {Integer} [timeOut] 超时时间,超过这个时间将不再响应本请求,并触发onfailure函数
  8403. * @config {Function} [onfailure] timeOut设定后才生效,到达超时时间时触发本函数
  8404. * @remark
  8405. * 1、与callByServer不同,callback参数只支持Function类型,不支持string。
  8406. * 2、如果请求了一个不存在的页面,callback函数在IE/opera下也会被调用,因此使用者需要在onsuccess函数中判断数据是否正确加载。
  8407. * @meta standard
  8408. * @see baidu.sio.callByServer
  8409. */
  8410. baidu.sio.callByBrowser = function (url, opt_callback, opt_options) {
  8411. var scr = document.createElement("SCRIPT"),
  8412. scriptLoaded = 0,
  8413. options = opt_options || {},
  8414. charset = options['charset'],
  8415. callback = opt_callback || function(){},
  8416. timeOut = options['timeOut'] || 0,
  8417. timer;
  8418. // IE和opera支持onreadystatechange
  8419. // safari、chrome、opera支持onload
  8420. scr.onload = scr.onreadystatechange = function () {
  8421. // 避免opera下的多次调用
  8422. if (scriptLoaded) {
  8423. return;
  8424. }
  8425. var readyState = scr.readyState;
  8426. if ('undefined' == typeof readyState
  8427. || readyState == "loaded"
  8428. || readyState == "complete") {
  8429. scriptLoaded = 1;
  8430. try {
  8431. callback();
  8432. clearTimeout(timer);
  8433. } finally {
  8434. scr.onload = scr.onreadystatechange = null;
  8435. baidu.sio._removeScriptTag(scr);
  8436. }
  8437. }
  8438. };
  8439. if( timeOut ){
  8440. timer = setTimeout(function(){
  8441. scr.onload = scr.onreadystatechange = null;
  8442. baidu.sio._removeScriptTag(scr);
  8443. options.onfailure && options.onfailure();
  8444. }, timeOut);
  8445. }
  8446. baidu.sio._createScriptTag(scr, url, charset);
  8447. };
  8448. /*
  8449. * Tangram
  8450. * Copyright 2009 Baidu Inc. All rights reserved.
  8451. */
  8452. /**
  8453. * 通过script标签加载数据,加载完成由服务器端触发回调
  8454. * @name baidu.sio.callByServer
  8455. * @function
  8456. * @grammar baidu.sio.callByServer(url, callback[, opt_options])
  8457. * @param {string} url 加载数据的url.
  8458. * @param {Function|string} callback 服务器端调用的函数或函数名。如果没有指定本参数,将在URL中寻找options['queryField']做为callback的方法名.
  8459. * @param {Object} opt_options 加载数据时的选项.
  8460. * @config {string} [charset] script的字符集
  8461. * @config {string} [queryField] 服务器端callback请求字段名,默认为callback
  8462. * @config {Integer} [timeOut] 超时时间(单位:ms),超过这个时间将不再响应本请求,并触发onfailure函数
  8463. * @config {Function} [onfailure] timeOut设定后才生效,到达超时时间时触发本函数
  8464. * @remark
  8465. * 如果url中已经包含key为“options['queryField']”的query项,将会被替换成callback中参数传递或自动生成的函数名。
  8466. * @meta standard
  8467. * @see baidu.sio.callByBrowser
  8468. */
  8469. baidu.sio.callByServer = function(url, callback, opt_options) {
  8470. var scr = document.createElement('SCRIPT'),
  8471. prefix = 'bd__cbs__',
  8472. callbackName,
  8473. callbackImpl,
  8474. options = opt_options || {},
  8475. charset = options['charset'],
  8476. queryField = options['queryField'] || 'callback',
  8477. timeOut = options['timeOut'] || 0,
  8478. timer,
  8479. reg = new RegExp('(\\?|&)' + queryField + '=([^&]*)'),
  8480. matches;
  8481. if (baidu.lang.isFunction(callback)) {
  8482. callbackName = prefix + Math.floor(Math.random() * 2147483648).toString(36);
  8483. window[callbackName] = getCallBack(0);
  8484. } else if(baidu.lang.isString(callback)){
  8485. // 如果callback是一个字符串的话,就需要保证url是唯一的,不要去改变它
  8486. // TODO 当调用了callback之后,无法删除动态创建的script标签
  8487. callbackName = callback;
  8488. } else {
  8489. if (matches = reg.exec(url)) {
  8490. callbackName = matches[2];
  8491. }
  8492. }
  8493. if( timeOut ){
  8494. timer = setTimeout(getCallBack(1), timeOut);
  8495. }
  8496. //如果用户在URL中已有callback,用参数传入的callback替换之
  8497. url = url.replace(reg, '\x241' + queryField + '=' + callbackName);
  8498. if (url.search(reg) < 0) {
  8499. url += (url.indexOf('?') < 0 ? '?' : '&') + queryField + '=' + callbackName;
  8500. }
  8501. baidu.sio._createScriptTag(scr, url, charset);
  8502. /*
  8503. * 返回一个函数,用于立即(挂在window上)或者超时(挂在setTimeout中)时执行
  8504. */
  8505. function getCallBack(onTimeOut){
  8506. /*global callbackName, callback, scr, options;*/
  8507. return function(){
  8508. try {
  8509. if( onTimeOut ){
  8510. options.onfailure && options.onfailure();
  8511. }else{
  8512. callback.apply(window, arguments);
  8513. clearTimeout(timer);
  8514. }
  8515. window[callbackName] = null;
  8516. delete window[callbackName];
  8517. } catch (exception) {
  8518. // ignore the exception
  8519. } finally {
  8520. baidu.sio._removeScriptTag(scr);
  8521. }
  8522. }
  8523. }
  8524. };
  8525. /*
  8526. * Tangram
  8527. * Copyright 2011 Baidu Inc. All rights reserved.
  8528. */
  8529. /**
  8530. * 通过请求一个图片的方式令服务器存储一条日志
  8531. * author: int08h,leeight
  8532. * @param {string} url 要发送的地址.
  8533. */
  8534. baidu.sio.log = function(url) {
  8535. var img = new Image(),
  8536. key = 'tangram_sio_log_' + Math.floor(Math.random() *
  8537. 2147483648).toString(36);
  8538. // 这里一定要挂在window下
  8539. // 在IE中,如果没挂在window下,这个img变量又正好被GC的话,img的请求会abort
  8540. // 导致服务器收不到日志
  8541. window[key] = img;
  8542. img.onload = img.onerror = img.onabort = function() {
  8543. // 下面这句非常重要
  8544. // 如果这个img很不幸正好加载了一个存在的资源,又是个gif动画
  8545. // 则在gif动画播放过程中,img会多次触发onload
  8546. // 因此一定要清空
  8547. img.onload = img.onerror = img.onabort = null;
  8548. window[key] = null;
  8549. // 下面这句非常重要
  8550. // new Image创建的是DOM,DOM的事件中形成闭包环引用DOM是典型的内存泄露
  8551. // 因此这里一定要置为null
  8552. img = null;
  8553. };
  8554. // 一定要在注册了事件之后再设置src
  8555. // 不然如果图片是读缓存的话,会错过事件处理
  8556. // 最后,对于url最好是添加客户端时间来防止缓存
  8557. // 同时服务器也配合一下传递Cache-Control: no-cache;
  8558. img.src = url;
  8559. };
  8560. /*
  8561. * Tangram
  8562. * Copyright 2009 Baidu Inc. All rights reserved.
  8563. *
  8564. * path: baidu/string/decodeHTML.js
  8565. * author: erik
  8566. * version: 1.1.0
  8567. * date: 2009/11/15
  8568. */
  8569. /**
  8570. * 对目标字符串进行html解码
  8571. * @name baidu.string.decodeHTML
  8572. * @function
  8573. * @grammar baidu.string.decodeHTML(source)
  8574. * @param {string} source 目标字符串
  8575. * @shortcut decodeHTML
  8576. * @meta standard
  8577. * @see baidu.string.encodeHTML
  8578. *
  8579. * @returns {string} html解码后的字符串
  8580. */
  8581. baidu.string.decodeHTML = function (source) {
  8582. var str = String(source)
  8583. .replace(/&quot;/g,'"')
  8584. .replace(/&lt;/g,'<')
  8585. .replace(/&gt;/g,'>')
  8586. .replace(/&amp;/g, "&");
  8587. //处理转义的中文和实体字符
  8588. return str.replace(/&#([\d]+);/g, function(_0, _1){
  8589. return String.fromCharCode(parseInt(_1, 10));
  8590. });
  8591. };
  8592. baidu.decodeHTML = baidu.string.decodeHTML;
  8593. /*
  8594. * Tangram
  8595. * Copyright 2009 Baidu Inc. All rights reserved.
  8596. *
  8597. * path: baidu/string/encodeHTML.js
  8598. * author: erik
  8599. * version: 1.1.0
  8600. * date: 2009/11/15
  8601. */
  8602. /**
  8603. * 对目标字符串进行html编码
  8604. * @name baidu.string.encodeHTML
  8605. * @function
  8606. * @grammar baidu.string.encodeHTML(source)
  8607. * @param {string} source 目标字符串
  8608. * @remark
  8609. * 编码字符有5个:&<>"'
  8610. * @shortcut encodeHTML
  8611. * @meta standard
  8612. * @see baidu.string.decodeHTML
  8613. *
  8614. * @returns {string} html编码后的字符串
  8615. */
  8616. baidu.string.encodeHTML = function (source) {
  8617. return String(source)
  8618. .replace(/&/g,'&amp;')
  8619. .replace(/</g,'&lt;')
  8620. .replace(/>/g,'&gt;')
  8621. .replace(/"/g, "&quot;")
  8622. .replace(/'/g, "&#39;");
  8623. };
  8624. baidu.encodeHTML = baidu.string.encodeHTML;
  8625. /*
  8626. * Tangram
  8627. * Copyright 2009 Baidu Inc. All rights reserved.
  8628. *
  8629. * path: baidu/string/filterFormat.js
  8630. * author: rocy
  8631. * version: 1.1.2
  8632. * date: 2010/06/10
  8633. */
  8634. /**
  8635. * 对目标字符串进行格式化,支持过滤
  8636. * @name baidu.string.filterFormat
  8637. * @function
  8638. * @grammar baidu.string.filterFormat(source, opts)
  8639. * @param {string} source 目标字符串
  8640. * @param {Object|string...} opts 提供相应数据的对象
  8641. * @version 1.2
  8642. * @remark
  8643. *
  8644. 在 baidu.string.format的基础上,增加了过滤功能. 目标字符串中的#{url|escapeUrl},<br/>
  8645. 会替换成baidu.string.filterFormat["escapeUrl"](opts.url);<br/>
  8646. 过滤函数需要之前挂载在baidu.string.filterFormat属性中.
  8647. * @see baidu.string.format,baidu.string.filterFormat.escapeJs,baidu.string.filterFormat.escapeString,baidu.string.filterFormat.toInt
  8648. * @returns {string} 格式化后的字符串
  8649. */
  8650. baidu.string.filterFormat = function (source, opts) {
  8651. var data = Array.prototype.slice.call(arguments,1), toString = Object.prototype.toString;
  8652. if(data.length){
  8653. data = data.length == 1 ?
  8654. /* ie 下 Object.prototype.toString.call(null) == '[object Object]' */
  8655. (opts !== null && (/\[object Array\]|\[object Object\]/.test(toString.call(opts))) ? opts : data)
  8656. : data;
  8657. return source.replace(/#\{(.+?)\}/g, function (match, key){
  8658. var filters, replacer, i, len, func;
  8659. if(!data) return '';
  8660. filters = key.split("|");
  8661. replacer = data[filters[0]];
  8662. // chrome 下 typeof /a/ == 'function'
  8663. if('[object Function]' == toString.call(replacer)){
  8664. replacer = replacer(filters[0]/*key*/);
  8665. }
  8666. for(i=1,len = filters.length; i< len; ++i){
  8667. func = baidu.string.filterFormat[filters[i]];
  8668. if('[object Function]' == toString.call(func)){
  8669. replacer = func(replacer);
  8670. }
  8671. }
  8672. return ( ('undefined' == typeof replacer || replacer === null)? '' : replacer);
  8673. });
  8674. }
  8675. return source;
  8676. };
  8677. /*
  8678. * Tangram
  8679. * Copyright 2009 Baidu Inc. All rights reserved.
  8680. *
  8681. * path: baidu/string/filterFormat/escapeJs.js
  8682. * author: rocy
  8683. * version: 1.1.2
  8684. * date: 2010/06/12
  8685. */
  8686. /**
  8687. * 对js片段的字符做安全转义,编码低于255的都将转换成\x加16进制数
  8688. * @name baidu.string.filterFormat.escapeJs
  8689. * @function
  8690. * @grammar baidu.string.filterFormat.escapeJs(source)
  8691. * @param {String} source 待转义字符串
  8692. *
  8693. * @see baidu.string.filterFormat,baidu.string.filterFormat.escapeString,baidu.string.filterFormat.toInt
  8694. * @version 1.2
  8695. * @return {String} 转义之后的字符串
  8696. */
  8697. baidu.string.filterFormat.escapeJs = function(str){
  8698. if(!str || 'string' != typeof str) return str;
  8699. var i,len,charCode,ret = [];
  8700. for(i=0, len=str.length; i < len; ++i){
  8701. charCode = str.charCodeAt(i);
  8702. if(charCode > 255){
  8703. ret.push(str.charAt(i));
  8704. } else{
  8705. ret.push('\\x' + charCode.toString(16));
  8706. }
  8707. }
  8708. return ret.join('');
  8709. };
  8710. baidu.string.filterFormat.js = baidu.string.filterFormat.escapeJs;
  8711. /*
  8712. * Tangram
  8713. * Copyright 2009 Baidu Inc. All rights reserved.
  8714. *
  8715. * path: baidu/string/filterFormat/escapeString.js
  8716. * author: rocy
  8717. * version: 1.1.2
  8718. * date: 2010/06/12
  8719. */
  8720. /**
  8721. * 对字符串做安全转义,转义字符包括: 单引号,双引号,左右小括号,斜杠,反斜杠,上引号.
  8722. * @name baidu.string.filterFormat.escapeString
  8723. * @function
  8724. * @grammar baidu.string.filterFormat.escapeString(source)
  8725. * @param {String} source 待转义字符串
  8726. *
  8727. * @see baidu.string.filterFormat,baidu.string.filterFormat.escapeJs,baidu.string.filterFormat.toInt
  8728. * @version 1.2
  8729. * @return {String} 转义之后的字符串
  8730. */
  8731. baidu.string.filterFormat.escapeString = function(str){
  8732. if(!str || 'string' != typeof str) return str;
  8733. return str.replace(/["'<>\\\/`]/g, function($0){
  8734. return '&#'+ $0.charCodeAt(0) +';';
  8735. });
  8736. };
  8737. baidu.string.filterFormat.e = baidu.string.filterFormat.escapeString;
  8738. /*
  8739. * Tangram
  8740. * Copyright 2009 Baidu Inc. All rights reserved.
  8741. *
  8742. * path: baidu/string/filterFormat/toInt.js
  8743. * author: rocy
  8744. * version: 1.1.2
  8745. * date: 2010/06/12
  8746. */
  8747. /**
  8748. * 对数字做安全转义,确保是十进制数字;否则返回0.
  8749. * @name baidu.string.filterFormat.toInt
  8750. * @function
  8751. * @grammar baidu.string.filterFormat.toInt(source)
  8752. * @param {String} source 待转义字符串
  8753. *
  8754. * @see baidu.string.filterFormat,baidu.string.filterFormat.escapeJs,baidu.string.filterFormat.escapeString
  8755. * @version 1.2
  8756. * @return {Number} 转义之后的数字
  8757. */
  8758. baidu.string.filterFormat.toInt = function(str){
  8759. return parseInt(str, 10) || 0;
  8760. };
  8761. baidu.string.filterFormat.i = baidu.string.filterFormat.toInt;
  8762. /*
  8763. * Tangram
  8764. * Copyright 2009 Baidu Inc. All rights reserved.
  8765. *
  8766. * path: baidu/string/format.js
  8767. * author: dron, erik
  8768. * version: 1.1.0
  8769. * date: 2009/11/30
  8770. */
  8771. /**
  8772. * 对目标字符串进行格式化
  8773. * @name baidu.string.format
  8774. * @function
  8775. * @grammar baidu.string.format(source, opts)
  8776. * @param {string} source 目标字符串
  8777. * @param {Object|string...} opts 提供相应数据的对象或多个字符串
  8778. * @remark
  8779. *
  8780. opts参数为“Object”时,替换目标字符串中的#{property name}部分。<br>
  8781. opts为“string...”时,替换目标字符串中的#{0}、#{1}...部分。
  8782. * @shortcut format
  8783. * @meta standard
  8784. *
  8785. * @returns {string} 格式化后的字符串
  8786. */
  8787. baidu.string.format = function (source, opts) {
  8788. source = String(source);
  8789. var data = Array.prototype.slice.call(arguments,1), toString = Object.prototype.toString;
  8790. if(data.length){
  8791. data = data.length == 1 ?
  8792. /* ie 下 Object.prototype.toString.call(null) == '[object Object]' */
  8793. (opts !== null && (/\[object Array\]|\[object Object\]/.test(toString.call(opts))) ? opts : data)
  8794. : data;
  8795. return source.replace(/#\{(.+?)\}/g, function (match, key){
  8796. var replacer = data[key];
  8797. // chrome 下 typeof /a/ == 'function'
  8798. if('[object Function]' == toString.call(replacer)){
  8799. replacer = replacer(key);
  8800. }
  8801. return ('undefined' == typeof replacer ? '' : replacer);
  8802. });
  8803. }
  8804. return source;
  8805. };
  8806. // 声明快捷方法
  8807. baidu.format = baidu.string.format;
  8808. /*
  8809. * Tangram
  8810. * Copyright 2010 Baidu Inc. All rights reserved.
  8811. *
  8812. * @author: meizz
  8813. * @namespace: baidu.string.formatColor
  8814. * @version: 2010-01-23
  8815. */
  8816. /**
  8817. * 将各种浏览器里的颜色值转换成 #RRGGBB 的格式
  8818. * @name baidu.string.formatColor
  8819. * @function
  8820. * @grammar baidu.string.formatColor(color)
  8821. * @param {string} color 颜色值字符串
  8822. * @version 1.3
  8823. *
  8824. * @returns {string} #RRGGBB格式的字符串或空
  8825. */
  8826. (function(){
  8827. // 将正则表达式预创建,可提高效率
  8828. var reg1 = /^\#[\da-f]{6}$/i,
  8829. reg2 = /^rgb\((\d+), (\d+), (\d+)\)$/,
  8830. keyword = {
  8831. black: '#000000',
  8832. silver: '#c0c0c0',
  8833. gray: '#808080',
  8834. white: '#ffffff',
  8835. maroon: '#800000',
  8836. red: '#ff0000',
  8837. purple: '#800080',
  8838. fuchsia: '#ff00ff',
  8839. green: '#008000',
  8840. lime: '#00ff00',
  8841. olive: '#808000',
  8842. yellow: '#ffff0',
  8843. navy: '#000080',
  8844. blue: '#0000ff',
  8845. teal: '#008080',
  8846. aqua: '#00ffff'
  8847. };
  8848. baidu.string.formatColor = function(color) {
  8849. if(reg1.test(color)) {
  8850. // #RRGGBB 直接返回
  8851. return color;
  8852. } else if(reg2.test(color)) {
  8853. // 非IE中的 rgb(0, 0, 0)
  8854. for (var s, i=1, color="#"; i<4; i++) {
  8855. s = parseInt(RegExp["\x24"+ i]).toString(16);
  8856. color += ("00"+ s).substr(s.length);
  8857. }
  8858. return color;
  8859. } else if(/^\#[\da-f]{3}$/.test(color)) {
  8860. // 简写的颜色值: #F00
  8861. var s1 = color.charAt(1),
  8862. s2 = color.charAt(2),
  8863. s3 = color.charAt(3);
  8864. return "#"+ s1 + s1 + s2 + s2 + s3 + s3;
  8865. }else if(keyword[color])
  8866. return keyword[color];
  8867. return "";
  8868. };
  8869. })();
  8870. /*
  8871. * Tangram
  8872. * Copyright 2009 Baidu Inc. All rights reserved.
  8873. *
  8874. * path: baidu/string/getByteLength.js
  8875. * author: erik
  8876. * version: 1.1.0
  8877. * date: 2009/11/15
  8878. */
  8879. /**
  8880. * 获取目标字符串在gbk编码下的字节长度
  8881. * @name baidu.string.getByteLength
  8882. * @function
  8883. * @grammar baidu.string.getByteLength(source)
  8884. * @param {string} source 目标字符串
  8885. * @remark
  8886. * 获取字符在gbk编码下的字节长度, 实现原理是认为大于127的就一定是双字节。如果字符超出gbk编码范围, 则这个计算不准确
  8887. * @meta standard
  8888. * @see baidu.string.subByte
  8889. *
  8890. * @returns {number} 字节长度
  8891. */
  8892. baidu.string.getByteLength = function (source) {
  8893. return String(source).replace(/[^\x00-\xff]/g, "ci").length;
  8894. };
  8895. /*
  8896. * tangram
  8897. * copyright 2011 baidu inc. all rights reserved.
  8898. *
  8899. * path: baidu/string/stripTags.js
  8900. * author: leeight
  8901. * version: 1.1.0
  8902. * date: 2011/04/30
  8903. */
  8904. /**
  8905. * 去掉字符串中的html标签
  8906. * @param {string} source 要处理的字符串.
  8907. * @return {string}
  8908. */
  8909. baidu.string.stripTags = function(source) {
  8910. return String(source || '').replace(/<[^>]+>/g, '');
  8911. };
  8912. /*
  8913. * Tangram
  8914. * Copyright 2009 Baidu Inc. All rights reserved.
  8915. *
  8916. * path: baidu/string/subByte.js
  8917. * author: dron, erik, berg
  8918. * version: 1.2
  8919. * date: 2010-06-30
  8920. */
  8921. /**
  8922. * 对目标字符串按gbk编码截取字节长度
  8923. * @name baidu.string.subByte
  8924. * @function
  8925. * @grammar baidu.string.subByte(source, length)
  8926. * @param {string} source 目标字符串
  8927. * @param {number} length 需要截取的字节长度
  8928. * @param {string} [tail] 追加字符串,可选.
  8929. * @remark
  8930. * 截取过程中,遇到半个汉字时,向下取整。
  8931. * @see baidu.string.getByteLength
  8932. *
  8933. * @returns {string} 字符串截取结果
  8934. */
  8935. baidu.string.subByte = function (source, length, tail) {
  8936. source = String(source);
  8937. tail = tail || '';
  8938. if (length < 0 || baidu.string.getByteLength(source) <= length) {
  8939. return source + tail;
  8940. }
  8941. //thanks 加宽提供优化方法
  8942. source = source.substr(0,length).replace(/([^\x00-\xff])/g,"\x241 ")//双字节字符替换成两个
  8943. .substr(0,length)//截取长度
  8944. .replace(/[^\x00-\xff]$/,"")//去掉临界双字节字符
  8945. .replace(/([^\x00-\xff]) /g,"\x241");//还原
  8946. return source + tail;
  8947. };
  8948. /*
  8949. * Tangram
  8950. * Copyright 2009 Baidu Inc. All rights reserved.
  8951. *
  8952. * path: baidu/string/toHalfWidth.js
  8953. * author: erik
  8954. * version: 1.1.0
  8955. * date: 2009/11/15
  8956. */
  8957. /**
  8958. * 将目标字符串中常见全角字符转换成半角字符
  8959. * @name baidu.string.toHalfWidth
  8960. * @function
  8961. * @grammar baidu.string.toHalfWidth(source)
  8962. * @param {string} source 目标字符串
  8963. * @remark
  8964. *
  8965. 将全角的字符转成半角, 将“&amp;#xFF01;”至“&amp;#xFF5E;”范围的全角转成“&amp;#33;”至“&amp;#126;”, 还包括全角空格包括常见的全角数字/空格/字母, 用于需要同时支持全半角的转换, 具体转换列表如下("空格"未列出):<br><br>
  8966. ! => !<br>
  8967. " => "<br>
  8968. # => #<br>
  8969. $ => $<br>
  8970. % => %<br>
  8971. & => &<br>
  8972. ' => '<br>
  8973. ( => (<br>
  8974. ) => )<br>
  8975. * => *<br>
  8976. + => +<br>
  8977. , => ,<br>
  8978. - => -<br>
  8979. . => .<br>
  8980. / => /<br>
  8981. 0 => 0<br>
  8982. 1 => 1<br>
  8983. 2 => 2<br>
  8984. 3 => 3<br>
  8985. 4 => 4<br>
  8986. 5 => 5<br>
  8987. 6 => 6<br>
  8988. 7 => 7<br>
  8989. 8 => 8<br>
  8990. 9 => 9<br>
  8991. : => :<br>
  8992. ; => ;<br>
  8993. < => <<br>
  8994. = => =<br>
  8995. > => ><br>
  8996. ? => ?<br>
  8997. @ => @<br>
  8998. A => A<br>
  8999. B => B<br>
  9000. C => C<br>
  9001. D => D<br>
  9002. E => E<br>
  9003. F => F<br>
  9004. G => G<br>
  9005. H => H<br>
  9006. I => I<br>
  9007. J => J<br>
  9008. K => K<br>
  9009. L => L<br>
  9010. M => M<br>
  9011. N => N<br>
  9012. O => O<br>
  9013. P => P<br>
  9014. Q => Q<br>
  9015. R => R<br>
  9016. S => S<br>
  9017. T => T<br>
  9018. U => U<br>
  9019. V => V<br>
  9020. W => W<br>
  9021. X => X<br>
  9022. Y => Y<br>
  9023. Z => Z<br>
  9024. [ => [<br>
  9025. \ => \<br>
  9026. ] => ]<br>
  9027. ^ => ^<br>
  9028. _ => _<br>
  9029. ` => `<br>
  9030. a => a<br>
  9031. b => b<br>
  9032. c => c<br>
  9033. d => d<br>
  9034. e => e<br>
  9035. f => f<br>
  9036. g => g<br>
  9037. h => h<br>
  9038. i => i<br>
  9039. j => j<br>
  9040. k => k<br>
  9041. l => l<br>
  9042. m => m<br>
  9043. n => n<br>
  9044. o => o<br>
  9045. p => p<br>
  9046. q => q<br>
  9047. r => r<br>
  9048. s => s<br>
  9049. t => t<br>
  9050. u => u<br>
  9051. v => v<br>
  9052. w => w<br>
  9053. x => x<br>
  9054. y => y<br>
  9055. z => z<br>
  9056. { => {<br>
  9057. | => |<br>
  9058. } => }<br>
  9059. ~ => ~<br>
  9060. *
  9061. * @returns {string} 转换后的字符串
  9062. */
  9063. baidu.string.toHalfWidth = function (source) {
  9064. return String(source).replace(/[\uFF01-\uFF5E]/g,
  9065. function(c){
  9066. return String.fromCharCode(c.charCodeAt(0) - 65248);
  9067. }).replace(/\u3000/g," ");
  9068. };
  9069. /*
  9070. * Tangram
  9071. * Copyright 2009 Baidu Inc. All rights reserved.
  9072. *
  9073. * path: baidu/string/wbr.js
  9074. * author: erik
  9075. * version: 1.1.0
  9076. * date: 2009/11/30
  9077. */
  9078. /**
  9079. * 为目标字符串添加wbr软换行
  9080. * @name baidu.string.wbr
  9081. * @function
  9082. * @grammar baidu.string.wbr(source)
  9083. * @param {string} source 目标字符串
  9084. * @remark
  9085. *
  9086. 1.支持html标签、属性以及字符实体。<br>
  9087. 2.任意字符中间都会插入wbr标签,对于过长的文本,会造成dom节点元素增多,占用浏览器资源。
  9088. 3.在opera下,浏览器默认css不会为wbr加上样式,导致没有换行效果,可以在css中加上 wbr:after { content: "\00200B" } 解决此问题
  9089. *
  9090. * @returns {string} 添加软换行后的字符串
  9091. */
  9092. baidu.string.wbr = function (source) {
  9093. return String(source)
  9094. .replace(/(?:<[^>]+>)|(?:&#?[0-9a-z]{2,6};)|(.{1})/gi, '$&<wbr>')
  9095. .replace(/><wbr>/g, '>');
  9096. };
  9097. /*
  9098. * Tangram
  9099. * Copyright 2009 Baidu Inc. All rights reserved.
  9100. *
  9101. * path: baidu/swf.js
  9102. * author: erik
  9103. * version: 1.1.0
  9104. * date: 2009/11/16
  9105. */
  9106. /**
  9107. * @namespace baidu.swf 操作flash对象的方法,包括创建flash对象、获取flash对象以及判断flash插件的版本号。
  9108. */
  9109. baidu.swf = baidu.swf || {};
  9110. /*
  9111. * Tangram
  9112. * Copyright 2009 Baidu Inc. All rights reserved.
  9113. *
  9114. * path: baidu/swf/version.js
  9115. * author: erik
  9116. * version: 1.1.0
  9117. * date: 2009/11/17
  9118. */
  9119. /**
  9120. * 浏览器支持的flash插件版本
  9121. * @property version 浏览器支持的flash插件版本
  9122. * @grammar baidu.swf.version
  9123. * @meta standard
  9124. */
  9125. baidu.swf.version = (function () {
  9126. var n = navigator;
  9127. if (n.plugins && n.mimeTypes.length) {
  9128. var plugin = n.plugins["Shockwave Flash"];
  9129. if (plugin && plugin.description) {
  9130. return plugin.description
  9131. .replace(/([a-zA-Z]|\s)+/, "")
  9132. .replace(/(\s)+r/, ".") + ".0";
  9133. }
  9134. } else if (window.ActiveXObject && !window.opera) {
  9135. for (var i = 12; i >= 2; i--) {
  9136. try {
  9137. var c = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + i);
  9138. if (c) {
  9139. var version = c.GetVariable("$version");
  9140. return version.replace(/WIN/g,'').replace(/,/g,'.');
  9141. }
  9142. } catch(e) {}
  9143. }
  9144. }
  9145. })();
  9146. /*
  9147. * Tangram
  9148. * Copyright 2009 Baidu Inc. All rights reserved.
  9149. *
  9150. * path: baidu/swf/createHTML.js
  9151. * author: erik
  9152. * version: 1.1.0
  9153. * date: 2009/11/17
  9154. */
  9155. /**
  9156. * 创建flash对象的html字符串
  9157. * @name baidu.swf.createHTML
  9158. * @function
  9159. * @grammar baidu.swf.createHTML(options)
  9160. *
  9161. * @param {Object} options 创建flash的选项参数
  9162. * @param {string} options.id 要创建的flash的标识
  9163. * @param {string} options.url flash文件的url
  9164. * @param {String} options.errorMessage 未安装flash player或flash player版本号过低时的提示
  9165. * @param {string} options.ver 最低需要的flash player版本号
  9166. * @param {string} options.width flash的宽度
  9167. * @param {string} options.height flash的高度
  9168. * @param {string} options.align flash的对齐方式,允许值:middle/left/right/top/bottom
  9169. * @param {string} options.base 设置用于解析swf文件中的所有相对路径语句的基本目录或URL
  9170. * @param {string} options.bgcolor swf文件的背景色
  9171. * @param {string} options.salign 设置缩放的swf文件在由width和height设置定义的区域内的位置。允许值:l/r/t/b/tl/tr/bl/br
  9172. * @param {boolean} options.menu 是否显示右键菜单,允许值:true/false
  9173. * @param {boolean} options.loop 播放到最后一帧时是否重新播放,允许值: true/false
  9174. * @param {boolean} options.play flash是否在浏览器加载时就开始播放。允许值:true/false
  9175. * @param {string} options.quality 设置flash播放的画质,允许值:low/medium/high/autolow/autohigh/best
  9176. * @param {string} options.scale 设置flash内容如何缩放来适应设置的宽高。允许值:showall/noborder/exactfit
  9177. * @param {string} options.wmode 设置flash的显示模式。允许值:window/opaque/transparent
  9178. * @param {string} options.allowscriptaccess 设置flash与页面的通信权限。允许值:always/never/sameDomain
  9179. * @param {string} options.allownetworking 设置swf文件中允许使用的网络API。允许值:all/internal/none
  9180. * @param {boolean} options.allowfullscreen 是否允许flash全屏。允许值:true/false
  9181. * @param {boolean} options.seamlesstabbing 允许设置执行无缝跳格,从而使用户能跳出flash应用程序。该参数只能在安装Flash7及更高版本的Windows中使用。允许值:true/false
  9182. * @param {boolean} options.devicefont 设置静态文本对象是否以设备字体呈现。允许值:true/false
  9183. * @param {boolean} options.swliveconnect 第一次加载flash时浏览器是否应启动Java。允许值:true/false
  9184. * @param {Object} options.vars 要传递给flash的参数,支持JSON或string类型。
  9185. *
  9186. * @see baidu.swf.create
  9187. * @meta standard
  9188. * @returns {string} flash对象的html字符串
  9189. */
  9190. baidu.swf.createHTML = function (options) {
  9191. options = options || {};
  9192. var version = baidu.swf.version,
  9193. needVersion = options['ver'] || '6.0.0',
  9194. vUnit1, vUnit2, i, k, len, item, tmpOpt = {},
  9195. encodeHTML = baidu.string.encodeHTML;
  9196. // 复制options,避免修改原对象
  9197. for (k in options) {
  9198. tmpOpt[k] = options[k];
  9199. }
  9200. options = tmpOpt;
  9201. // 浏览器支持的flash插件版本判断
  9202. if (version) {
  9203. version = version.split('.');
  9204. needVersion = needVersion.split('.');
  9205. for (i = 0; i < 3; i++) {
  9206. vUnit1 = parseInt(version[i], 10);
  9207. vUnit2 = parseInt(needVersion[i], 10);
  9208. if (vUnit2 < vUnit1) {
  9209. break;
  9210. } else if (vUnit2 > vUnit1) {
  9211. return ''; // 需要更高的版本号
  9212. }
  9213. }
  9214. } else {
  9215. return ''; // 未安装flash插件
  9216. }
  9217. var vars = options['vars'],
  9218. objProperties = ['classid', 'codebase', 'id', 'width', 'height', 'align'];
  9219. // 初始化object标签需要的classid、codebase属性值
  9220. options['align'] = options['align'] || 'middle';
  9221. options['classid'] = 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000';
  9222. options['codebase'] = 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0';
  9223. options['movie'] = options['url'] || '';
  9224. delete options['vars'];
  9225. delete options['url'];
  9226. // 初始化flashvars参数的值
  9227. if ('string' == typeof vars) {
  9228. options['flashvars'] = vars;
  9229. } else {
  9230. var fvars = [];
  9231. for (k in vars) {
  9232. item = vars[k];
  9233. fvars.push(k + "=" + encodeURIComponent(item));
  9234. }
  9235. options['flashvars'] = fvars.join('&');
  9236. }
  9237. // 构建IE下支持的object字符串,包括属性和参数列表
  9238. var str = ['<object '];
  9239. for (i = 0, len = objProperties.length; i < len; i++) {
  9240. item = objProperties[i];
  9241. str.push(' ', item, '="', encodeHTML(options[item]), '"');
  9242. }
  9243. str.push('>');
  9244. var params = {
  9245. 'wmode' : 1,
  9246. 'scale' : 1,
  9247. 'quality' : 1,
  9248. 'play' : 1,
  9249. 'loop' : 1,
  9250. 'menu' : 1,
  9251. 'salign' : 1,
  9252. 'bgcolor' : 1,
  9253. 'base' : 1,
  9254. 'allowscriptaccess' : 1,
  9255. 'allownetworking' : 1,
  9256. 'allowfullscreen' : 1,
  9257. 'seamlesstabbing' : 1,
  9258. 'devicefont' : 1,
  9259. 'swliveconnect' : 1,
  9260. 'flashvars' : 1,
  9261. 'movie' : 1
  9262. };
  9263. for (k in options) {
  9264. item = options[k];
  9265. k = k.toLowerCase();
  9266. if (params[k] && (item || item === false || item === 0)) {
  9267. str.push('<param name="' + k + '" value="' + encodeHTML(item) + '" />');
  9268. }
  9269. }
  9270. // 使用embed时,flash地址的属性名是src,并且要指定embed的type和pluginspage属性
  9271. options['src'] = options['movie'];
  9272. options['name'] = options['id'];
  9273. delete options['id'];
  9274. delete options['movie'];
  9275. delete options['classid'];
  9276. delete options['codebase'];
  9277. options['type'] = 'application/x-shockwave-flash';
  9278. options['pluginspage'] = 'http://www.macromedia.com/go/getflashplayer';
  9279. // 构建embed标签的字符串
  9280. str.push('<embed');
  9281. // 在firefox、opera、safari下,salign属性必须在scale属性之后,否则会失效
  9282. // 经过讨论,决定采用BT方法,把scale属性的值先保存下来,最后输出
  9283. var salign;
  9284. for (k in options) {
  9285. item = options[k];
  9286. if (item || item === false || item === 0) {
  9287. if ((new RegExp("^salign\x24", "i")).test(k)) {
  9288. salign = item;
  9289. continue;
  9290. }
  9291. str.push(' ', k, '="', encodeHTML(item), '"');
  9292. }
  9293. }
  9294. if (salign) {
  9295. str.push(' salign="', encodeHTML(salign), '"');
  9296. }
  9297. str.push('></embed></object>');
  9298. return str.join('');
  9299. };
  9300. /*
  9301. * Tangram
  9302. * Copyright 2009 Baidu Inc. All rights reserved.
  9303. *
  9304. * path: baidu/swf/create.js
  9305. * author: erik
  9306. * version: 1.1.0
  9307. * date: 2009/11/17
  9308. */
  9309. /**
  9310. * 在页面中创建一个flash对象
  9311. * @name baidu.swf.create
  9312. * @function
  9313. * @grammar baidu.swf.create(options[, container])
  9314. *
  9315. * @param {Object} options 创建flash的选项参数
  9316. * @param {string} options.id 要创建的flash的标识
  9317. * @param {string} options.url flash文件的url
  9318. * @param {String} options.errorMessage 未安装flash player或flash player版本号过低时的提示
  9319. * @param {string} options.ver 最低需要的flash player版本号
  9320. * @param {string} options.width flash的宽度
  9321. * @param {string} options.height flash的高度
  9322. * @param {string} options.align flash的对齐方式,允许值:middle/left/right/top/bottom
  9323. * @param {string} options.base 设置用于解析swf文件中的所有相对路径语句的基本目录或URL
  9324. * @param {string} options.bgcolor swf文件的背景色
  9325. * @param {string} options.salign 设置缩放的swf文件在由width和height设置定义的区域内的位置。允许值:l/r/t/b/tl/tr/bl/br
  9326. * @param {boolean} options.menu 是否显示右键菜单,允许值:true/false
  9327. * @param {boolean} options.loop 播放到最后一帧时是否重新播放,允许值: true/false
  9328. * @param {boolean} options.play flash是否在浏览器加载时就开始播放。允许值:true/false
  9329. * @param {string} options.quality 设置flash播放的画质,允许值:low/medium/high/autolow/autohigh/best
  9330. * @param {string} options.scale 设置flash内容如何缩放来适应设置的宽高。允许值:showall/noborder/exactfit
  9331. * @param {string} options.wmode 设置flash的显示模式。允许值:window/opaque/transparent
  9332. * @param {string} options.allowscriptaccess 设置flash与页面的通信权限。允许值:always/never/sameDomain
  9333. * @param {string} options.allownetworking 设置swf文件中允许使用的网络API。允许值:all/internal/none
  9334. * @param {boolean} options.allowfullscreen 是否允许flash全屏。允许值:true/false
  9335. * @param {boolean} options.seamlesstabbing 允许设置执行无缝跳格,从而使用户能跳出flash应用程序。该参数只能在安装Flash7及更高版本的Windows中使用。允许值:true/false
  9336. * @param {boolean} options.devicefont 设置静态文本对象是否以设备字体呈现。允许值:true/false
  9337. * @param {boolean} options.swliveconnect 第一次加载flash时浏览器是否应启动Java。允许值:true/false
  9338. * @param {Object} options.vars 要传递给flash的参数,支持JSON或string类型。
  9339. *
  9340. * @param {HTMLElement|string} [container] flash对象的父容器元素,不传递该参数时在当前代码位置创建flash对象。
  9341. * @meta standard
  9342. * @see baidu.swf.createHTML,baidu.swf.getMovie
  9343. */
  9344. baidu.swf.create = function (options, target) {
  9345. options = options || {};
  9346. var html = baidu.swf.createHTML(options)
  9347. || options['errorMessage']
  9348. || '';
  9349. if (target && 'string' == typeof target) {
  9350. target = document.getElementById(target);
  9351. }
  9352. if (target) {
  9353. target.innerHTML = html;
  9354. } else {
  9355. document.write(html);
  9356. }
  9357. };
  9358. /*
  9359. * Tangram
  9360. * Copyright 2009 Baidu Inc. All rights reserved.
  9361. *
  9362. * path: baidu/swf/getMovie.js
  9363. * author: erik
  9364. * version: 1.1.0
  9365. * date: 2009/11/16
  9366. */
  9367. /**
  9368. * 获得flash对象的实例
  9369. * @name baidu.swf.getMovie
  9370. * @function
  9371. * @grammar baidu.swf.getMovie(name)
  9372. * @param {string} name flash对象的名称
  9373. * @see baidu.swf.create
  9374. * @meta standard
  9375. * @returns {HTMLElement} flash对象的实例
  9376. */
  9377. baidu.swf.getMovie = function (name) {
  9378. //ie9下, Object标签和embed标签嵌套的方式生成flash时,
  9379. //会导致document[name]多返回一个Object元素,而起作用的只有embed标签
  9380. var movie = document[name], ret;
  9381. return baidu.browser.ie == 9 ?
  9382. movie && movie.length ?
  9383. (ret = baidu.array.remove(baidu.lang.toArray(movie),function(item){
  9384. return item.tagName.toLowerCase() != "embed";
  9385. })).length == 1 ? ret[0] : ret
  9386. : movie
  9387. : movie || window[name];
  9388. };
  9389. /*
  9390. * Tangram
  9391. * Copyright 2011 Baidu Inc. All rights reserved.
  9392. */
  9393. /**
  9394. * Js 调用 Flash方法的代理类.
  9395. * @function
  9396. * @name baidu.swf.Proxy
  9397. * @grammar new baidu.swf.Proxy(id, property, [, loadedHandler])
  9398. * @param {string} id Flash的元素id.object标签id, embed标签name.
  9399. * @param {string} property Flash的方法或者属性名称,用来检测Flash是否初始化好了.
  9400. * @param {Function} loadedHandler 初始化之后的回调函数.
  9401. * @remark Flash对应的DOM元素必须已经存在, 否则抛错. 可以使用baidu.swf.create预先创建Flash对应的DOM元素.
  9402. * @author xxxxxx@baidu.com (leeight)
  9403. */
  9404. baidu.swf.Proxy = function(id, property, loadedHandler) {
  9405. /**
  9406. * 页面上的Flash对象
  9407. * @type {HTMLElement}
  9408. */
  9409. var me = this,
  9410. flash = this._flash = baidu.swf.getMovie(id),
  9411. timer;
  9412. if (! property) {
  9413. return this;
  9414. }
  9415. timer = setInterval(function() {
  9416. try {
  9417. /** @preserveTry */
  9418. if (flash[property]) {
  9419. me._initialized = true;
  9420. clearInterval(timer);
  9421. if (loadedHandler) {
  9422. loadedHandler();
  9423. }
  9424. }
  9425. } catch (e) {
  9426. }
  9427. }, 100);
  9428. };
  9429. /**
  9430. * 获取flash对象.
  9431. * @return {HTMLElement} Flash对象.
  9432. */
  9433. baidu.swf.Proxy.prototype.getFlash = function() {
  9434. return this._flash;
  9435. };
  9436. /**
  9437. * 判断Flash是否初始化完成,可以与js进行交互.
  9438. */
  9439. baidu.swf.Proxy.prototype.isReady = function() {
  9440. return !! this._initialized;
  9441. };
  9442. /**
  9443. * 调用Flash中的某个方法
  9444. * @param {string} methodName 方法名.
  9445. * @param {...*} var_args 方法的参数.
  9446. */
  9447. baidu.swf.Proxy.prototype.call = function(methodName, var_args) {
  9448. try {
  9449. var flash = this.getFlash(),
  9450. args = Array.prototype.slice.call(arguments);
  9451. args.shift();
  9452. if (flash[methodName]) {
  9453. flash[methodName].apply(flash, args);
  9454. }
  9455. } catch (e) {
  9456. }
  9457. };
  9458. /*
  9459. * Tangram
  9460. * Copyright 2009 Baidu Inc. All rights reserved.
  9461. *
  9462. * path: baidu/url.js
  9463. * author: erik
  9464. * version: 1.1.0
  9465. * date: 2009/11/16
  9466. */
  9467. /**
  9468. * @namespace baidu.url 操作url的方法。
  9469. */
  9470. baidu.url = baidu.url || {};
  9471. /*
  9472. * Tangram
  9473. * Copyright 2009 Baidu Inc. All rights reserved.
  9474. *
  9475. * path: baidu/url/escapeSymbol.js
  9476. * author: erik
  9477. * version: 1.1.0
  9478. * date: 2009/11/16
  9479. */
  9480. /**
  9481. * 对字符串进行%&+/#=和空格七个字符进行url转义
  9482. * @name baidu.url.escapeSymbol
  9483. * @function
  9484. * @grammar baidu.url.escapeSymbol(source)
  9485. * @param {string} source 需要转义的字符串
  9486. * @return {string} 转义之后的字符串.
  9487. * @remark
  9488. * 用于get请求转义。在服务器只接受gbk,并且页面是gbk编码时,可以经过本转义后直接发get请求。
  9489. *
  9490. * @returns {string} 转义后的字符串
  9491. */
  9492. baidu.url.escapeSymbol = function (source) {
  9493. return String(source).replace(/\%/g, "%25")
  9494. .replace(/&/g, "%26")
  9495. .replace(/\+/g, "%2B")
  9496. .replace(/\ /g, "%20")
  9497. .replace(/\//g, "%2F")
  9498. .replace(/\#/g, "%23")
  9499. .replace(/\=/g, "%3D");
  9500. };
  9501. /*
  9502. * Tangram
  9503. * Copyright 2009 Baidu Inc. All rights reserved.
  9504. *
  9505. * path: baidu/url/getQueryValue.js
  9506. * author: erik
  9507. * version: 1.1.0
  9508. * date: 2009/11/16
  9509. */
  9510. /**
  9511. * 根据参数名从目标URL中获取参数值
  9512. * @name baidu.url.getQueryValue
  9513. * @function
  9514. * @grammar baidu.url.getQueryValue(url, key)
  9515. * @param {string} url 目标URL
  9516. * @param {string} key 要获取的参数名
  9517. * @meta standard
  9518. * @see baidu.url.jsonToQuery
  9519. *
  9520. * @returns {string|null} - 获取的参数值,其中URI编码后的字符不会被解码,获取不到时返回null
  9521. */
  9522. baidu.url.getQueryValue = function (url, key) {
  9523. var reg = new RegExp(
  9524. "(^|&|\\?|#)"
  9525. + baidu.string.escapeReg(key)
  9526. + "=([^&#]*)(&|\x24|#)",
  9527. "");
  9528. var match = url.match(reg);
  9529. if (match) {
  9530. return match[2];
  9531. }
  9532. return null;
  9533. };
  9534. /*
  9535. * Tangram
  9536. * Copyright 2009 Baidu Inc. All rights reserved.
  9537. *
  9538. * path: baidu/url/jsonToQuery.js
  9539. * author: erik
  9540. * version: 1.1.0
  9541. * date: 2009/11/16
  9542. */
  9543. /**
  9544. * 将json对象解析成query字符串
  9545. * @name baidu.url.jsonToQuery
  9546. * @function
  9547. * @grammar baidu.url.jsonToQuery(json[, replacer])
  9548. * @param {Object} json 需要解析的json对象
  9549. * @param {Function=} replacer_opt 对值进行特殊处理的函数,function (value, key)
  9550. * @see baidu.url.queryToJson,baidu.url.getQueryValue
  9551. *
  9552. * @return {string} - 解析结果字符串,其中值将被URI编码,{a:'&1 '} ==> "a=%261%20"。
  9553. */
  9554. baidu.url.jsonToQuery = function (json, replacer_opt) {
  9555. var result = [],
  9556. itemLen,
  9557. replacer = replacer_opt || function (value) {
  9558. return baidu.url.escapeSymbol(value);
  9559. };
  9560. baidu.object.each(json, function(item, key){
  9561. // 这里只考虑item为数组、字符串、数字类型,不考虑嵌套的object
  9562. if (baidu.lang.isArray(item)) {
  9563. itemLen = item.length;
  9564. // FIXME value的值需要encodeURIComponent转义吗?
  9565. while (itemLen--) {
  9566. result.push(key + '=' + replacer(item[itemLen], key));
  9567. }
  9568. } else {
  9569. result.push(key + '=' + replacer(item, key));
  9570. }
  9571. });
  9572. return result.join('&');
  9573. };
  9574. /*
  9575. * Tangram
  9576. * Copyright 2009 Baidu Inc. All rights reserved.
  9577. *
  9578. * path: baidu/url/queryToJson.js
  9579. * author: erik
  9580. * version: 1.1.0
  9581. * date: 2009/11/16
  9582. */
  9583. /**
  9584. * 解析目标URL中的参数成json对象
  9585. * @name baidu.url.queryToJson
  9586. * @function
  9587. * @grammar baidu.url.queryToJson(url)
  9588. * @param {string} url 目标URL
  9589. * @see baidu.url.jsonToQuery
  9590. *
  9591. * @returns {Object} - 解析为结果对象,其中URI编码后的字符不会被解码,'a=%20' ==> {a:'%20'}。
  9592. */
  9593. baidu.url.queryToJson = function (url) {
  9594. var query = url.substr(url.lastIndexOf('?') + 1),
  9595. params = query.split('&'),
  9596. len = params.length,
  9597. result = {},
  9598. i = 0,
  9599. key, value, item, param;
  9600. for (; i < len; i++) {
  9601. if(!params[i]){
  9602. continue;
  9603. }
  9604. param = params[i].split('=');
  9605. key = param[0];
  9606. value = param[1];
  9607. item = result[key];
  9608. if ('undefined' == typeof item) {
  9609. result[key] = value;
  9610. } else if (baidu.lang.isArray(item)) {
  9611. item.push(value);
  9612. } else { // 这里只可能是string了
  9613. result[key] = [item, value];
  9614. }
  9615. }
  9616. return result;
  9617. };
  9618. })();