mui.js 258 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390
  1. /*!
  2. * =====================================================
  3. * Mui v3.7.3 (http://dev.dcloud.net.cn/mui)
  4. * =====================================================
  5. */
  6. /**
  7. * MUI核心JS
  8. * @type _L4.$|Function
  9. */
  10. var mui = (function(document, undefined) {
  11. var readyRE = /complete|loaded|interactive/;
  12. var idSelectorRE = /^#([\w-]+)$/;
  13. var classSelectorRE = /^\.([\w-]+)$/;
  14. var tagSelectorRE = /^[\w-]+$/;
  15. var translateRE = /translate(?:3d)?\((.+?)\)/;
  16. var translateMatrixRE = /matrix(3d)?\((.+?)\)/;
  17. var $ = function(selector, context) {
  18. context = context || document;
  19. if (!selector)
  20. return wrap();
  21. if (typeof selector === 'object')
  22. if ($.isArrayLike(selector)) {
  23. return wrap($.slice.call(selector), null);
  24. } else {
  25. return wrap([selector], null);
  26. }
  27. if (typeof selector === 'function')
  28. return $.ready(selector);
  29. if (typeof selector === 'string') {
  30. try {
  31. selector = selector.trim();
  32. if (idSelectorRE.test(selector)) {
  33. var found = document.getElementById(RegExp.$1);
  34. return wrap(found ? [found] : []);
  35. }
  36. return wrap($.qsa(selector, context), selector);
  37. } catch (e) {}
  38. }
  39. return wrap();
  40. };
  41. var wrap = function(dom, selector) {
  42. dom = dom || [];
  43. Object.setPrototypeOf(dom, $.fn);
  44. dom.selector = selector || '';
  45. return dom;
  46. };
  47. $.uuid = 0;
  48. $.data = {};
  49. /**
  50. * extend(simple)
  51. * @param {type} target
  52. * @param {type} source
  53. * @param {type} deep
  54. * @returns {unresolved}
  55. */
  56. $.extend = function() { //from jquery2
  57. var options, name, src, copy, copyIsArray, clone,
  58. target = arguments[0] || {},
  59. i = 1,
  60. length = arguments.length,
  61. deep = false;
  62. if (typeof target === "boolean") {
  63. deep = target;
  64. target = arguments[i] || {};
  65. i++;
  66. }
  67. if (typeof target !== "object" && !$.isFunction(target)) {
  68. target = {};
  69. }
  70. if (i === length) {
  71. target = this;
  72. i--;
  73. }
  74. for (; i < length; i++) {
  75. if ((options = arguments[i]) != null) {
  76. for (name in options) {
  77. src = target[name];
  78. copy = options[name];
  79. if (target === copy) {
  80. continue;
  81. }
  82. if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {
  83. if (copyIsArray) {
  84. copyIsArray = false;
  85. clone = src && $.isArray(src) ? src : [];
  86. } else {
  87. clone = src && $.isPlainObject(src) ? src : {};
  88. }
  89. target[name] = $.extend(deep, clone, copy);
  90. } else if (copy !== undefined) {
  91. target[name] = copy;
  92. }
  93. }
  94. }
  95. }
  96. return target;
  97. };
  98. /**
  99. * mui noop(function)
  100. */
  101. $.noop = function() {};
  102. /**
  103. * mui slice(array)
  104. */
  105. $.slice = [].slice;
  106. /**
  107. * mui filter(array)
  108. */
  109. $.filter = [].filter;
  110. $.type = function(obj) {
  111. return obj == null ? String(obj) : class2type[{}.toString.call(obj)] || "object";
  112. };
  113. /**
  114. * mui isArray
  115. */
  116. $.isArray = Array.isArray ||
  117. function(object) {
  118. return object instanceof Array;
  119. };
  120. /**
  121. * mui isArrayLike
  122. * @param {Object} obj
  123. */
  124. $.isArrayLike = function(obj) {
  125. var length = !!obj && "length" in obj && obj.length;
  126. var type = $.type(obj);
  127. if (type === "function" || $.isWindow(obj)) {
  128. return false;
  129. }
  130. return type === "array" || length === 0 ||
  131. typeof length === "number" && length > 0 && (length - 1) in obj;
  132. };
  133. /**
  134. * mui isWindow(需考虑obj为undefined的情况)
  135. */
  136. $.isWindow = function(obj) {
  137. return obj != null && obj === obj.window;
  138. };
  139. /**
  140. * mui isObject
  141. */
  142. $.isObject = function(obj) {
  143. return $.type(obj) === "object";
  144. };
  145. /**
  146. * mui isPlainObject
  147. */
  148. $.isPlainObject = function(obj) {
  149. return $.isObject(obj) && !$.isWindow(obj) && Object.getPrototypeOf(obj) === Object.prototype;
  150. };
  151. /**
  152. * mui isEmptyObject
  153. * @param {Object} o
  154. */
  155. $.isEmptyObject = function(o) {
  156. for (var p in o) {
  157. if (p !== undefined) {
  158. return false;
  159. }
  160. }
  161. return true;
  162. };
  163. /**
  164. * mui isFunction
  165. */
  166. $.isFunction = function(value) {
  167. return $.type(value) === "function";
  168. };
  169. /**
  170. * mui querySelectorAll
  171. * @param {type} selector
  172. * @param {type} context
  173. * @returns {Array}
  174. */
  175. $.qsa = function(selector, context) {
  176. context = context || document;
  177. return $.slice.call(classSelectorRE.test(selector) ? context.getElementsByClassName(RegExp.$1) : tagSelectorRE.test(selector) ? context.getElementsByTagName(selector) : context.querySelectorAll(selector));
  178. };
  179. /**
  180. * ready(DOMContentLoaded)
  181. * @param {type} callback
  182. * @returns {_L6.$}
  183. */
  184. $.ready = function(callback) {
  185. if (readyRE.test(document.readyState)) {
  186. callback($);
  187. } else {
  188. document.addEventListener('DOMContentLoaded', function() {
  189. callback($);
  190. }, false);
  191. }
  192. return this;
  193. };
  194. /**
  195. * 将 fn 缓存一段时间后, 再被调用执行
  196. * 此方法为了避免在 ms 段时间内, 执行 fn 多次. 常用于 resize , scroll , mousemove 等连续性事件中;
  197. * 当 ms 设置为 -1, 表示立即执行 fn, 即和直接调用 fn 一样;
  198. * 调用返回函数的 stop 停止最后一次的 buffer 效果
  199. * @param {Object} fn
  200. * @param {Object} ms
  201. * @param {Object} context
  202. */
  203. $.buffer = function(fn, ms, context) {
  204. var timer;
  205. var lastStart = 0;
  206. var lastEnd = 0;
  207. var ms = ms || 150;
  208. function run() {
  209. if (timer) {
  210. timer.cancel();
  211. timer = 0;
  212. }
  213. lastStart = $.now();
  214. fn.apply(context || this, arguments);
  215. lastEnd = $.now();
  216. }
  217. return $.extend(function() {
  218. if (
  219. (!lastStart) || // 从未运行过
  220. (lastEnd >= lastStart && $.now() - lastEnd > ms) || // 上次运行成功后已经超过ms毫秒
  221. (lastEnd < lastStart && $.now() - lastStart > ms * 8) // 上次运行或未完成,后8*ms毫秒
  222. ) {
  223. run.apply(this, arguments);
  224. } else {
  225. if (timer) {
  226. timer.cancel();
  227. }
  228. timer = $.later(run, ms, null, $.slice.call(arguments));
  229. }
  230. }, {
  231. stop: function() {
  232. if (timer) {
  233. timer.cancel();
  234. timer = 0;
  235. }
  236. }
  237. });
  238. };
  239. /**
  240. * each
  241. * @param {type} elements
  242. * @param {type} callback
  243. * @returns {_L8.$}
  244. */
  245. $.each = function(elements, callback, hasOwnProperty) {
  246. if (!elements) {
  247. return this;
  248. }
  249. if (typeof elements.length === 'number') {
  250. [].every.call(elements, function(el, idx) {
  251. return callback.call(el, idx, el) !== false;
  252. });
  253. } else {
  254. for (var key in elements) {
  255. if (hasOwnProperty) {
  256. if (elements.hasOwnProperty(key)) {
  257. if (callback.call(elements[key], key, elements[key]) === false) return elements;
  258. }
  259. } else {
  260. if (callback.call(elements[key], key, elements[key]) === false) return elements;
  261. }
  262. }
  263. }
  264. return this;
  265. };
  266. $.focus = function(element) {
  267. if ($.os.ios) {
  268. setTimeout(function() {
  269. element.focus();
  270. }, 10);
  271. } else {
  272. element.focus();
  273. }
  274. };
  275. /**
  276. * trigger event
  277. * @param {type} element
  278. * @param {type} eventType
  279. * @param {type} eventData
  280. * @returns {_L8.$}
  281. */
  282. $.trigger = function(element, eventType, eventData) {
  283. element.dispatchEvent(new CustomEvent(eventType, {
  284. detail: eventData,
  285. bubbles: true,
  286. cancelable: true
  287. }));
  288. return this;
  289. };
  290. /**
  291. * getStyles
  292. * @param {type} element
  293. * @param {type} property
  294. * @returns {styles}
  295. */
  296. $.getStyles = function(element, property) {
  297. var styles = element.ownerDocument.defaultView.getComputedStyle(element, null);
  298. if (property) {
  299. return styles.getPropertyValue(property) || styles[property];
  300. }
  301. return styles;
  302. };
  303. /**
  304. * parseTranslate
  305. * @param {type} translateString
  306. * @param {type} position
  307. * @returns {Object}
  308. */
  309. $.parseTranslate = function(translateString, position) {
  310. var result = translateString.match(translateRE || '');
  311. if (!result || !result[1]) {
  312. result = ['', '0,0,0'];
  313. }
  314. result = result[1].split(",");
  315. result = {
  316. x: parseFloat(result[0]),
  317. y: parseFloat(result[1]),
  318. z: parseFloat(result[2])
  319. };
  320. if (position && result.hasOwnProperty(position)) {
  321. return result[position];
  322. }
  323. return result;
  324. };
  325. /**
  326. * parseTranslateMatrix
  327. * @param {type} translateString
  328. * @param {type} position
  329. * @returns {Object}
  330. */
  331. $.parseTranslateMatrix = function(translateString, position) {
  332. var matrix = translateString.match(translateMatrixRE);
  333. var is3D = matrix && matrix[1];
  334. if (matrix) {
  335. matrix = matrix[2].split(",");
  336. if (is3D === "3d")
  337. matrix = matrix.slice(12, 15);
  338. else {
  339. matrix.push(0);
  340. matrix = matrix.slice(4, 7);
  341. }
  342. } else {
  343. matrix = [0, 0, 0];
  344. }
  345. var result = {
  346. x: parseFloat(matrix[0]),
  347. y: parseFloat(matrix[1]),
  348. z: parseFloat(matrix[2])
  349. };
  350. if (position && result.hasOwnProperty(position)) {
  351. return result[position];
  352. }
  353. return result;
  354. };
  355. $.hooks = {};
  356. $.addAction = function(type, hook) {
  357. var hooks = $.hooks[type];
  358. if (!hooks) {
  359. hooks = [];
  360. }
  361. hook.index = hook.index || 1000;
  362. hooks.push(hook);
  363. hooks.sort(function(a, b) {
  364. return a.index - b.index;
  365. });
  366. $.hooks[type] = hooks;
  367. return $.hooks[type];
  368. };
  369. $.doAction = function(type, callback) {
  370. if ($.isFunction(callback)) { //指定了callback
  371. $.each($.hooks[type], callback);
  372. } else { //未指定callback,直接执行
  373. $.each($.hooks[type], function(index, hook) {
  374. return !hook.handle();
  375. });
  376. }
  377. };
  378. /**
  379. * setTimeout封装
  380. * @param {Object} fn
  381. * @param {Object} when
  382. * @param {Object} context
  383. * @param {Object} data
  384. */
  385. $.later = function(fn, when, context, data) {
  386. when = when || 0;
  387. var m = fn;
  388. var d = data;
  389. var f;
  390. var r;
  391. if (typeof fn === 'string') {
  392. m = context[fn];
  393. }
  394. f = function() {
  395. m.apply(context, $.isArray(d) ? d : [d]);
  396. };
  397. r = setTimeout(f, when);
  398. return {
  399. id: r,
  400. cancel: function() {
  401. clearTimeout(r);
  402. }
  403. };
  404. };
  405. $.now = Date.now || function() {
  406. return +new Date();
  407. };
  408. var class2type = {};
  409. $.each(['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'], function(i, name) {
  410. class2type["[object " + name + "]"] = name.toLowerCase();
  411. });
  412. if (window.JSON) {
  413. $.parseJSON = JSON.parse;
  414. }
  415. /**
  416. * $.fn
  417. */
  418. $.fn = {
  419. each: function(callback) {
  420. [].every.call(this, function(el, idx) {
  421. return callback.call(el, idx, el) !== false;
  422. });
  423. return this;
  424. }
  425. };
  426. /**
  427. * 兼容 AMD 模块
  428. **/
  429. if (typeof define === 'function' && define.amd) {
  430. define('mui', [], function() {
  431. return $;
  432. });
  433. }
  434. return $;
  435. })(document);
  436. //window.mui = mui;
  437. //'$' in window || (window.$ = mui);
  438. /**
  439. * $.os
  440. * @param {type} $
  441. * @returns {undefined}
  442. */
  443. (function($, window) {
  444. function detect(ua) {
  445. this.os = {};
  446. var funcs = [
  447. function() { //wechat
  448. var wechat = ua.match(/(MicroMessenger)\/([\d\.]+)/i);
  449. if (wechat) { //wechat
  450. this.os.wechat = {
  451. version: wechat[2].replace(/_/g, '.')
  452. };
  453. }
  454. return false;
  455. },
  456. function() { //android
  457. var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
  458. if (android) {
  459. this.os.android = true;
  460. this.os.version = android[2];
  461. this.os.isBadAndroid = !(/Chrome\/\d/.test(window.navigator.appVersion));
  462. }
  463. return this.os.android === true;
  464. },
  465. function() { //ios
  466. var iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/);
  467. if (iphone) { //iphone
  468. this.os.ios = this.os.iphone = true;
  469. this.os.version = iphone[2].replace(/_/g, '.');
  470. } else {
  471. var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
  472. if (ipad) { //ipad
  473. this.os.ios = this.os.ipad = true;
  474. this.os.version = ipad[2].replace(/_/g, '.');
  475. }
  476. }
  477. return this.os.ios === true;
  478. }
  479. ];
  480. [].every.call(funcs, function(func) {
  481. return !func.call($);
  482. });
  483. }
  484. detect.call($, navigator.userAgent);
  485. })(mui, window);
  486. /**
  487. * $.os.plus
  488. * @param {type} $
  489. * @returns {undefined}
  490. */
  491. (function($, document) {
  492. function detect(ua) {
  493. this.os = this.os || {};
  494. var plus = ua.match(/Html5Plus/i); //TODO 5\+Browser?
  495. if (plus) {
  496. this.os.plus = true;
  497. $(function() {
  498. document.body.classList.add('mui-plus');
  499. });
  500. if (ua.match(/StreamApp/i)) { //TODO 最好有流应用自己的标识
  501. this.os.stream = true;
  502. $(function() {
  503. document.body.classList.add('mui-plus-stream');
  504. });
  505. }
  506. }
  507. }
  508. detect.call($, navigator.userAgent);
  509. })(mui, document);
  510. /**
  511. * 仅提供简单的on,off(仅支持事件委托,不支持当前元素绑定,当前元素绑定请直接使用addEventListener,removeEventListener)
  512. * @param {Object} $
  513. */
  514. (function($) {
  515. if ('ontouchstart' in window) {
  516. $.isTouchable = true;
  517. $.EVENT_START = 'touchstart';
  518. $.EVENT_MOVE = 'touchmove';
  519. $.EVENT_END = 'touchend';
  520. } else {
  521. $.isTouchable = false;
  522. $.EVENT_START = 'mousedown';
  523. $.EVENT_MOVE = 'mousemove';
  524. $.EVENT_END = 'mouseup';
  525. }
  526. $.EVENT_CANCEL = 'touchcancel';
  527. $.EVENT_CLICK = 'click';
  528. var _mid = 1;
  529. var delegates = {};
  530. //需要wrap的函数
  531. var eventMethods = {
  532. preventDefault: 'isDefaultPrevented',
  533. stopImmediatePropagation: 'isImmediatePropagationStopped',
  534. stopPropagation: 'isPropagationStopped'
  535. };
  536. //默认true返回函数
  537. var returnTrue = function() {
  538. return true
  539. };
  540. //默认false返回函数
  541. var returnFalse = function() {
  542. return false
  543. };
  544. //wrap浏览器事件
  545. var compatible = function(event, target) {
  546. if (!event.detail) {
  547. event.detail = {
  548. currentTarget: target
  549. };
  550. } else {
  551. event.detail.currentTarget = target;
  552. }
  553. $.each(eventMethods, function(name, predicate) {
  554. var sourceMethod = event[name];
  555. event[name] = function() {
  556. this[predicate] = returnTrue;
  557. return sourceMethod && sourceMethod.apply(event, arguments)
  558. }
  559. event[predicate] = returnFalse;
  560. }, true);
  561. return event;
  562. };
  563. //简单的wrap对象_mid
  564. var mid = function(obj) {
  565. return obj && (obj._mid || (obj._mid = _mid++));
  566. };
  567. //事件委托对象绑定的事件回调列表
  568. var delegateFns = {};
  569. //返回事件委托的wrap事件回调
  570. var delegateFn = function(element, event, selector, callback) {
  571. return function(e) {
  572. //same event
  573. var callbackObjs = delegates[element._mid][event];
  574. var handlerQueue = [];
  575. var target = e.target;
  576. var selectorAlls = {};
  577. for (; target && target !== document; target = target.parentNode) {
  578. if (target === element) {
  579. break;
  580. }
  581. if (~['click', 'tap', 'doubletap', 'longtap', 'hold'].indexOf(event) && (target.disabled || target.classList.contains('mui-disabled'))) {
  582. break;
  583. }
  584. var matches = {};
  585. $.each(callbackObjs, function(selector, callbacks) { //same selector
  586. selectorAlls[selector] || (selectorAlls[selector] = $.qsa(selector, element));
  587. if (selectorAlls[selector] && ~(selectorAlls[selector]).indexOf(target)) {
  588. if (!matches[selector]) {
  589. matches[selector] = callbacks;
  590. }
  591. }
  592. }, true);
  593. if (!$.isEmptyObject(matches)) {
  594. handlerQueue.push({
  595. element: target,
  596. handlers: matches
  597. });
  598. }
  599. }
  600. selectorAlls = null;
  601. e = compatible(e); //compatible event
  602. $.each(handlerQueue, function(index, handler) {
  603. target = handler.element;
  604. var tagName = target.tagName;
  605. if (event === 'tap' && (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && tagName !== 'SELECT')) {
  606. e.preventDefault();
  607. e.detail && e.detail.gesture && e.detail.gesture.preventDefault();
  608. }
  609. $.each(handler.handlers, function(index, handler) {
  610. $.each(handler, function(index, callback) {
  611. if (callback.call(target, e) === false) {
  612. e.preventDefault();
  613. e.stopPropagation();
  614. }
  615. }, true);
  616. }, true)
  617. if (e.isPropagationStopped()) {
  618. return false;
  619. }
  620. }, true);
  621. };
  622. };
  623. var findDelegateFn = function(element, event) {
  624. var delegateCallbacks = delegateFns[mid(element)];
  625. var result = [];
  626. if (delegateCallbacks) {
  627. result = [];
  628. if (event) {
  629. var filterFn = function(fn) {
  630. return fn.type === event;
  631. }
  632. return delegateCallbacks.filter(filterFn);
  633. } else {
  634. result = delegateCallbacks;
  635. }
  636. }
  637. return result;
  638. };
  639. var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
  640. /**
  641. * mui delegate events
  642. * @param {type} event
  643. * @param {type} selector
  644. * @param {type} callback
  645. * @returns {undefined}
  646. */
  647. $.fn.on = function(event, selector, callback) { //仅支持简单的事件委托,主要是tap事件使用,类似mouse,focus之类暂不封装支持
  648. return this.each(function() {
  649. var element = this;
  650. mid(element);
  651. mid(callback);
  652. var isAddEventListener = false;
  653. var delegateEvents = delegates[element._mid] || (delegates[element._mid] = {});
  654. var delegateCallbackObjs = delegateEvents[event] || ((delegateEvents[event] = {}));
  655. if ($.isEmptyObject(delegateCallbackObjs)) {
  656. isAddEventListener = true;
  657. }
  658. var delegateCallbacks = delegateCallbackObjs[selector] || (delegateCallbackObjs[selector] = []);
  659. delegateCallbacks.push(callback);
  660. if (isAddEventListener) {
  661. var delegateFnArray = delegateFns[mid(element)];
  662. if (!delegateFnArray) {
  663. delegateFnArray = [];
  664. }
  665. var delegateCallback = delegateFn(element, event, selector, callback);
  666. delegateFnArray.push(delegateCallback);
  667. delegateCallback.i = delegateFnArray.length - 1;
  668. delegateCallback.type = event;
  669. delegateFns[mid(element)] = delegateFnArray;
  670. element.addEventListener(event, delegateCallback);
  671. if (event === 'tap') { //TODO 需要找个更好的解决方案
  672. element.addEventListener('click', function(e) {
  673. if (e.target) {
  674. var tagName = e.target.tagName;
  675. if (!preventDefaultException.test(tagName)) {
  676. if (tagName === 'A') {
  677. var href = e.target.href;
  678. if (!(href && ~href.indexOf('tel:'))) {
  679. e.preventDefault();
  680. }
  681. } else {
  682. e.preventDefault();
  683. }
  684. }
  685. }
  686. });
  687. }
  688. }
  689. });
  690. };
  691. $.fn.off = function(event, selector, callback) {
  692. return this.each(function() {
  693. var _mid = mid(this);
  694. if (!event) { //mui(selector).off();
  695. delegates[_mid] && delete delegates[_mid];
  696. } else if (!selector) { //mui(selector).off(event);
  697. delegates[_mid] && delete delegates[_mid][event];
  698. } else if (!callback) { //mui(selector).off(event,selector);
  699. delegates[_mid] && delegates[_mid][event] && delete delegates[_mid][event][selector];
  700. } else { //mui(selector).off(event,selector,callback);
  701. var delegateCallbacks = delegates[_mid] && delegates[_mid][event] && delegates[_mid][event][selector];
  702. $.each(delegateCallbacks, function(index, delegateCallback) {
  703. if (mid(delegateCallback) === mid(callback)) {
  704. delegateCallbacks.splice(index, 1);
  705. return false;
  706. }
  707. }, true);
  708. }
  709. if (delegates[_mid]) {
  710. //如果off掉了所有当前element的指定的event事件,则remove掉当前element的delegate回调
  711. if ((!delegates[_mid][event] || $.isEmptyObject(delegates[_mid][event]))) {
  712. findDelegateFn(this, event).forEach(function(fn) {
  713. this.removeEventListener(fn.type, fn);
  714. delete delegateFns[_mid][fn.i];
  715. }.bind(this));
  716. }
  717. } else {
  718. //如果delegates[_mid]已不存在,删除所有
  719. findDelegateFn(this).forEach(function(fn) {
  720. this.removeEventListener(fn.type, fn);
  721. delete delegateFns[_mid][fn.i];
  722. }.bind(this));
  723. }
  724. });
  725. };
  726. })(mui);
  727. /**
  728. * mui target(action>popover>modal>tab>toggle)
  729. */
  730. (function($, window, document) {
  731. /**
  732. * targets
  733. */
  734. $.targets = {};
  735. /**
  736. * target handles
  737. */
  738. $.targetHandles = [];
  739. /**
  740. * register target
  741. * @param {type} target
  742. * @returns {$.targets}
  743. */
  744. $.registerTarget = function(target) {
  745. target.index = target.index || 1000;
  746. $.targetHandles.push(target);
  747. $.targetHandles.sort(function(a, b) {
  748. return a.index - b.index;
  749. });
  750. return $.targetHandles;
  751. };
  752. window.addEventListener($.EVENT_START, function(event) {
  753. var target = event.target;
  754. var founds = {};
  755. for (; target && target !== document; target = target.parentNode) {
  756. var isFound = false;
  757. $.each($.targetHandles, function(index, targetHandle) {
  758. var name = targetHandle.name;
  759. if (!isFound && !founds[name] && targetHandle.hasOwnProperty('handle')) {
  760. $.targets[name] = targetHandle.handle(event, target);
  761. if ($.targets[name]) {
  762. founds[name] = true;
  763. if (targetHandle.isContinue !== true) {
  764. isFound = true;
  765. }
  766. }
  767. } else {
  768. if (!founds[name]) {
  769. if (targetHandle.isReset !== false)
  770. $.targets[name] = false;
  771. }
  772. }
  773. });
  774. if (isFound) {
  775. break;
  776. }
  777. }
  778. });
  779. window.addEventListener('click', function(event) { //解决touch与click的target不一致的问题(比如链接边缘点击时,touch的target为html,而click的target为A)
  780. var target = event.target;
  781. var isFound = false;
  782. for (; target && target !== document; target = target.parentNode) {
  783. if (target.tagName === 'A') {
  784. $.each($.targetHandles, function(index, targetHandle) {
  785. var name = targetHandle.name;
  786. if (targetHandle.hasOwnProperty('handle')) {
  787. if (targetHandle.handle(event, target)) {
  788. isFound = true;
  789. event.preventDefault();
  790. return false;
  791. }
  792. }
  793. });
  794. if (isFound) {
  795. break;
  796. }
  797. }
  798. }
  799. });
  800. })(mui, window, document);
  801. /**
  802. * fixed trim
  803. * @param {type} undefined
  804. * @returns {undefined}
  805. */
  806. (function(undefined) {
  807. if (String.prototype.trim === undefined) { // fix for iOS 3.2
  808. String.prototype.trim = function() {
  809. return this.replace(/^\s+|\s+$/g, '');
  810. };
  811. }
  812. Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {
  813. obj['__proto__'] = proto;
  814. return obj;
  815. };
  816. })();
  817. /**
  818. * fixed CustomEvent
  819. */
  820. (function() {
  821. if (typeof window.CustomEvent === 'undefined') {
  822. function CustomEvent(event, params) {
  823. params = params || {
  824. bubbles: false,
  825. cancelable: false,
  826. detail: undefined
  827. };
  828. var evt = document.createEvent('Events');
  829. var bubbles = true;
  830. for (var name in params) {
  831. (name === 'bubbles') ? (bubbles = !!params[name]) : (evt[name] = params[name]);
  832. }
  833. evt.initEvent(event, bubbles, true);
  834. return evt;
  835. };
  836. CustomEvent.prototype = window.Event.prototype;
  837. window.CustomEvent = CustomEvent;
  838. }
  839. })();
  840. /*
  841. A shim for non ES5 supporting browsers.
  842. Adds function bind to Function prototype, so that you can do partial application.
  843. Works even with the nasty thing, where the first word is the opposite of extranet, the second one is the profession of Columbus, and the version number is 9, flipped 180 degrees.
  844. */
  845. Function.prototype.bind = Function.prototype.bind || function(to) {
  846. // Make an array of our arguments, starting from second argument
  847. var partial = Array.prototype.splice.call(arguments, 1),
  848. // We'll need the original function.
  849. fn = this;
  850. var bound = function() {
  851. // Join the already applied arguments to the now called ones (after converting to an array again).
  852. var args = partial.concat(Array.prototype.splice.call(arguments, 0));
  853. // If not being called as a constructor
  854. if (!(this instanceof bound)) {
  855. // return the result of the function called bound to target and partially applied.
  856. return fn.apply(to, args);
  857. }
  858. // If being called as a constructor, apply the function bound to self.
  859. fn.apply(this, args);
  860. }
  861. // Attach the prototype of the function to our newly created function.
  862. bound.prototype = fn.prototype;
  863. return bound;
  864. };
  865. /**
  866. * mui fixed classList
  867. * @param {type} document
  868. * @returns {undefined}
  869. */
  870. (function(document) {
  871. if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {
  872. Object.defineProperty(HTMLElement.prototype, 'classList', {
  873. get: function() {
  874. var self = this;
  875. function update(fn) {
  876. return function(value) {
  877. var classes = self.className.split(/\s+/),
  878. index = classes.indexOf(value);
  879. fn(classes, index, value);
  880. self.className = classes.join(" ");
  881. };
  882. }
  883. var ret = {
  884. add: update(function(classes, index, value) {
  885. ~index || classes.push(value);
  886. }),
  887. remove: update(function(classes, index) {
  888. ~index && classes.splice(index, 1);
  889. }),
  890. toggle: update(function(classes, index, value) {
  891. ~index ? classes.splice(index, 1) : classes.push(value);
  892. }),
  893. contains: function(value) {
  894. return !!~self.className.split(/\s+/).indexOf(value);
  895. },
  896. item: function(i) {
  897. return self.className.split(/\s+/)[i] || null;
  898. }
  899. };
  900. Object.defineProperty(ret, 'length', {
  901. get: function() {
  902. return self.className.split(/\s+/).length;
  903. }
  904. });
  905. return ret;
  906. }
  907. });
  908. }
  909. })(document);
  910. /**
  911. * mui fixed requestAnimationFrame
  912. * @param {type} window
  913. * @returns {undefined}
  914. */
  915. (function(window) {
  916. if (!window.requestAnimationFrame) {
  917. var lastTime = 0;
  918. window.requestAnimationFrame = window.webkitRequestAnimationFrame || function(callback, element) {
  919. var currTime = new Date().getTime();
  920. var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
  921. var id = window.setTimeout(function() {
  922. callback(currTime + timeToCall);
  923. }, timeToCall);
  924. lastTime = currTime + timeToCall;
  925. return id;
  926. };
  927. window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || function(id) {
  928. clearTimeout(id);
  929. };
  930. };
  931. }(window));
  932. /**
  933. * fastclick(only for radio,checkbox)
  934. */
  935. (function($, window, name) {
  936. if (!$.os.android && !$.os.ios) { //目前仅识别android和ios
  937. return;
  938. }
  939. if (window.FastClick) {
  940. return;
  941. }
  942. var handle = function(event, target) {
  943. if (target.tagName === 'LABEL') {
  944. if (target.parentNode) {
  945. target = target.parentNode.querySelector('input');
  946. }
  947. }
  948. if (target && (target.type === 'radio' || target.type === 'checkbox')) {
  949. if (!target.disabled) { //disabled
  950. return target;
  951. }
  952. }
  953. return false;
  954. };
  955. $.registerTarget({
  956. name: name,
  957. index: 40,
  958. handle: handle,
  959. target: false
  960. });
  961. var dispatchEvent = function(event) {
  962. var targetElement = $.targets.click;
  963. if (targetElement) {
  964. var clickEvent, touch;
  965. // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect
  966. if (document.activeElement && document.activeElement !== targetElement) {
  967. document.activeElement.blur();
  968. }
  969. touch = event.detail.gesture.changedTouches[0];
  970. // Synthesise a click event, with an extra attribute so it can be tracked
  971. clickEvent = document.createEvent('MouseEvents');
  972. clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
  973. clickEvent.forwardedTouchEvent = true;
  974. targetElement.dispatchEvent(clickEvent);
  975. event.detail && event.detail.gesture.preventDefault();
  976. }
  977. };
  978. window.addEventListener('tap', dispatchEvent);
  979. window.addEventListener('doubletap', dispatchEvent);
  980. //捕获
  981. window.addEventListener('click', function(event) {
  982. if ($.targets.click) {
  983. if (!event.forwardedTouchEvent) { //stop click
  984. if (event.stopImmediatePropagation) {
  985. event.stopImmediatePropagation();
  986. } else {
  987. // Part of the hack for browsers that don't support Event#stopImmediatePropagation
  988. event.propagationStopped = true;
  989. }
  990. event.stopPropagation();
  991. event.preventDefault();
  992. return false;
  993. }
  994. }
  995. }, true);
  996. })(mui, window, 'click');
  997. (function($, document) {
  998. $(function() {
  999. if (!$.os.ios) {
  1000. return;
  1001. }
  1002. var CLASS_FOCUSIN = 'mui-focusin';
  1003. var CLASS_BAR_TAB = 'mui-bar-tab';
  1004. var CLASS_BAR_FOOTER = 'mui-bar-footer';
  1005. var CLASS_BAR_FOOTER_SECONDARY = 'mui-bar-footer-secondary';
  1006. var CLASS_BAR_FOOTER_SECONDARY_TAB = 'mui-bar-footer-secondary-tab';
  1007. // var content = document.querySelector('.' + CLASS_CONTENT);
  1008. // if (content) {
  1009. // document.body.insertBefore(content, document.body.firstElementChild);
  1010. // }
  1011. document.addEventListener('focusin', function(e) {
  1012. if ($.os.plus) { //在父webview里边不fix
  1013. if (window.plus) {
  1014. if (plus.webview.currentWebview().children().length > 0) {
  1015. return;
  1016. }
  1017. }
  1018. }
  1019. var target = e.target;
  1020. //TODO 需考虑所有键盘弹起的情况
  1021. if (target.tagName && (target.tagName === 'TEXTAREA' || (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'search' || target.type === 'number')))) {
  1022. if (target.disabled || target.readOnly) {
  1023. return;
  1024. }
  1025. document.body.classList.add(CLASS_FOCUSIN);
  1026. var isFooter = false;
  1027. for (; target && target !== document; target = target.parentNode) {
  1028. var classList = target.classList;
  1029. if (classList && classList.contains(CLASS_BAR_TAB) || classList.contains(CLASS_BAR_FOOTER) || classList.contains(CLASS_BAR_FOOTER_SECONDARY) || classList.contains(CLASS_BAR_FOOTER_SECONDARY_TAB)) {
  1030. isFooter = true;
  1031. break;
  1032. }
  1033. }
  1034. if (isFooter) {
  1035. var scrollTop = document.body.scrollHeight;
  1036. var scrollLeft = document.body.scrollLeft;
  1037. setTimeout(function() {
  1038. window.scrollTo(scrollLeft, scrollTop);
  1039. }, 20);
  1040. }
  1041. }
  1042. });
  1043. document.addEventListener('focusout', function(e) {
  1044. var classList = document.body.classList;
  1045. if (classList.contains(CLASS_FOCUSIN)) {
  1046. classList.remove(CLASS_FOCUSIN);
  1047. setTimeout(function() {
  1048. window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
  1049. }, 20);
  1050. }
  1051. });
  1052. });
  1053. })(mui, document);
  1054. /**
  1055. * mui namespace(optimization)
  1056. * @param {type} $
  1057. * @returns {undefined}
  1058. */
  1059. (function($) {
  1060. $.namespace = 'mui';
  1061. $.classNamePrefix = $.namespace + '-';
  1062. $.classSelectorPrefix = '.' + $.classNamePrefix;
  1063. /**
  1064. * 返回正确的className
  1065. * @param {type} className
  1066. * @returns {String}
  1067. */
  1068. $.className = function(className) {
  1069. return $.classNamePrefix + className;
  1070. };
  1071. /**
  1072. * 返回正确的classSelector
  1073. * @param {type} classSelector
  1074. * @returns {String}
  1075. */
  1076. $.classSelector = function(classSelector) {
  1077. return classSelector.replace(/\./g, $.classSelectorPrefix);
  1078. };
  1079. /**
  1080. * 返回正确的eventName
  1081. * @param {type} event
  1082. * @param {type} module
  1083. * @returns {String}
  1084. */
  1085. $.eventName = function(event, module) {
  1086. return event + ($.namespace ? ('.' + $.namespace) : '') + ( module ? ('.' + module) : '');
  1087. };
  1088. })(mui);
  1089. /**
  1090. * mui gestures
  1091. * @param {type} $
  1092. * @param {type} window
  1093. * @returns {undefined}
  1094. */
  1095. (function($, window) {
  1096. $.gestures = {
  1097. session: {}
  1098. };
  1099. /**
  1100. * Gesture preventDefault
  1101. * @param {type} e
  1102. * @returns {undefined}
  1103. */
  1104. $.preventDefault = function(e) {
  1105. e.preventDefault();
  1106. };
  1107. /**
  1108. * Gesture stopPropagation
  1109. * @param {type} e
  1110. * @returns {undefined}
  1111. */
  1112. $.stopPropagation = function(e) {
  1113. e.stopPropagation();
  1114. };
  1115. /**
  1116. * register gesture
  1117. * @param {type} gesture
  1118. * @returns {$.gestures}
  1119. */
  1120. $.addGesture = function(gesture) {
  1121. return $.addAction('gestures', gesture);
  1122. };
  1123. var round = Math.round;
  1124. var abs = Math.abs;
  1125. var sqrt = Math.sqrt;
  1126. var atan = Math.atan;
  1127. var atan2 = Math.atan2;
  1128. /**
  1129. * distance
  1130. * @param {type} p1
  1131. * @param {type} p2
  1132. * @returns {Number}
  1133. */
  1134. var getDistance = function(p1, p2, props) {
  1135. if(!props) {
  1136. props = ['x', 'y'];
  1137. }
  1138. var x = p2[props[0]] - p1[props[0]];
  1139. var y = p2[props[1]] - p1[props[1]];
  1140. return sqrt((x * x) + (y * y));
  1141. };
  1142. /**
  1143. * scale
  1144. * @param {Object} starts
  1145. * @param {Object} moves
  1146. */
  1147. var getScale = function(starts, moves) {
  1148. if(starts.length >= 2 && moves.length >= 2) {
  1149. var props = ['pageX', 'pageY'];
  1150. return getDistance(moves[1], moves[0], props) / getDistance(starts[1], starts[0], props);
  1151. }
  1152. return 1;
  1153. };
  1154. /**
  1155. * angle
  1156. * @param {type} p1
  1157. * @param {type} p2
  1158. * @returns {Number}
  1159. */
  1160. var getAngle = function(p1, p2, props) {
  1161. if(!props) {
  1162. props = ['x', 'y'];
  1163. }
  1164. var x = p2[props[0]] - p1[props[0]];
  1165. var y = p2[props[1]] - p1[props[1]];
  1166. return atan2(y, x) * 180 / Math.PI;
  1167. };
  1168. /**
  1169. * direction
  1170. * @param {Object} x
  1171. * @param {Object} y
  1172. */
  1173. var getDirection = function(x, y) {
  1174. if(x === y) {
  1175. return '';
  1176. }
  1177. if(abs(x) >= abs(y)) {
  1178. return x > 0 ? 'left' : 'right';
  1179. }
  1180. return y > 0 ? 'up' : 'down';
  1181. };
  1182. /**
  1183. * rotation
  1184. * @param {Object} start
  1185. * @param {Object} end
  1186. */
  1187. var getRotation = function(start, end) {
  1188. var props = ['pageX', 'pageY'];
  1189. return getAngle(end[1], end[0], props) - getAngle(start[1], start[0], props);
  1190. };
  1191. /**
  1192. * px per ms
  1193. * @param {Object} deltaTime
  1194. * @param {Object} x
  1195. * @param {Object} y
  1196. */
  1197. var getVelocity = function(deltaTime, x, y) {
  1198. return {
  1199. x: x / deltaTime || 0,
  1200. y: y / deltaTime || 0
  1201. };
  1202. };
  1203. /**
  1204. * detect gestures
  1205. * @param {type} event
  1206. * @param {type} touch
  1207. * @returns {undefined}
  1208. */
  1209. var detect = function(event, touch) {
  1210. if($.gestures.stoped) {
  1211. return;
  1212. }
  1213. $.doAction('gestures', function(index, gesture) {
  1214. if(!$.gestures.stoped) {
  1215. if($.options.gestureConfig[gesture.name] !== false) {
  1216. gesture.handle(event, touch);
  1217. }
  1218. }
  1219. });
  1220. };
  1221. /**
  1222. * 暂时无用
  1223. * @param {Object} node
  1224. * @param {Object} parent
  1225. */
  1226. var hasParent = function(node, parent) {
  1227. while(node) {
  1228. if(node == parent) {
  1229. return true;
  1230. }
  1231. node = node.parentNode;
  1232. }
  1233. return false;
  1234. };
  1235. var uniqueArray = function(src, key, sort) {
  1236. var results = [];
  1237. var values = [];
  1238. var i = 0;
  1239. while(i < src.length) {
  1240. var val = key ? src[i][key] : src[i];
  1241. if(values.indexOf(val) < 0) {
  1242. results.push(src[i]);
  1243. }
  1244. values[i] = val;
  1245. i++;
  1246. }
  1247. if(sort) {
  1248. if(!key) {
  1249. results = results.sort();
  1250. } else {
  1251. results = results.sort(function sortUniqueArray(a, b) {
  1252. return a[key] > b[key];
  1253. });
  1254. }
  1255. }
  1256. return results;
  1257. };
  1258. var getMultiCenter = function(touches) {
  1259. var touchesLength = touches.length;
  1260. if(touchesLength === 1) {
  1261. return {
  1262. x: round(touches[0].pageX),
  1263. y: round(touches[0].pageY)
  1264. };
  1265. }
  1266. var x = 0;
  1267. var y = 0;
  1268. var i = 0;
  1269. while(i < touchesLength) {
  1270. x += touches[i].pageX;
  1271. y += touches[i].pageY;
  1272. i++;
  1273. }
  1274. return {
  1275. x: round(x / touchesLength),
  1276. y: round(y / touchesLength)
  1277. };
  1278. };
  1279. var multiTouch = function() {
  1280. return $.options.gestureConfig.pinch;
  1281. };
  1282. var copySimpleTouchData = function(touch) {
  1283. var touches = [];
  1284. var i = 0;
  1285. while(i < touch.touches.length) {
  1286. touches[i] = {
  1287. pageX: round(touch.touches[i].pageX),
  1288. pageY: round(touch.touches[i].pageY)
  1289. };
  1290. i++;
  1291. }
  1292. return {
  1293. timestamp: $.now(),
  1294. gesture: touch.gesture,
  1295. touches: touches,
  1296. center: getMultiCenter(touch.touches),
  1297. deltaX: touch.deltaX,
  1298. deltaY: touch.deltaY
  1299. };
  1300. };
  1301. var calDelta = function(touch) {
  1302. var session = $.gestures.session;
  1303. var center = touch.center;
  1304. var offset = session.offsetDelta || {};
  1305. var prevDelta = session.prevDelta || {};
  1306. var prevTouch = session.prevTouch || {};
  1307. if(touch.gesture.type === $.EVENT_START || touch.gesture.type === $.EVENT_END) {
  1308. prevDelta = session.prevDelta = {
  1309. x: prevTouch.deltaX || 0,
  1310. y: prevTouch.deltaY || 0
  1311. };
  1312. offset = session.offsetDelta = {
  1313. x: center.x,
  1314. y: center.y
  1315. };
  1316. }
  1317. touch.deltaX = prevDelta.x + (center.x - offset.x);
  1318. touch.deltaY = prevDelta.y + (center.y - offset.y);
  1319. };
  1320. var calTouchData = function(touch) {
  1321. var session = $.gestures.session;
  1322. var touches = touch.touches;
  1323. var touchesLength = touches.length;
  1324. if(!session.firstTouch) {
  1325. session.firstTouch = copySimpleTouchData(touch);
  1326. }
  1327. if(multiTouch() && touchesLength > 1 && !session.firstMultiTouch) {
  1328. session.firstMultiTouch = copySimpleTouchData(touch);
  1329. } else if(touchesLength === 1) {
  1330. session.firstMultiTouch = false;
  1331. }
  1332. var firstTouch = session.firstTouch;
  1333. var firstMultiTouch = session.firstMultiTouch;
  1334. var offsetCenter = firstMultiTouch ? firstMultiTouch.center : firstTouch.center;
  1335. var center = touch.center = getMultiCenter(touches);
  1336. touch.timestamp = $.now();
  1337. touch.deltaTime = touch.timestamp - firstTouch.timestamp;
  1338. touch.angle = getAngle(offsetCenter, center);
  1339. touch.distance = getDistance(offsetCenter, center);
  1340. calDelta(touch);
  1341. touch.offsetDirection = getDirection(touch.deltaX, touch.deltaY);
  1342. touch.scale = firstMultiTouch ? getScale(firstMultiTouch.touches, touches) : 1;
  1343. touch.rotation = firstMultiTouch ? getRotation(firstMultiTouch.touches, touches) : 0;
  1344. calIntervalTouchData(touch);
  1345. };
  1346. var CAL_INTERVAL = 25;
  1347. var calIntervalTouchData = function(touch) {
  1348. var session = $.gestures.session;
  1349. var last = session.lastInterval || touch;
  1350. var deltaTime = touch.timestamp - last.timestamp;
  1351. var velocity;
  1352. var velocityX;
  1353. var velocityY;
  1354. var direction;
  1355. if(touch.gesture.type != $.EVENT_CANCEL && (deltaTime > CAL_INTERVAL || last.velocity === undefined)) {
  1356. var deltaX = last.deltaX - touch.deltaX;
  1357. var deltaY = last.deltaY - touch.deltaY;
  1358. var v = getVelocity(deltaTime, deltaX, deltaY);
  1359. velocityX = v.x;
  1360. velocityY = v.y;
  1361. velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
  1362. direction = getDirection(deltaX, deltaY) || last.direction;
  1363. session.lastInterval = touch;
  1364. } else {
  1365. velocity = last.velocity;
  1366. velocityX = last.velocityX;
  1367. velocityY = last.velocityY;
  1368. direction = last.direction;
  1369. }
  1370. touch.velocity = velocity;
  1371. touch.velocityX = velocityX;
  1372. touch.velocityY = velocityY;
  1373. touch.direction = direction;
  1374. };
  1375. var targetIds = {};
  1376. var convertTouches = function(touches) {
  1377. for(var i = 0; i < touches.length; i++) {
  1378. !touches['identifier'] && (touches['identifier'] = 0);
  1379. }
  1380. return touches;
  1381. };
  1382. var getTouches = function(event, touch) {
  1383. var allTouches = convertTouches($.slice.call(event.touches || [event]));
  1384. var type = event.type;
  1385. var targetTouches = [];
  1386. var changedTargetTouches = [];
  1387. //当touchstart或touchmove且touches长度为1,直接获得all和changed
  1388. if((type === $.EVENT_START || type === $.EVENT_MOVE) && allTouches.length === 1) {
  1389. targetIds[allTouches[0].identifier] = true;
  1390. targetTouches = allTouches;
  1391. changedTargetTouches = allTouches;
  1392. touch.target = event.target;
  1393. } else {
  1394. var i = 0;
  1395. var targetTouches = [];
  1396. var changedTargetTouches = [];
  1397. var changedTouches = convertTouches($.slice.call(event.changedTouches || [event]));
  1398. touch.target = event.target;
  1399. var sessionTarget = $.gestures.session.target || event.target;
  1400. targetTouches = allTouches.filter(function(touch) {
  1401. return hasParent(touch.target, sessionTarget);
  1402. });
  1403. if(type === $.EVENT_START) {
  1404. i = 0;
  1405. while(i < targetTouches.length) {
  1406. targetIds[targetTouches[i].identifier] = true;
  1407. i++;
  1408. }
  1409. }
  1410. i = 0;
  1411. while(i < changedTouches.length) {
  1412. if(targetIds[changedTouches[i].identifier]) {
  1413. changedTargetTouches.push(changedTouches[i]);
  1414. }
  1415. if(type === $.EVENT_END || type === $.EVENT_CANCEL) {
  1416. delete targetIds[changedTouches[i].identifier];
  1417. }
  1418. i++;
  1419. }
  1420. if(!changedTargetTouches.length) {
  1421. return false;
  1422. }
  1423. }
  1424. targetTouches = uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true);
  1425. var touchesLength = targetTouches.length;
  1426. var changedTouchesLength = changedTargetTouches.length;
  1427. if(type === $.EVENT_START && touchesLength - changedTouchesLength === 0) { //first
  1428. touch.isFirst = true;
  1429. $.gestures.touch = $.gestures.session = {
  1430. target: event.target
  1431. };
  1432. }
  1433. touch.isFinal = ((type === $.EVENT_END || type === $.EVENT_CANCEL) && (touchesLength - changedTouchesLength === 0));
  1434. touch.touches = targetTouches;
  1435. touch.changedTouches = changedTargetTouches;
  1436. return true;
  1437. };
  1438. var handleTouchEvent = function(event) {
  1439. var touch = {
  1440. gesture: event
  1441. };
  1442. var touches = getTouches(event, touch);
  1443. if(!touches) {
  1444. return;
  1445. }
  1446. calTouchData(touch);
  1447. detect(event, touch);
  1448. $.gestures.session.prevTouch = touch;
  1449. if(event.type === $.EVENT_END && !$.isTouchable) {
  1450. $.gestures.touch = $.gestures.session = {};
  1451. }
  1452. };
  1453. var supportsPassive = (function checkPassiveListener() {
  1454. var supportsPassive = false;
  1455. try {
  1456. var opts = Object.defineProperty({}, 'passive', {
  1457. get: function get() {
  1458. supportsPassive = true;
  1459. },
  1460. });
  1461. window.addEventListener('testPassiveListener', null, opts);
  1462. } catch(e) {
  1463. // No support
  1464. }
  1465. return supportsPassive;
  1466. }())
  1467. window.addEventListener($.EVENT_START, handleTouchEvent);
  1468. window.addEventListener($.EVENT_MOVE, handleTouchEvent, supportsPassive ? {
  1469. passive: false,
  1470. capture: false
  1471. } : false);
  1472. window.addEventListener($.EVENT_END, handleTouchEvent);
  1473. window.addEventListener($.EVENT_CANCEL, handleTouchEvent);
  1474. //fixed hashchange(android)
  1475. window.addEventListener($.EVENT_CLICK, function(e) {
  1476. //TODO 应该判断当前target是不是在targets.popover内部,而不是非要相等
  1477. if(($.os.android || $.os.ios) && (($.targets.popover && e.target === $.targets.popover) || ($.targets.tab) || $.targets.offcanvas || $.targets.modal)) {
  1478. e.preventDefault();
  1479. }
  1480. }, true);
  1481. //增加原生滚动识别
  1482. $.isScrolling = false;
  1483. var scrollingTimeout = null;
  1484. window.addEventListener('scroll', function() {
  1485. $.isScrolling = true;
  1486. scrollingTimeout && clearTimeout(scrollingTimeout);
  1487. scrollingTimeout = setTimeout(function() {
  1488. $.isScrolling = false;
  1489. }, 250);
  1490. });
  1491. })(mui, window);
  1492. /**
  1493. * mui gesture flick[left|right|up|down]
  1494. * @param {type} $
  1495. * @param {type} name
  1496. * @returns {undefined}
  1497. */
  1498. (function($, name) {
  1499. var flickStartTime = 0;
  1500. var handle = function(event, touch) {
  1501. var session = $.gestures.session;
  1502. var options = this.options;
  1503. var now = $.now();
  1504. switch (event.type) {
  1505. case $.EVENT_MOVE:
  1506. if (now - flickStartTime > 300) {
  1507. flickStartTime = now;
  1508. session.flickStart = touch.center;
  1509. }
  1510. break;
  1511. case $.EVENT_END:
  1512. case $.EVENT_CANCEL:
  1513. touch.flick = false;
  1514. if (session.flickStart && options.flickMaxTime > (now - flickStartTime) && touch.distance > options.flickMinDistince) {
  1515. touch.flick = true;
  1516. touch.flickTime = now - flickStartTime;
  1517. touch.flickDistanceX = touch.center.x - session.flickStart.x;
  1518. touch.flickDistanceY = touch.center.y - session.flickStart.y;
  1519. $.trigger(session.target, name, touch);
  1520. $.trigger(session.target, name + touch.direction, touch);
  1521. }
  1522. break;
  1523. }
  1524. };
  1525. /**
  1526. * mui gesture flick
  1527. */
  1528. $.addGesture({
  1529. name: name,
  1530. index: 5,
  1531. handle: handle,
  1532. options: {
  1533. flickMaxTime: 200,
  1534. flickMinDistince: 10
  1535. }
  1536. });
  1537. })(mui, 'flick');
  1538. /**
  1539. * mui gesture swipe[left|right|up|down]
  1540. * @param {type} $
  1541. * @param {type} name
  1542. * @returns {undefined}
  1543. */
  1544. (function($, name) {
  1545. var handle = function(event, touch) {
  1546. var session = $.gestures.session;
  1547. if (event.type === $.EVENT_END || event.type === $.EVENT_CANCEL) {
  1548. var options = this.options;
  1549. touch.swipe = false;
  1550. //TODO 后续根据velocity计算
  1551. if (touch.direction && options.swipeMaxTime > touch.deltaTime && touch.distance > options.swipeMinDistince) {
  1552. touch.swipe = true;
  1553. $.trigger(session.target, name, touch);
  1554. $.trigger(session.target, name + touch.direction, touch);
  1555. }
  1556. }
  1557. };
  1558. /**
  1559. * mui gesture swipe
  1560. */
  1561. $.addGesture({
  1562. name: name,
  1563. index: 10,
  1564. handle: handle,
  1565. options: {
  1566. swipeMaxTime: 300,
  1567. swipeMinDistince: 18
  1568. }
  1569. });
  1570. })(mui, 'swipe');
  1571. /**
  1572. * mui gesture drag[start|left|right|up|down|end]
  1573. * @param {type} $
  1574. * @param {type} name
  1575. * @returns {undefined}
  1576. */
  1577. (function($, name) {
  1578. var handle = function(event, touch) {
  1579. var session = $.gestures.session;
  1580. switch (event.type) {
  1581. case $.EVENT_START:
  1582. break;
  1583. case $.EVENT_MOVE:
  1584. if (!touch.direction || !session.target) {
  1585. return;
  1586. }
  1587. //修正direction,可在session期间自行锁定拖拽方向,方便开发scroll类不同方向拖拽插件嵌套
  1588. if (session.lockDirection && session.startDirection) {
  1589. if (session.startDirection && session.startDirection !== touch.direction) {
  1590. if (session.startDirection === 'up' || session.startDirection === 'down') {
  1591. touch.direction = touch.deltaY < 0 ? 'up' : 'down';
  1592. } else {
  1593. touch.direction = touch.deltaX < 0 ? 'left' : 'right';
  1594. }
  1595. }
  1596. }
  1597. if (!session.drag) {
  1598. session.drag = true;
  1599. $.trigger(session.target, name + 'start', touch);
  1600. }
  1601. $.trigger(session.target, name, touch);
  1602. $.trigger(session.target, name + touch.direction, touch);
  1603. break;
  1604. case $.EVENT_END:
  1605. case $.EVENT_CANCEL:
  1606. if (session.drag && touch.isFinal) {
  1607. $.trigger(session.target, name + 'end', touch);
  1608. }
  1609. break;
  1610. }
  1611. };
  1612. /**
  1613. * mui gesture drag
  1614. */
  1615. $.addGesture({
  1616. name: name,
  1617. index: 20,
  1618. handle: handle,
  1619. options: {
  1620. fingers: 1
  1621. }
  1622. });
  1623. })(mui, 'drag');
  1624. /**
  1625. * mui gesture tap and doubleTap
  1626. * @param {type} $
  1627. * @param {type} name
  1628. * @returns {undefined}
  1629. */
  1630. (function($, name) {
  1631. var lastTarget;
  1632. var lastTapTime;
  1633. var handle = function(event, touch) {
  1634. var session = $.gestures.session;
  1635. var options = this.options;
  1636. switch (event.type) {
  1637. case $.EVENT_END:
  1638. if (!touch.isFinal) {
  1639. return;
  1640. }
  1641. var target = session.target;
  1642. if (!target || (target.disabled || (target.classList && target.classList.contains('mui-disabled')))) {
  1643. return;
  1644. }
  1645. if (touch.distance < options.tapMaxDistance && touch.deltaTime < options.tapMaxTime) {
  1646. if ($.options.gestureConfig.doubletap && lastTarget && (lastTarget === target)) { //same target
  1647. if (lastTapTime && (touch.timestamp - lastTapTime) < options.tapMaxInterval) {
  1648. $.trigger(target, 'doubletap', touch);
  1649. lastTapTime = $.now();
  1650. lastTarget = target;
  1651. return;
  1652. }
  1653. }
  1654. $.trigger(target, name, touch);
  1655. lastTapTime = $.now();
  1656. lastTarget = target;
  1657. }
  1658. break;
  1659. }
  1660. };
  1661. /**
  1662. * mui gesture tap
  1663. */
  1664. $.addGesture({
  1665. name: name,
  1666. index: 30,
  1667. handle: handle,
  1668. options: {
  1669. fingers: 1,
  1670. tapMaxInterval: 300,
  1671. tapMaxDistance: 5,
  1672. tapMaxTime: 250
  1673. }
  1674. });
  1675. })(mui, 'tap');
  1676. /**
  1677. * mui gesture longtap
  1678. * @param {type} $
  1679. * @param {type} name
  1680. * @returns {undefined}
  1681. */
  1682. (function($, name) {
  1683. var timer;
  1684. var handle = function(event, touch) {
  1685. var session = $.gestures.session;
  1686. var options = this.options;
  1687. switch (event.type) {
  1688. case $.EVENT_START:
  1689. clearTimeout(timer);
  1690. timer = setTimeout(function() {
  1691. $.trigger(session.target, name, touch);
  1692. }, options.holdTimeout);
  1693. break;
  1694. case $.EVENT_MOVE:
  1695. if (touch.distance > options.holdThreshold) {
  1696. clearTimeout(timer);
  1697. }
  1698. break;
  1699. case $.EVENT_END:
  1700. case $.EVENT_CANCEL:
  1701. clearTimeout(timer);
  1702. break;
  1703. }
  1704. };
  1705. /**
  1706. * mui gesture longtap
  1707. */
  1708. $.addGesture({
  1709. name: name,
  1710. index: 10,
  1711. handle: handle,
  1712. options: {
  1713. fingers: 1,
  1714. holdTimeout: 500,
  1715. holdThreshold: 2
  1716. }
  1717. });
  1718. })(mui, 'longtap');
  1719. /**
  1720. * mui gesture hold
  1721. * @param {type} $
  1722. * @param {type} name
  1723. * @returns {undefined}
  1724. */
  1725. (function($, name) {
  1726. var timer;
  1727. var handle = function(event, touch) {
  1728. var session = $.gestures.session;
  1729. var options = this.options;
  1730. switch (event.type) {
  1731. case $.EVENT_START:
  1732. if ($.options.gestureConfig.hold) {
  1733. timer && clearTimeout(timer);
  1734. timer = setTimeout(function() {
  1735. touch.hold = true;
  1736. $.trigger(session.target, name, touch);
  1737. }, options.holdTimeout);
  1738. }
  1739. break;
  1740. case $.EVENT_MOVE:
  1741. break;
  1742. case $.EVENT_END:
  1743. case $.EVENT_CANCEL:
  1744. if (timer) {
  1745. clearTimeout(timer) && (timer = null);
  1746. $.trigger(session.target, 'release', touch);
  1747. }
  1748. break;
  1749. }
  1750. };
  1751. /**
  1752. * mui gesture hold
  1753. */
  1754. $.addGesture({
  1755. name: name,
  1756. index: 10,
  1757. handle: handle,
  1758. options: {
  1759. fingers: 1,
  1760. holdTimeout: 0
  1761. }
  1762. });
  1763. })(mui, 'hold');
  1764. /**
  1765. * mui gesture pinch
  1766. * @param {type} $
  1767. * @param {type} name
  1768. * @returns {undefined}
  1769. */
  1770. (function($, name) {
  1771. var handle = function(event, touch) {
  1772. var options = this.options;
  1773. var session = $.gestures.session;
  1774. switch (event.type) {
  1775. case $.EVENT_START:
  1776. break;
  1777. case $.EVENT_MOVE:
  1778. if ($.options.gestureConfig.pinch) {
  1779. if (touch.touches.length < 2) {
  1780. return;
  1781. }
  1782. if (!session.pinch) { //start
  1783. session.pinch = true;
  1784. $.trigger(session.target, name + 'start', touch);
  1785. }
  1786. $.trigger(session.target, name, touch);
  1787. var scale = touch.scale;
  1788. var rotation = touch.rotation;
  1789. var lastScale = typeof touch.lastScale === 'undefined' ? 1 : touch.lastScale;
  1790. var scaleDiff = 0.000000000001; //防止scale与lastScale相等,不触发事件的情况。
  1791. if (scale > lastScale) { //out
  1792. lastScale = scale - scaleDiff;
  1793. $.trigger(session.target, name + 'out', touch);
  1794. } //in
  1795. else if (scale < lastScale) {
  1796. lastScale = scale + scaleDiff;
  1797. $.trigger(session.target, name + 'in', touch);
  1798. }
  1799. if (Math.abs(rotation) > options.minRotationAngle) {
  1800. $.trigger(session.target, 'rotate', touch);
  1801. }
  1802. }
  1803. break;
  1804. case $.EVENT_END:
  1805. case $.EVENT_CANCEL:
  1806. if ($.options.gestureConfig.pinch && session.pinch && touch.touches.length === 2) {
  1807. session.pinch = false;
  1808. $.trigger(session.target, name + 'end', touch);
  1809. }
  1810. break;
  1811. }
  1812. };
  1813. /**
  1814. * mui gesture pinch
  1815. */
  1816. $.addGesture({
  1817. name: name,
  1818. index: 10,
  1819. handle: handle,
  1820. options: {
  1821. minRotationAngle: 0
  1822. }
  1823. });
  1824. })(mui, 'pinch');
  1825. /**
  1826. * mui.init
  1827. * @param {type} $
  1828. * @returns {undefined}
  1829. */
  1830. (function($) {
  1831. $.global = $.options = {
  1832. gestureConfig: {
  1833. tap: true,
  1834. doubletap: false,
  1835. longtap: false,
  1836. hold: false,
  1837. flick: true,
  1838. swipe: true,
  1839. drag: true,
  1840. pinch: false
  1841. }
  1842. };
  1843. /**
  1844. *
  1845. * @param {type} options
  1846. * @returns {undefined}
  1847. */
  1848. $.initGlobal = function(options) {
  1849. $.options = $.extend(true, $.global, options);
  1850. return this;
  1851. };
  1852. var inits = {};
  1853. /**
  1854. * 单页配置 初始化
  1855. * @param {object} options
  1856. */
  1857. $.init = function(options) {
  1858. $.options = $.extend(true, $.global, options || {});
  1859. $.ready(function() {
  1860. $.doAction('inits', function(index, init) {
  1861. var isInit = !!(!inits[init.name] || init.repeat);
  1862. if (isInit) {
  1863. init.handle.call($);
  1864. inits[init.name] = true;
  1865. }
  1866. });
  1867. });
  1868. return this;
  1869. };
  1870. /**
  1871. * 增加初始化执行流程
  1872. * @param {function} init
  1873. */
  1874. $.addInit = function(init) {
  1875. return $.addAction('inits', init);
  1876. };
  1877. /**
  1878. * 处理html5版本subpages
  1879. */
  1880. $.addInit({
  1881. name: 'iframe',
  1882. index: 100,
  1883. handle: function() {
  1884. var options = $.options;
  1885. var subpages = options.subpages || [];
  1886. if (!$.os.plus && subpages.length) {
  1887. //暂时只处理单个subpage。后续可以考虑支持多个subpage
  1888. createIframe(subpages[0]);
  1889. }
  1890. }
  1891. });
  1892. var createIframe = function(options) {
  1893. var wrapper = document.createElement('div');
  1894. wrapper.className = 'mui-iframe-wrapper';
  1895. var styles = options.styles || {};
  1896. if (typeof styles.top !== 'string') {
  1897. styles.top = '0px';
  1898. }
  1899. if (typeof styles.bottom !== 'string') {
  1900. styles.bottom = '0px';
  1901. }
  1902. wrapper.style.top = styles.top;
  1903. wrapper.style.bottom = styles.bottom;
  1904. var iframe = document.createElement('iframe');
  1905. iframe.src = options.url;
  1906. iframe.id = options.id || options.url;
  1907. iframe.name = iframe.id;
  1908. wrapper.appendChild(iframe);
  1909. document.body.appendChild(wrapper);
  1910. //目前仅处理微信
  1911. $.os.wechat && handleScroll(wrapper, iframe);
  1912. };
  1913. function handleScroll(wrapper, iframe) {
  1914. var key = 'MUI_SCROLL_POSITION_' + document.location.href + '_' + iframe.src;
  1915. var scrollTop = (parseFloat(localStorage.getItem(key)) || 0);
  1916. if (scrollTop) {
  1917. (function(y) {
  1918. iframe.onload = function() {
  1919. window.scrollTo(0, y);
  1920. };
  1921. })(scrollTop);
  1922. }
  1923. setInterval(function() {
  1924. var _scrollTop = window.scrollY;
  1925. if (scrollTop !== _scrollTop) {
  1926. localStorage.setItem(key, _scrollTop + '');
  1927. scrollTop = _scrollTop;
  1928. }
  1929. }, 100);
  1930. };
  1931. $(function() {
  1932. var classList = document.body.classList;
  1933. var os = [];
  1934. if ($.os.ios) {
  1935. os.push({
  1936. os: 'ios',
  1937. version: $.os.version
  1938. });
  1939. classList.add('mui-ios');
  1940. } else if ($.os.android) {
  1941. os.push({
  1942. os: 'android',
  1943. version: $.os.version
  1944. });
  1945. classList.add('mui-android');
  1946. }
  1947. if ($.os.wechat) {
  1948. os.push({
  1949. os: 'wechat',
  1950. version: $.os.wechat.version
  1951. });
  1952. classList.add('mui-wechat');
  1953. }
  1954. if (os.length) {
  1955. $.each(os, function(index, osObj) {
  1956. var version = '';
  1957. var classArray = [];
  1958. if (osObj.version) {
  1959. $.each(osObj.version.split('.'), function(i, v) {
  1960. version = version + (version ? '-' : '') + v;
  1961. classList.add($.className(osObj.os + '-' + version));
  1962. });
  1963. }
  1964. });
  1965. }
  1966. });
  1967. })(mui);
  1968. /**
  1969. * mui.init 5+
  1970. * @param {type} $
  1971. * @returns {undefined}
  1972. */
  1973. (function($) {
  1974. var defaultOptions = {
  1975. swipeBack: false,
  1976. preloadPages: [], //5+ lazyLoad webview
  1977. preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出)
  1978. keyEventBind: {
  1979. backbutton: true,
  1980. menubutton: true
  1981. },
  1982. titleConfig: {
  1983. height: "44px",
  1984. backgroundColor: "#f7f7f7", //导航栏背景色
  1985. bottomBorderColor: "#cccccc", //底部边线颜色
  1986. title: { //标题配置
  1987. text: "", //标题文字
  1988. position: {
  1989. top: 0,
  1990. left: 0,
  1991. width: "100%",
  1992. height: "100%"
  1993. },
  1994. styles: {
  1995. color: "#000000",
  1996. align: "center",
  1997. family: "'Helvetica Neue',Helvetica,sans-serif",
  1998. size: "17px",
  1999. style: "normal",
  2000. weight: "normal",
  2001. fontSrc: ""
  2002. }
  2003. },
  2004. back: {
  2005. image: {
  2006. base64Data: '',
  2007. imgSrc: '',
  2008. sprite: {
  2009. top: '0px',
  2010. left: '0px',
  2011. width: '100%',
  2012. height: '100%'
  2013. },
  2014. position: {
  2015. top: "10px",
  2016. left: "10px",
  2017. width: "24px",
  2018. height: "24px"
  2019. }
  2020. }
  2021. }
  2022. }
  2023. };
  2024. //默认页面动画
  2025. var defaultShow = {
  2026. event:"titleUpdate",
  2027. autoShow: true,
  2028. duration: 300,
  2029. aniShow: 'slide-in-right',
  2030. extras:{}
  2031. };
  2032. //若执行了显示动画初始化操作,则要覆盖默认配置
  2033. if($.options.show) {
  2034. defaultShow = $.extend(true, defaultShow, $.options.show);
  2035. }
  2036. $.currentWebview = null;
  2037. $.extend(true, $.global, defaultOptions);
  2038. $.extend(true, $.options, defaultOptions);
  2039. /**
  2040. * 等待动画配置
  2041. * @param {type} options
  2042. * @returns {Object}
  2043. */
  2044. $.waitingOptions = function(options) {
  2045. return $.extend(true, {}, {
  2046. autoShow: true,
  2047. title: '',
  2048. modal: false
  2049. }, options);
  2050. };
  2051. /**
  2052. * 窗口显示配置
  2053. * @param {type} options
  2054. * @returns {Object}
  2055. */
  2056. $.showOptions = function(options) {
  2057. return $.extend(true, {}, defaultShow, options);
  2058. };
  2059. /**
  2060. * 窗口默认配置
  2061. * @param {type} options
  2062. * @returns {Object}
  2063. */
  2064. $.windowOptions = function(options) {
  2065. return $.extend({
  2066. scalable: false,
  2067. bounce: "" //vertical
  2068. }, options);
  2069. };
  2070. /**
  2071. * plusReady
  2072. * @param {type} callback
  2073. * @returns {_L6.$}
  2074. */
  2075. $.plusReady = function(callback) {
  2076. if(window.plus) {
  2077. setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)
  2078. callback();
  2079. }, 0);
  2080. } else {
  2081. document.addEventListener("plusready", function() {
  2082. callback();
  2083. }, false);
  2084. }
  2085. return this;
  2086. };
  2087. /**
  2088. * 5+ event(5+没提供之前我自己实现)
  2089. * @param {type} webview
  2090. * @param {type} eventType
  2091. * @param {type} data
  2092. * @returns {undefined}
  2093. */
  2094. $.fire = function(webview, eventType, data) {
  2095. if(webview) {
  2096. if(typeof data === 'undefined') {
  2097. data = '';
  2098. } else if(typeof data === 'boolean' || typeof data === 'number') {
  2099. webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")");
  2100. return;
  2101. } else if($.isPlainObject(data) || $.isArray(data)) {
  2102. data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c");
  2103. }
  2104. webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')");
  2105. }
  2106. };
  2107. /**
  2108. * 5+ event(5+没提供之前我自己实现)
  2109. * @param {type} eventType
  2110. * @param {type} data
  2111. * @returns {undefined}
  2112. */
  2113. $.receive = function(eventType, data) {
  2114. if(eventType) {
  2115. try {
  2116. if(data && typeof data === 'string') {
  2117. data = JSON.parse(data);
  2118. }
  2119. } catch(e) {}
  2120. $.trigger(document, eventType, data);
  2121. }
  2122. };
  2123. var triggerPreload = function(webview) {
  2124. if(!webview.preloaded) { //保证仅触发一次
  2125. $.fire(webview, 'preload');
  2126. var list = webview.children();
  2127. for(var i = 0; i < list.length; i++) {
  2128. $.fire(list[i], 'preload');
  2129. }
  2130. webview.preloaded = true;
  2131. }
  2132. };
  2133. var trigger = function(webview, eventType, timeChecked) {
  2134. if(timeChecked) {
  2135. if(!webview[eventType + 'ed']) {
  2136. $.fire(webview, eventType);
  2137. var list = webview.children();
  2138. for(var i = 0; i < list.length; i++) {
  2139. $.fire(list[i], eventType);
  2140. }
  2141. webview[eventType + 'ed'] = true;
  2142. }
  2143. } else {
  2144. $.fire(webview, eventType);
  2145. var list = webview.children();
  2146. for(var i = 0; i < list.length; i++) {
  2147. $.fire(list[i], eventType);
  2148. }
  2149. }
  2150. };
  2151. /**
  2152. * 打开新窗口
  2153. * @param {string} url 要打开的页面地址
  2154. * @param {string} id 指定页面ID
  2155. * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}}
  2156. */
  2157. $.openWindow = function(url, id, options) {
  2158. if(typeof url === 'object') {
  2159. options = url;
  2160. url = options.url;
  2161. id = options.id || url;
  2162. } else {
  2163. if(typeof id === 'object') {
  2164. options = id;
  2165. id = options.id || url;
  2166. } else {
  2167. id = id || url;
  2168. }
  2169. }
  2170. if(!$.os.plus) {
  2171. //TODO 先临时这么处理:手机上顶层跳,PC上parent跳
  2172. if($.os.ios || $.os.android) {
  2173. window.top.location.href = url;
  2174. } else {
  2175. window.parent.location.href = url;
  2176. }
  2177. return;
  2178. }
  2179. if(!window.plus) {
  2180. return;
  2181. }
  2182. options = options || {};
  2183. var params = options.params || {};
  2184. var webview = null,
  2185. webviewCache = null,
  2186. nShow, nWaiting;
  2187. if($.webviews[id]) {
  2188. webviewCache = $.webviews[id];
  2189. //webview真实存在,才能获取
  2190. if(plus.webview.getWebviewById(id)) {
  2191. webview = webviewCache.webview;
  2192. }
  2193. } else if(options.createNew !== true) {
  2194. webview = plus.webview.getWebviewById(id);
  2195. }
  2196. if(webview) { //已缓存
  2197. //每次show都需要传递动画参数;
  2198. //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
  2199. nShow = webviewCache ? webviewCache.show : defaultShow;
  2200. nShow = options.show ? $.extend(nShow, options.show) : nShow;
  2201. nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
  2202. triggerPreload(webview);
  2203. trigger(webview, 'pagebeforeshow', false);
  2204. });
  2205. if(webviewCache) {
  2206. webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
  2207. }
  2208. return webview;
  2209. } else { //新窗口
  2210. if(!url) {
  2211. throw new Error('webview[' + id + '] does not exist');
  2212. }
  2213. //显示waiting
  2214. var waitingConfig = $.waitingOptions(options.waiting);
  2215. if(waitingConfig.autoShow) {
  2216. nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
  2217. }
  2218. //创建页面
  2219. options = $.extend(options, {
  2220. id: id,
  2221. url: url
  2222. });
  2223. webview = $.createWindow(options);
  2224. //显示
  2225. nShow = $.showOptions(options.show);
  2226. if(nShow.autoShow) {
  2227. var showWebview = function() {
  2228. //关闭等待框
  2229. if(nWaiting) {
  2230. nWaiting.close();
  2231. }
  2232. //显示页面
  2233. webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
  2234. options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
  2235. };
  2236. //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
  2237. webview.addEventListener(nShow.event, showWebview, false);
  2238. //loaded事件发生后,触发预加载和pagebeforeshow事件
  2239. webview.addEventListener("loaded", function() {
  2240. triggerPreload(webview);
  2241. trigger(webview, 'pagebeforeshow', false);
  2242. }, false);
  2243. }
  2244. }
  2245. return webview;
  2246. };
  2247. $.openWindowWithTitle = function(options, titleConfig) {
  2248. options = options || {};
  2249. var url = options.url;
  2250. var id = options.id || url;
  2251. if(!$.os.plus) {
  2252. //TODO 先临时这么处理:手机上顶层跳,PC上parent跳
  2253. if($.os.ios || $.os.android) {
  2254. window.top.location.href = url;
  2255. } else {
  2256. window.parent.location.href = url;
  2257. }
  2258. return;
  2259. }
  2260. if(!window.plus) {
  2261. return;
  2262. }
  2263. var params = options.params || {};
  2264. var webview = null,
  2265. webviewCache = null,
  2266. nShow, nWaiting;
  2267. if($.webviews[id]) {
  2268. webviewCache = $.webviews[id];
  2269. //webview真实存在,才能获取
  2270. if(plus.webview.getWebviewById(id)) {
  2271. webview = webviewCache.webview;
  2272. }
  2273. } else if(options.createNew !== true) {
  2274. webview = plus.webview.getWebviewById(id);
  2275. }
  2276. if(webview) { //已缓存
  2277. //每次show都需要传递动画参数;
  2278. //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
  2279. nShow = webviewCache ? webviewCache.show : defaultShow;
  2280. nShow = options.show ? $.extend(nShow, options.show) : nShow;
  2281. nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
  2282. triggerPreload(webview);
  2283. trigger(webview, 'pagebeforeshow', false);
  2284. });
  2285. if(webviewCache) {
  2286. webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
  2287. }
  2288. return webview;
  2289. } else { //新窗口
  2290. if(!url) {
  2291. throw new Error('webview[' + id + '] does not exist');
  2292. }
  2293. //显示waiting
  2294. var waitingConfig = $.waitingOptions(options.waiting);
  2295. if(waitingConfig.autoShow) {
  2296. nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
  2297. }
  2298. //创建页面
  2299. options = $.extend(options, {
  2300. id: id,
  2301. url: url
  2302. });
  2303. webview = $.createWindow(options);
  2304. if(titleConfig) { //处理原生头
  2305. $.extend(true, $.options.titleConfig, titleConfig);
  2306. var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title";
  2307. var view = new plus.nativeObj.View(tid, {
  2308. top: 0,
  2309. height: $.options.titleConfig.height,
  2310. width: "100%",
  2311. dock: "top",
  2312. position: "dock"
  2313. });
  2314. view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色
  2315. var _b = parseInt($.options.titleConfig.height) - 1;
  2316. view.drawRect($.options.titleConfig.bottomBorderColor, {
  2317. top: _b + "px",
  2318. left: "0px"
  2319. }); //绘制底部边线
  2320. //绘制文字
  2321. if($.options.titleConfig.title.text){
  2322. var _title = $.options.titleConfig.title;
  2323. view.drawText(_title.text,_title.position , _title.styles);
  2324. }
  2325. //返回图标绘制
  2326. var _back = $.options.titleConfig.back;
  2327. var backClick = null;
  2328. //优先字体
  2329. //其次是图片
  2330. var _backImage = _back.image;
  2331. if(_backImage.base64Data || _backImage.imgSrc) {
  2332. //TODO 此处需要处理百分比的情况
  2333. backClick = {
  2334. left:parseInt(_backImage.position.left),
  2335. right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width)
  2336. };
  2337. var bitmap = new plus.nativeObj.Bitmap(id + "_back");
  2338. if(_backImage.base64Data) { //优先base64编码字符串
  2339. bitmap.loadBase64Data(_backImage.base64Data);
  2340. } else { //其次加载图片文件
  2341. bitmap.load(_backImage.imgSrc);
  2342. }
  2343. view.drawBitmap(bitmap,_backImage.sprite , _backImage.position);
  2344. }
  2345. //处理点击事件
  2346. view.setTouchEventRect({
  2347. top: "0px",
  2348. left: "0px",
  2349. width: "100%",
  2350. height: "100%"
  2351. });
  2352. view.interceptTouchEvent(true);
  2353. view.addEventListener("click", function(e) {
  2354. var x = e.clientX;
  2355. //返回按钮点击
  2356. if(backClick&& x > backClick.left && x < backClick.right){
  2357. if( _back.click && $.isFunction(_back.click)){
  2358. _back.click();
  2359. }else{
  2360. webview.evalJS("window.mui&&mui.back();");
  2361. }
  2362. }
  2363. }, false);
  2364. webview.append(view);
  2365. }
  2366. //显示
  2367. nShow = $.showOptions(options.show);
  2368. if(nShow.autoShow) {
  2369. //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
  2370. webview.addEventListener(nShow.event, function () {
  2371. //关闭等待框
  2372. if(nWaiting) {
  2373. nWaiting.close();
  2374. }
  2375. //显示页面
  2376. webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
  2377. }, false);
  2378. }
  2379. }
  2380. return webview;
  2381. };
  2382. /**
  2383. * 根据配置信息创建一个webview
  2384. * @param {type} options
  2385. * @param {type} isCreate
  2386. * @returns {webview}
  2387. */
  2388. $.createWindow = function(options, isCreate) {
  2389. if(!window.plus) {
  2390. return;
  2391. }
  2392. var id = options.id || options.url;
  2393. var webview;
  2394. if(options.preload) {
  2395. if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache
  2396. webview = $.webviews[id].webview;
  2397. } else { //新增预加载窗口
  2398. //判断是否携带createNew参数,默认为false
  2399. if(options.createNew !== true) {
  2400. webview = plus.webview.getWebviewById(id);
  2401. }
  2402. //之前没有,那就新创建
  2403. if(!webview) {
  2404. webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({
  2405. preload: true
  2406. }, options.extras));
  2407. if(options.subpages) {
  2408. $.each(options.subpages, function(index, subpage) {
  2409. var subpageId = subpage.id || subpage.url;
  2410. if(subpageId) { //过滤空对象
  2411. var subWebview = plus.webview.getWebviewById(subpageId);
  2412. if(!subWebview) { //如果该webview不存在,则创建
  2413. subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({
  2414. preload: true
  2415. }, subpage.extras));
  2416. }
  2417. webview.append(subWebview);
  2418. }
  2419. });
  2420. }
  2421. }
  2422. }
  2423. //TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题;
  2424. $.webviews[id] = {
  2425. webview: webview, //目前仅preload的缓存webview
  2426. preload: true,
  2427. show: $.showOptions(options.show),
  2428. afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯
  2429. };
  2430. //索引该预加载窗口
  2431. var preloads = $.data.preloads;
  2432. var index = preloads.indexOf(id);
  2433. if(~index) { //删除已存在的(变相调整插入位置)
  2434. preloads.splice(index, 1);
  2435. }
  2436. preloads.push(id);
  2437. if(preloads.length > $.options.preloadLimit) {
  2438. //先进先出
  2439. var first = $.data.preloads.shift();
  2440. var webviewCache = $.webviews[first];
  2441. if(webviewCache && webviewCache.webview) {
  2442. //需要将自己打开的所有页面,全部close;
  2443. //关闭该预加载webview
  2444. $.closeAll(webviewCache.webview);
  2445. }
  2446. //删除缓存
  2447. delete $.webviews[first];
  2448. }
  2449. } else {
  2450. if(isCreate !== false) { //直接创建非预加载窗口
  2451. webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras);
  2452. if(options.subpages) {
  2453. $.each(options.subpages, function(index, subpage) {
  2454. var subpageId = subpage.id || subpage.url;
  2455. var subWebview = plus.webview.getWebviewById(subpageId);
  2456. if(!subWebview) {
  2457. subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras);
  2458. }
  2459. webview.append(subWebview);
  2460. });
  2461. }
  2462. }
  2463. }
  2464. return webview;
  2465. };
  2466. /**
  2467. * 预加载
  2468. */
  2469. $.preload = function(options) {
  2470. //调用预加载函数,不管是否传递preload参数,强制变为true
  2471. if(!options.preload) {
  2472. options.preload = true;
  2473. }
  2474. return $.createWindow(options);
  2475. };
  2476. /**
  2477. *关闭当前webview打开的所有webview;
  2478. */
  2479. $.closeOpened = function(webview) {
  2480. var opened = webview.opened();
  2481. if(opened) {
  2482. for(var i = 0, len = opened.length; i < len; i++) {
  2483. var openedWebview = opened[i];
  2484. var open_open = openedWebview.opened();
  2485. if(open_open && open_open.length > 0) {
  2486. //关闭打开的webview
  2487. $.closeOpened(openedWebview);
  2488. //关闭自己
  2489. openedWebview.close("none");
  2490. } else {
  2491. //如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子;
  2492. if(openedWebview.parent() !== webview) {
  2493. openedWebview.close('none');
  2494. }
  2495. }
  2496. }
  2497. }
  2498. };
  2499. $.closeAll = function(webview, aniShow) {
  2500. $.closeOpened(webview);
  2501. if(aniShow) {
  2502. webview.close(aniShow);
  2503. } else {
  2504. webview.close();
  2505. }
  2506. };
  2507. /**
  2508. * 批量创建webview
  2509. * @param {type} options
  2510. * @returns {undefined}
  2511. */
  2512. $.createWindows = function(options) {
  2513. $.each(options, function(index, option) {
  2514. //初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建)
  2515. $.createWindow(option, false);
  2516. });
  2517. };
  2518. /**
  2519. * 创建当前页面的子webview
  2520. * @param {type} options
  2521. * @returns {webview}
  2522. */
  2523. $.appendWebview = function(options) {
  2524. if(!window.plus) {
  2525. return;
  2526. }
  2527. var id = options.id || options.url;
  2528. var webview;
  2529. if(!$.webviews[id]) { //保证执行一遍
  2530. //TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话;
  2531. if(!plus.webview.getWebviewById(id)) {
  2532. webview = plus.webview.create(options.url, id, options.styles, options.extras);
  2533. }
  2534. //之前的实现方案:子窗口loaded之后再append到父窗口中;
  2535. //问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败;
  2536. // 比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发;
  2537. //修改方式:不再监控loaded事件,直接append
  2538. //by chb@20150521
  2539. // webview.addEventListener('loaded', function() {
  2540. plus.webview.currentWebview().append(webview);
  2541. // });
  2542. $.webviews[id] = options;
  2543. }
  2544. return webview;
  2545. };
  2546. //全局webviews
  2547. $.webviews = {};
  2548. //预加载窗口索引
  2549. $.data.preloads = [];
  2550. //$.currentWebview
  2551. $.plusReady(function() {
  2552. $.currentWebview = plus.webview.currentWebview();
  2553. });
  2554. $.addInit({
  2555. name: '5+',
  2556. index: 100,
  2557. handle: function() {
  2558. var options = $.options;
  2559. var subpages = options.subpages || [];
  2560. if($.os.plus) {
  2561. $.plusReady(function() {
  2562. //TODO 这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法;
  2563. //或者:在openwindow方法中,监听实现;
  2564. $.each(subpages, function(index, subpage) {
  2565. $.appendWebview(subpage);
  2566. });
  2567. //判断是否首页
  2568. if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) {
  2569. //首页需要自己激活预加载;
  2570. //timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题;
  2571. setTimeout(function() {
  2572. triggerPreload(plus.webview.currentWebview());
  2573. }, 300);
  2574. }
  2575. //设置ios顶部状态栏颜色;
  2576. if($.os.ios && $.options.statusBarBackground) {
  2577. plus.navigator.setStatusBarBackground($.options.statusBarBackground);
  2578. }
  2579. if($.os.android && parseFloat($.os.version) < 4.4) {
  2580. //解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题;
  2581. if(plus.webview.currentWebview().parent() == null) {
  2582. document.addEventListener("resume", function() {
  2583. var body = document.body;
  2584. body.style.display = 'none';
  2585. setTimeout(function() {
  2586. body.style.display = '';
  2587. }, 10);
  2588. });
  2589. }
  2590. }
  2591. });
  2592. } else {
  2593. //已支持iframe嵌入
  2594. // if (subpages.length > 0) {
  2595. // var err = document.createElement('div');
  2596. // err.className = 'mui-error';
  2597. // //文字描述
  2598. // var span = document.createElement('span');
  2599. // span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考';
  2600. // err.appendChild(span);
  2601. // var a = document.createElement('a');
  2602. // a.innerHTML = '"mui框架适用场景"';
  2603. // a.href = 'http://ask.dcloud.net.cn/article/113';
  2604. // err.appendChild(a);
  2605. // document.body.appendChild(err);
  2606. // console.log('在该浏览器下,不支持创建子页面');
  2607. // }
  2608. }
  2609. }
  2610. });
  2611. window.addEventListener('preload', function() {
  2612. //处理预加载部分
  2613. var webviews = $.options.preloadPages || [];
  2614. $.plusReady(function() {
  2615. $.each(webviews, function(index, webview) {
  2616. $.createWindow($.extend(webview, {
  2617. preload: true
  2618. }));
  2619. });
  2620. });
  2621. });
  2622. $.supportStatusbarOffset = function() {
  2623. return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7;
  2624. };
  2625. $.ready(function() {
  2626. //标识当前环境支持statusbar
  2627. if($.supportStatusbarOffset()) {
  2628. document.body.classList.add('mui-statusbar');
  2629. }
  2630. });
  2631. })(mui);
  2632. /**
  2633. * mui back
  2634. * @param {type} $
  2635. * @param {type} window
  2636. * @returns {undefined}
  2637. */
  2638. (function($, window) {
  2639. /**
  2640. * register back
  2641. * @param {type} back
  2642. * @returns {$.gestures}
  2643. */
  2644. $.addBack = function(back) {
  2645. return $.addAction('backs', back);
  2646. };
  2647. /**
  2648. * default
  2649. */
  2650. $.addBack({
  2651. name: 'browser',
  2652. index: 100,
  2653. handle: function() {
  2654. if (window.history.length > 1) {
  2655. window.history.back();
  2656. return true;
  2657. }
  2658. return false;
  2659. }
  2660. });
  2661. /**
  2662. * 后退
  2663. */
  2664. $.back = function() {
  2665. if (typeof $.options.beforeback === 'function') {
  2666. if ($.options.beforeback() === false) {
  2667. return;
  2668. }
  2669. }
  2670. $.doAction('backs');
  2671. };
  2672. window.addEventListener('tap', function(e) {
  2673. var action = $.targets.action;
  2674. if (action && action.classList.contains('mui-action-back')) {
  2675. $.back();
  2676. $.targets.action = false;
  2677. }
  2678. });
  2679. window.addEventListener('swiperight', function(e) {
  2680. var detail = e.detail;
  2681. if ($.options.swipeBack === true && Math.abs(detail.angle) < 3) {
  2682. $.back();
  2683. }
  2684. });
  2685. })(mui, window);
  2686. /**
  2687. * mui back 5+
  2688. * @param {type} $
  2689. * @param {type} window
  2690. * @returns {undefined}
  2691. */
  2692. (function($, window) {
  2693. if ($.os.plus && $.os.android) {
  2694. $.addBack({
  2695. name: 'mui',
  2696. index: 5,
  2697. handle: function() {
  2698. //后续重新设计此处,将back放到各个空间内部实现
  2699. //popover
  2700. if ($.targets._popover && $.targets._popover.classList.contains('mui-active')) {
  2701. $($.targets._popover).popover('hide');
  2702. return true;
  2703. }
  2704. //offcanvas
  2705. var offCanvas = document.querySelector('.mui-off-canvas-wrap.mui-active');
  2706. if (offCanvas) {
  2707. $(offCanvas).offCanvas('close');
  2708. return true;
  2709. }
  2710. var previewImage = $.isFunction($.getPreviewImage) && $.getPreviewImage();
  2711. if (previewImage && previewImage.isShown()) {
  2712. previewImage.close();
  2713. return true;
  2714. }
  2715. //popup
  2716. return $.closePopup();
  2717. }
  2718. });
  2719. }
  2720. //首次按下back按键的时间
  2721. $.__back__first = null;
  2722. /**
  2723. * 5+ back
  2724. */
  2725. $.addBack({
  2726. name: '5+',
  2727. index: 10,
  2728. handle: function() {
  2729. if (!window.plus) {
  2730. return false;
  2731. }
  2732. var wobj = plus.webview.currentWebview();
  2733. var parent = wobj.parent();
  2734. if (parent) {
  2735. parent.evalJS('mui&&mui.back();');
  2736. } else {
  2737. wobj.canBack(function(e) {
  2738. //by chb 暂时注释,在碰到类似popover之类的锚点的时候,需多次点击才能返回;
  2739. if (e.canBack) { //webview history back
  2740. window.history.back();
  2741. } else { //webview close or hide
  2742. //fixed by fxy 此处不应该用opener判断,因为用户有可能自己close掉当前窗口的opener。这样的话。opener就为空了,导致不能执行close
  2743. if (wobj.id === plus.runtime.appid) { //首页
  2744. //首页不存在opener的情况下,后退实际上应该是退出应用;
  2745. //首次按键,提示‘再按一次退出应用’
  2746. if (!$.__back__first) {
  2747. $.__back__first = new Date().getTime();
  2748. mui.toast('再按一次退出应用');
  2749. setTimeout(function() {
  2750. $.__back__first = null;
  2751. }, 2000);
  2752. } else {
  2753. if (new Date().getTime() - $.__back__first < 2000) {
  2754. plus.runtime.quit();
  2755. }
  2756. }
  2757. } else { //其他页面,
  2758. if (wobj.preload) {
  2759. wobj.hide("auto");
  2760. } else {
  2761. //关闭页面时,需要将其打开的所有子页面全部关闭;
  2762. $.closeAll(wobj);
  2763. }
  2764. }
  2765. }
  2766. });
  2767. }
  2768. return true;
  2769. }
  2770. });
  2771. $.menu = function() {
  2772. var menu = document.querySelector('.mui-action-menu');
  2773. if (menu) {
  2774. $.trigger(menu, $.EVENT_START); //临时处理menu无touchstart的话,找不到当前targets的问题
  2775. $.trigger(menu, 'tap');
  2776. } else { //执行父窗口的menu
  2777. if (window.plus) {
  2778. var wobj = $.currentWebview;
  2779. var parent = wobj.parent();
  2780. if (parent) { //又得evalJS
  2781. parent.evalJS('mui&&mui.menu();');
  2782. }
  2783. }
  2784. }
  2785. };
  2786. var __back = function() {
  2787. $.back();
  2788. };
  2789. var __menu = function() {
  2790. $.menu();
  2791. };
  2792. //默认监听
  2793. $.plusReady(function() {
  2794. if ($.options.keyEventBind.backbutton) {
  2795. plus.key.addEventListener('backbutton', __back, false);
  2796. }
  2797. if ($.options.keyEventBind.menubutton) {
  2798. plus.key.addEventListener('menubutton', __menu, false);
  2799. }
  2800. });
  2801. //处理按键监听事件
  2802. $.addInit({
  2803. name: 'keyEventBind',
  2804. index: 1000,
  2805. handle: function() {
  2806. $.plusReady(function() {
  2807. //如果不为true,则移除默认监听
  2808. if (!$.options.keyEventBind.backbutton) {
  2809. plus.key.removeEventListener('backbutton', __back);
  2810. }
  2811. if (!$.options.keyEventBind.menubutton) {
  2812. plus.key.removeEventListener('menubutton', __menu);
  2813. }
  2814. });
  2815. }
  2816. });
  2817. })(mui, window);
  2818. /**
  2819. * mui.init pulldownRefresh
  2820. * @param {type} $
  2821. * @returns {undefined}
  2822. */
  2823. (function($) {
  2824. $.addInit({
  2825. name: 'pullrefresh',
  2826. index: 1000,
  2827. handle: function() {
  2828. var options = $.options;
  2829. var pullRefreshOptions = options.pullRefresh || {};
  2830. var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback');
  2831. var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback');
  2832. if(hasPulldown || hasPullup) {
  2833. var container = pullRefreshOptions.container;
  2834. if(container) {
  2835. var $container = $(container);
  2836. if($container.length === 1) {
  2837. if($.os.plus) { //5+环境
  2838. if(hasPulldown && pullRefreshOptions.down.style == "circle") { //原生转圈
  2839. $.plusReady(function() {
  2840. //这里改写$.fn.pullRefresh
  2841. $.fn.pullRefresh = $.fn.pullRefresh_native;
  2842. $container.pullRefresh(pullRefreshOptions);
  2843. });
  2844. } else if($.os.android) { //非原生转圈,但是Android环境
  2845. $.plusReady(function() {
  2846. //这里改写$.fn.pullRefresh
  2847. $.fn.pullRefresh = $.fn.pullRefresh_native
  2848. var webview = plus.webview.currentWebview();
  2849. if(window.__NWin_Enable__ === false) { //不支持多webview
  2850. $container.pullRefresh(pullRefreshOptions);
  2851. } else {
  2852. if(hasPullup) {
  2853. //当前页面初始化pullup
  2854. var upOptions = {};
  2855. upOptions.up = pullRefreshOptions.up;
  2856. upOptions.webviewId = webview.id || webview.getURL();
  2857. $container.pullRefresh(upOptions);
  2858. }
  2859. if(hasPulldown) {
  2860. var parent = webview.parent();
  2861. var id = webview.id || webview.getURL();
  2862. if(parent) {
  2863. if(!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法
  2864. $container.pullRefresh({
  2865. webviewId: id
  2866. });
  2867. }
  2868. var downOptions = {
  2869. webviewId: id//子页面id
  2870. };
  2871. downOptions.down = $.extend({}, pullRefreshOptions.down);
  2872. downOptions.down.callback = '_CALLBACK';
  2873. //改写父页面的$.fn.pullRefresh
  2874. parent.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native");
  2875. //父页面初始化pulldown
  2876. parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')");
  2877. }
  2878. }
  2879. }
  2880. });
  2881. } else { //非原生转圈,iOS环境
  2882. $container.pullRefresh(pullRefreshOptions);
  2883. }
  2884. } else {
  2885. $container.pullRefresh(pullRefreshOptions);
  2886. }
  2887. }
  2888. }
  2889. }
  2890. }
  2891. });
  2892. })(mui);
  2893. /**
  2894. * mui ajax
  2895. * @param {type} $
  2896. * @returns {undefined}
  2897. */
  2898. (function($, window, undefined) {
  2899. var jsonType = 'application/json';
  2900. var htmlType = 'text/html';
  2901. var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
  2902. var scriptTypeRE = /^(?:text|application)\/javascript/i;
  2903. var xmlTypeRE = /^(?:text|application)\/xml/i;
  2904. var blankRE = /^\s*$/;
  2905. $.ajaxSettings = {
  2906. type: 'GET',
  2907. beforeSend: $.noop,
  2908. success: $.noop,
  2909. error: $.noop,
  2910. complete: $.noop,
  2911. context: null,
  2912. xhr: function(protocol) {
  2913. return new window.XMLHttpRequest();
  2914. },
  2915. accepts: {
  2916. script: 'text/javascript, application/javascript, application/x-javascript',
  2917. json: jsonType,
  2918. xml: 'application/xml, text/xml',
  2919. html: htmlType,
  2920. text: 'text/plain'
  2921. },
  2922. timeout: 0,
  2923. processData: true,
  2924. cache: true
  2925. };
  2926. var ajaxBeforeSend = function(xhr, settings) {
  2927. var context = settings.context
  2928. if(settings.beforeSend.call(context, xhr, settings) === false) {
  2929. return false;
  2930. }
  2931. };
  2932. var ajaxSuccess = function(data, xhr, settings) {
  2933. settings.success.call(settings.context, data, 'success', xhr);
  2934. ajaxComplete('success', xhr, settings);
  2935. };
  2936. // type: "timeout", "error", "abort", "parsererror"
  2937. var ajaxError = function(error, type, xhr, settings) {
  2938. settings.error.call(settings.context, xhr, type, error);
  2939. ajaxComplete(type, xhr, settings);
  2940. };
  2941. // status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
  2942. var ajaxComplete = function(status, xhr, settings) {
  2943. settings.complete.call(settings.context, xhr, status);
  2944. };
  2945. var serialize = function(params, obj, traditional, scope) {
  2946. var type, array = $.isArray(obj),
  2947. hash = $.isPlainObject(obj);
  2948. $.each(obj, function(key, value) {
  2949. type = $.type(value);
  2950. if(scope) {
  2951. key = traditional ? scope :
  2952. scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']';
  2953. }
  2954. // handle data in serializeArray() format
  2955. if(!scope && array) {
  2956. params.add(value.name, value.value);
  2957. }
  2958. // recurse into nested objects
  2959. else if(type === "array" || (!traditional && type === "object")) {
  2960. serialize(params, value, traditional, key);
  2961. } else {
  2962. params.add(key, value);
  2963. }
  2964. });
  2965. };
  2966. var serializeData = function(options) {
  2967. if(options.processData && options.data && typeof options.data !== "string") {
  2968. var contentType = options.contentType;
  2969. if(!contentType && options.headers) {
  2970. contentType = options.headers['Content-Type'];
  2971. }
  2972. if(contentType && ~contentType.indexOf(jsonType)) { //application/json
  2973. options.data = JSON.stringify(options.data);
  2974. } else {
  2975. options.data = $.param(options.data, options.traditional);
  2976. }
  2977. }
  2978. if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
  2979. options.url = appendQuery(options.url, options.data);
  2980. options.data = undefined;
  2981. }
  2982. };
  2983. var appendQuery = function(url, query) {
  2984. if(query === '') {
  2985. return url;
  2986. }
  2987. return(url + '&' + query).replace(/[&?]{1,2}/, '?');
  2988. };
  2989. var mimeToDataType = function(mime) {
  2990. if(mime) {
  2991. mime = mime.split(';', 2)[0];
  2992. }
  2993. return mime && (mime === htmlType ? 'html' :
  2994. mime === jsonType ? 'json' :
  2995. scriptTypeRE.test(mime) ? 'script' :
  2996. xmlTypeRE.test(mime) && 'xml') || 'text';
  2997. };
  2998. var parseArguments = function(url, data, success, dataType) {
  2999. if($.isFunction(data)) {
  3000. dataType = success, success = data, data = undefined;
  3001. }
  3002. if(!$.isFunction(success)) {
  3003. dataType = success, success = undefined;
  3004. }
  3005. return {
  3006. url: url,
  3007. data: data,
  3008. success: success,
  3009. dataType: dataType
  3010. };
  3011. };
  3012. $.ajax = function(url, options) {
  3013. if(typeof url === "object") {
  3014. options = url;
  3015. url = undefined;
  3016. }
  3017. var settings = options || {};
  3018. settings.url = url || settings.url;
  3019. for(var key in $.ajaxSettings) {
  3020. if(settings[key] === undefined) {
  3021. settings[key] = $.ajaxSettings[key];
  3022. }
  3023. }
  3024. serializeData(settings);
  3025. var dataType = settings.dataType;
  3026. if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) {
  3027. settings.url = appendQuery(settings.url, '_=' + $.now());
  3028. }
  3029. var mime = settings.accepts[dataType && dataType.toLowerCase()];
  3030. var headers = {};
  3031. var setHeader = function(name, value) {
  3032. headers[name.toLowerCase()] = [name, value];
  3033. };
  3034. var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;
  3035. var xhr = settings.xhr(settings);
  3036. if(location.protocol === 'file:' && $.os.ios && window.webkit && window.webkit.messageHandlers && !(xhr instanceof plus.net.XMLHttpRequest)){
  3037. console.error("当前运行环境为WKWebview,需在plusReady事件触发后再调用mui.ajax,否则可能会执行失败或报Script error的错误")
  3038. }
  3039. var nativeSetHeader = xhr.setRequestHeader;
  3040. var abortTimeout;
  3041. setHeader('X-Requested-With', 'XMLHttpRequest');
  3042. setHeader('Accept', mime || '*/*');
  3043. if(!!(mime = settings.mimeType || mime)) {
  3044. if(mime.indexOf(',') > -1) {
  3045. mime = mime.split(',', 2)[0];
  3046. }
  3047. xhr.overrideMimeType && xhr.overrideMimeType(mime);
  3048. }
  3049. if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) {
  3050. setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
  3051. }
  3052. if(settings.headers) {
  3053. for(var name in settings.headers)
  3054. setHeader(name, settings.headers[name]);
  3055. }
  3056. xhr.setRequestHeader = setHeader;
  3057. xhr.onreadystatechange = function() {
  3058. if(xhr.readyState === 4) {
  3059. xhr.onreadystatechange = $.noop;
  3060. clearTimeout(abortTimeout);
  3061. var result, error = false;
  3062. var isLocal = protocol === 'file:';
  3063. if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) {
  3064. dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'));
  3065. result = xhr.responseText;
  3066. try {
  3067. // http://perfectionkills.com/global-eval-what-are-the-options/
  3068. if(dataType === 'script') {
  3069. (1, eval)(result);
  3070. } else if(dataType === 'xml') {
  3071. result = xhr.responseXML;
  3072. } else if(dataType === 'json') {
  3073. result = blankRE.test(result) ? null : $.parseJSON(result);
  3074. }
  3075. } catch(e) {
  3076. error = e;
  3077. }
  3078. if(error) {
  3079. ajaxError(error, 'parsererror', xhr, settings);
  3080. } else {
  3081. ajaxSuccess(result, xhr, settings);
  3082. }
  3083. } else {
  3084. var status = xhr.status ? 'error' : 'abort';
  3085. var statusText = xhr.statusText || null;
  3086. if(isLocal) {
  3087. status = 'error';
  3088. statusText = '404';
  3089. }
  3090. ajaxError(statusText, status, xhr, settings);
  3091. }
  3092. }
  3093. };
  3094. if(ajaxBeforeSend(xhr, settings) === false) {
  3095. xhr.abort();
  3096. ajaxError(null, 'abort', xhr, settings);
  3097. return xhr;
  3098. }
  3099. if(settings.xhrFields) {
  3100. for(var name in settings.xhrFields) {
  3101. xhr[name] = settings.xhrFields[name];
  3102. }
  3103. }
  3104. var async = 'async' in settings ? settings.async : true;
  3105. xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password);
  3106. for(var name in headers) {
  3107. if(headers.hasOwnProperty(name)) {
  3108. nativeSetHeader.apply(xhr, headers[name]);
  3109. }
  3110. }
  3111. if(settings.timeout > 0) {
  3112. abortTimeout = setTimeout(function() {
  3113. xhr.onreadystatechange = $.noop;
  3114. xhr.abort();
  3115. ajaxError(null, 'timeout', xhr, settings);
  3116. }, settings.timeout);
  3117. }
  3118. xhr.send(settings.data ? settings.data : null);
  3119. return xhr;
  3120. };
  3121. $.param = function(obj, traditional) {
  3122. var params = [];
  3123. params.add = function(k, v) {
  3124. this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
  3125. };
  3126. serialize(params, obj, traditional);
  3127. return params.join('&').replace(/%20/g, '+');
  3128. };
  3129. $.get = function( /* url, data, success, dataType */ ) {
  3130. return $.ajax(parseArguments.apply(null, arguments));
  3131. };
  3132. $.post = function( /* url, data, success, dataType */ ) {
  3133. var options = parseArguments.apply(null, arguments);
  3134. options.type = 'POST';
  3135. return $.ajax(options);
  3136. };
  3137. $.getJSON = function( /* url, data, success */ ) {
  3138. var options = parseArguments.apply(null, arguments);
  3139. options.dataType = 'json';
  3140. return $.ajax(options);
  3141. };
  3142. $.fn.load = function(url, data, success) {
  3143. if(!this.length)
  3144. return this;
  3145. var self = this,
  3146. parts = url.split(/\s/),
  3147. selector,
  3148. options = parseArguments(url, data, success),
  3149. callback = options.success;
  3150. if(parts.length > 1)
  3151. options.url = parts[0], selector = parts[1];
  3152. options.success = function(response) {
  3153. if(selector) {
  3154. var div = document.createElement('div');
  3155. div.innerHTML = response.replace(rscript, "");
  3156. var selectorDiv = document.createElement('div');
  3157. var childs = div.querySelectorAll(selector);
  3158. if(childs && childs.length > 0) {
  3159. for(var i = 0, len = childs.length; i < len; i++) {
  3160. selectorDiv.appendChild(childs[i]);
  3161. }
  3162. }
  3163. self[0].innerHTML = selectorDiv.innerHTML;
  3164. } else {
  3165. self[0].innerHTML = response;
  3166. }
  3167. callback && callback.apply(self, arguments);
  3168. };
  3169. $.ajax(options);
  3170. return this;
  3171. };
  3172. })(mui, window);
  3173. /**
  3174. * 5+ ajax
  3175. */
  3176. (function($) {
  3177. var originAnchor = document.createElement('a');
  3178. originAnchor.href = window.location.href;
  3179. $.plusReady(function() {
  3180. $.ajaxSettings = $.extend($.ajaxSettings, {
  3181. xhr: function(settings) {
  3182. if (settings.crossDomain) { //强制使用plus跨域
  3183. return new plus.net.XMLHttpRequest();
  3184. }
  3185. //仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest
  3186. if (originAnchor.protocol !== 'file:') {
  3187. var urlAnchor = document.createElement('a');
  3188. urlAnchor.href = settings.url;
  3189. urlAnchor.href = urlAnchor.href;
  3190. settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host);
  3191. if (settings.crossDomain) {
  3192. return new plus.net.XMLHttpRequest();
  3193. }
  3194. }
  3195. if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr
  3196. return new plus.net.XMLHttpRequest();
  3197. }
  3198. return new window.XMLHttpRequest();
  3199. }
  3200. });
  3201. });
  3202. })(mui);
  3203. /**
  3204. * mui layout(offset[,position,width,height...])
  3205. * @param {type} $
  3206. * @param {type} window
  3207. * @param {type} undefined
  3208. * @returns {undefined}
  3209. */
  3210. (function($, window, undefined) {
  3211. $.offset = function(element) {
  3212. var box = {
  3213. top : 0,
  3214. left : 0
  3215. };
  3216. if ( typeof element.getBoundingClientRect !== undefined) {
  3217. box = element.getBoundingClientRect();
  3218. }
  3219. return {
  3220. top : box.top + window.pageYOffset - element.clientTop,
  3221. left : box.left + window.pageXOffset - element.clientLeft
  3222. };
  3223. };
  3224. })(mui, window);
  3225. /**
  3226. * mui animation
  3227. */
  3228. (function($, window) {
  3229. /**
  3230. * scrollTo
  3231. */
  3232. $.scrollTo = function(scrollTop, duration, callback) {
  3233. duration = duration || 1000;
  3234. var scroll = function(duration) {
  3235. if (duration <= 0) {
  3236. window.scrollTo(0, scrollTop);
  3237. callback && callback();
  3238. return;
  3239. }
  3240. var distaince = scrollTop - window.scrollY;
  3241. setTimeout(function() {
  3242. window.scrollTo(0, window.scrollY + distaince / duration * 10);
  3243. scroll(duration - 10);
  3244. }, 16.7);
  3245. };
  3246. scroll(duration);
  3247. };
  3248. $.animationFrame = function(cb) {
  3249. var args, isQueued, context;
  3250. return function() {
  3251. args = arguments;
  3252. context = this;
  3253. if (!isQueued) {
  3254. isQueued = true;
  3255. requestAnimationFrame(function() {
  3256. cb.apply(context, args);
  3257. isQueued = false;
  3258. });
  3259. }
  3260. };
  3261. };
  3262. })(mui, window);
  3263. (function($) {
  3264. var initializing = false,
  3265. fnTest = /xyz/.test(function() {
  3266. xyz;
  3267. }) ? /\b_super\b/ : /.*/;
  3268. var Class = function() {};
  3269. Class.extend = function(prop) {
  3270. var _super = this.prototype;
  3271. initializing = true;
  3272. var prototype = new this();
  3273. initializing = false;
  3274. for (var name in prop) {
  3275. prototype[name] = typeof prop[name] == "function" &&
  3276. typeof _super[name] == "function" && fnTest.test(prop[name]) ?
  3277. (function(name, fn) {
  3278. return function() {
  3279. var tmp = this._super;
  3280. this._super = _super[name];
  3281. var ret = fn.apply(this, arguments);
  3282. this._super = tmp;
  3283. return ret;
  3284. };
  3285. })(name, prop[name]) :
  3286. prop[name];
  3287. }
  3288. function Class() {
  3289. if (!initializing && this.init)
  3290. this.init.apply(this, arguments);
  3291. }
  3292. Class.prototype = prototype;
  3293. Class.prototype.constructor = Class;
  3294. Class.extend = arguments.callee;
  3295. return Class;
  3296. };
  3297. $.Class = Class;
  3298. })(mui);
  3299. (function($, document, undefined) {
  3300. var CLASS_PULL_TOP_POCKET = 'mui-pull-top-pocket';
  3301. var CLASS_PULL_BOTTOM_POCKET = 'mui-pull-bottom-pocket';
  3302. var CLASS_PULL = 'mui-pull';
  3303. var CLASS_PULL_LOADING = 'mui-pull-loading';
  3304. var CLASS_PULL_CAPTION = 'mui-pull-caption';
  3305. var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
  3306. var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
  3307. var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
  3308. var CLASS_ICON = 'mui-icon';
  3309. var CLASS_SPINNER = 'mui-spinner';
  3310. var CLASS_ICON_PULLDOWN = 'mui-icon-pulldown';
  3311. var CLASS_BLOCK = 'mui-block';
  3312. var CLASS_HIDDEN = 'mui-hidden';
  3313. var CLASS_VISIBILITY = 'mui-visibility';
  3314. var CLASS_LOADING_UP = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
  3315. var CLASS_LOADING_DOWN = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
  3316. var CLASS_LOADING = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_SPINNER;
  3317. var pocketHtml = ['<div class="' + CLASS_PULL + '">', '<div class="{icon}"></div>', '<div class="' + CLASS_PULL_CAPTION + '">{contentrefresh}</div>', '</div>'].join('');
  3318. var PullRefresh = {
  3319. init: function(element, options) {
  3320. this._super(element, $.extend(true, {
  3321. scrollY: true,
  3322. scrollX: false,
  3323. indicators: true,
  3324. deceleration: 0.003,
  3325. down: {
  3326. height: 50,
  3327. contentinit: '下拉可以刷新',
  3328. contentdown: '下拉可以刷新',
  3329. contentover: '释放立即刷新',
  3330. contentrefresh: '正在刷新...'
  3331. },
  3332. up: {
  3333. height: 50,
  3334. auto: false,
  3335. contentinit: '上拉显示更多',
  3336. contentdown: '上拉显示更多',
  3337. contentrefresh: '正在加载...',
  3338. contentnomore: '没有更多数据了',
  3339. duration: 300
  3340. }
  3341. }, options));
  3342. },
  3343. _init: function() {
  3344. this._super();
  3345. this._initPocket();
  3346. },
  3347. _initPulldownRefresh: function() {
  3348. this.pulldown = true;
  3349. if (this.topPocket) {
  3350. this.pullPocket = this.topPocket;
  3351. this.pullPocket.classList.add(CLASS_BLOCK);
  3352. this.pullPocket.classList.add(CLASS_VISIBILITY);
  3353. this.pullCaption = this.topCaption;
  3354. this.pullLoading = this.topLoading;
  3355. }
  3356. },
  3357. _initPullupRefresh: function() {
  3358. this.pulldown = false;
  3359. if (this.bottomPocket) {
  3360. this.pullPocket = this.bottomPocket;
  3361. this.pullPocket.classList.add(CLASS_BLOCK);
  3362. this.pullPocket.classList.add(CLASS_VISIBILITY);
  3363. this.pullCaption = this.bottomCaption;
  3364. this.pullLoading = this.bottomLoading;
  3365. }
  3366. },
  3367. _initPocket: function() {
  3368. var options = this.options;
  3369. if (options.down && options.down.hasOwnProperty('callback')) {
  3370. this.topPocket = this.scroller.querySelector('.' + CLASS_PULL_TOP_POCKET);
  3371. if (!this.topPocket) {
  3372. this.topPocket = this._createPocket(CLASS_PULL_TOP_POCKET, options.down, CLASS_LOADING_DOWN);
  3373. this.wrapper.insertBefore(this.topPocket, this.wrapper.firstChild);
  3374. }
  3375. this.topLoading = this.topPocket.querySelector('.' + CLASS_PULL_LOADING);
  3376. this.topCaption = this.topPocket.querySelector('.' + CLASS_PULL_CAPTION);
  3377. }
  3378. if (options.up && options.up.hasOwnProperty('callback')) {
  3379. this.bottomPocket = this.scroller.querySelector('.' + CLASS_PULL_BOTTOM_POCKET);
  3380. if (!this.bottomPocket) {
  3381. this.bottomPocket = this._createPocket(CLASS_PULL_BOTTOM_POCKET, options.up, CLASS_LOADING);
  3382. this.scroller.appendChild(this.bottomPocket);
  3383. }
  3384. this.bottomLoading = this.bottomPocket.querySelector('.' + CLASS_PULL_LOADING);
  3385. this.bottomCaption = this.bottomPocket.querySelector('.' + CLASS_PULL_CAPTION);
  3386. //TODO only for h5
  3387. this.wrapper.addEventListener('scrollbottom', this);
  3388. }
  3389. },
  3390. _createPocket: function(clazz, options, iconClass) {
  3391. var pocket = document.createElement('div');
  3392. pocket.className = clazz;
  3393. pocket.innerHTML = pocketHtml.replace('{contentrefresh}', options.contentinit).replace('{icon}', iconClass);
  3394. return pocket;
  3395. },
  3396. _resetPullDownLoading: function() {
  3397. var loading = this.pullLoading;
  3398. if (loading) {
  3399. this.pullCaption.innerHTML = this.options.down.contentdown;
  3400. loading.style.webkitTransition = "";
  3401. loading.style.webkitTransform = "";
  3402. loading.style.webkitAnimation = "";
  3403. loading.className = CLASS_LOADING_DOWN;
  3404. }
  3405. },
  3406. _setCaptionClass: function(isPulldown, caption, title) {
  3407. if (!isPulldown) {
  3408. switch (title) {
  3409. case this.options.up.contentdown:
  3410. caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
  3411. break;
  3412. case this.options.up.contentrefresh:
  3413. caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH
  3414. break;
  3415. case this.options.up.contentnomore:
  3416. caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
  3417. break;
  3418. }
  3419. }
  3420. },
  3421. _setCaption: function(title, reset) {
  3422. if (this.loading) {
  3423. return;
  3424. }
  3425. var options = this.options;
  3426. var pocket = this.pullPocket;
  3427. var caption = this.pullCaption;
  3428. var loading = this.pullLoading;
  3429. var isPulldown = this.pulldown;
  3430. var self = this;
  3431. if (pocket) {
  3432. if (reset) {
  3433. setTimeout(function() {
  3434. caption.innerHTML = self.lastTitle = title;
  3435. if (isPulldown) {
  3436. loading.className = CLASS_LOADING_DOWN;
  3437. } else {
  3438. self._setCaptionClass(false, caption, title);
  3439. loading.className = CLASS_LOADING;
  3440. }
  3441. loading.style.webkitAnimation = "";
  3442. loading.style.webkitTransition = "";
  3443. loading.style.webkitTransform = "";
  3444. }, 100);
  3445. } else {
  3446. if (title !== this.lastTitle) {
  3447. caption.innerHTML = title;
  3448. if (isPulldown) {
  3449. if (title === options.down.contentrefresh) {
  3450. loading.className = CLASS_LOADING;
  3451. loading.style.webkitAnimation = "spinner-spin 1s step-end infinite";
  3452. } else if (title === options.down.contentover) {
  3453. loading.className = CLASS_LOADING_UP;
  3454. loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
  3455. loading.style.webkitTransform = "rotate(180deg)";
  3456. } else if (title === options.down.contentdown) {
  3457. loading.className = CLASS_LOADING_DOWN;
  3458. loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
  3459. loading.style.webkitTransform = "rotate(0deg)";
  3460. }
  3461. } else {
  3462. if (title === options.up.contentrefresh) {
  3463. loading.className = CLASS_LOADING + ' ' + CLASS_VISIBILITY;
  3464. } else {
  3465. loading.className = CLASS_LOADING + ' ' + CLASS_HIDDEN;
  3466. }
  3467. self._setCaptionClass(false, caption, title);
  3468. }
  3469. this.lastTitle = title;
  3470. }
  3471. }
  3472. }
  3473. }
  3474. };
  3475. $.PullRefresh = PullRefresh;
  3476. })(mui, document);
  3477. (function($, window, document, undefined) {
  3478. var CLASS_SCROLL = 'mui-scroll';
  3479. var CLASS_SCROLLBAR = 'mui-scrollbar';
  3480. var CLASS_INDICATOR = 'mui-scrollbar-indicator';
  3481. var CLASS_SCROLLBAR_VERTICAL = CLASS_SCROLLBAR + '-vertical';
  3482. var CLASS_SCROLLBAR_HORIZONTAL = CLASS_SCROLLBAR + '-horizontal';
  3483. var CLASS_ACTIVE = 'mui-active';
  3484. var ease = {
  3485. quadratic: {
  3486. style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
  3487. fn: function(k) {
  3488. return k * (2 - k);
  3489. }
  3490. },
  3491. circular: {
  3492. style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',
  3493. fn: function(k) {
  3494. return Math.sqrt(1 - (--k * k));
  3495. }
  3496. },
  3497. outCirc: {
  3498. style: 'cubic-bezier(0.075, 0.82, 0.165, 1)'
  3499. },
  3500. outCubic: {
  3501. style: 'cubic-bezier(0.165, 0.84, 0.44, 1)'
  3502. }
  3503. }
  3504. var Scroll = $.Class.extend({
  3505. init: function(element, options) {
  3506. this.wrapper = this.element = element;
  3507. this.scroller = this.wrapper.children[0];
  3508. this.scrollerStyle = this.scroller && this.scroller.style;
  3509. this.stopped = false;
  3510. this.options = $.extend(true, {
  3511. scrollY: true, //是否竖向滚动
  3512. scrollX: false, //是否横向滚动
  3513. startX: 0, //初始化时滚动至x
  3514. startY: 0, //初始化时滚动至y
  3515. indicators: true, //是否显示滚动条
  3516. stopPropagation: false,
  3517. hardwareAccelerated: true,
  3518. fixedBadAndorid: false,
  3519. preventDefaultException: {
  3520. tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
  3521. },
  3522. momentum: true,
  3523. snapX: 0.5, //横向切换距离(以当前容器宽度为基准)
  3524. snap: false, //图片轮播,拖拽式选项卡
  3525. bounce: true, //是否启用回弹
  3526. bounceTime: 500, //回弹动画时间
  3527. bounceEasing: ease.outCirc, //回弹动画曲线
  3528. scrollTime: 500,
  3529. scrollEasing: ease.outCubic, //轮播动画曲线
  3530. directionLockThreshold: 5,
  3531. parallaxElement: false, //视差元素
  3532. parallaxRatio: 0.5
  3533. }, options);
  3534. this.x = 0;
  3535. this.y = 0;
  3536. this.translateZ = this.options.hardwareAccelerated ? ' translateZ(0)' : '';
  3537. this._init();
  3538. if (this.scroller) {
  3539. this.refresh();
  3540. // if (this.options.startX !== 0 || this.options.startY !== 0) { //需要判断吗?后续根据实际情况再看看
  3541. this.scrollTo(this.options.startX, this.options.startY);
  3542. // }
  3543. }
  3544. },
  3545. _init: function() {
  3546. this._initParallax();
  3547. this._initIndicators();
  3548. this._initEvent();
  3549. },
  3550. _initParallax: function() {
  3551. if (this.options.parallaxElement) {
  3552. this.parallaxElement = document.querySelector(this.options.parallaxElement);
  3553. this.parallaxStyle = this.parallaxElement.style;
  3554. this.parallaxHeight = this.parallaxElement.offsetHeight;
  3555. this.parallaxImgStyle = this.parallaxElement.querySelector('img').style;
  3556. }
  3557. },
  3558. _initIndicators: function() {
  3559. var self = this;
  3560. self.indicators = [];
  3561. if (!this.options.indicators) {
  3562. return;
  3563. }
  3564. var indicators = [],
  3565. indicator;
  3566. // Vertical scrollbar
  3567. if (self.options.scrollY) {
  3568. indicator = {
  3569. el: this._createScrollBar(CLASS_SCROLLBAR_VERTICAL),
  3570. listenX: false
  3571. };
  3572. this.wrapper.appendChild(indicator.el);
  3573. indicators.push(indicator);
  3574. }
  3575. // Horizontal scrollbar
  3576. if (this.options.scrollX) {
  3577. indicator = {
  3578. el: this._createScrollBar(CLASS_SCROLLBAR_HORIZONTAL),
  3579. listenY: false
  3580. };
  3581. this.wrapper.appendChild(indicator.el);
  3582. indicators.push(indicator);
  3583. }
  3584. for (var i = indicators.length; i--;) {
  3585. this.indicators.push(new Indicator(this, indicators[i]));
  3586. }
  3587. },
  3588. _initSnap: function() {
  3589. this.currentPage = {};
  3590. this.pages = [];
  3591. var snaps = this.snaps;
  3592. var length = snaps.length;
  3593. var m = 0;
  3594. var n = -1;
  3595. var x = 0;
  3596. var leftX = 0;
  3597. var rightX = 0;
  3598. var snapX = 0;
  3599. for (var i = 0; i < length; i++) {
  3600. var snap = snaps[i];
  3601. var offsetLeft = snap.offsetLeft;
  3602. var offsetWidth = snap.offsetWidth;
  3603. if (i === 0 || offsetLeft <= snaps[i - 1].offsetLeft) {
  3604. m = 0;
  3605. n++;
  3606. }
  3607. if (!this.pages[m]) {
  3608. this.pages[m] = [];
  3609. }
  3610. x = this._getSnapX(offsetLeft);
  3611. snapX = Math.round((offsetWidth) * this.options.snapX);
  3612. leftX = x - snapX;
  3613. rightX = x - offsetWidth + snapX;
  3614. this.pages[m][n] = {
  3615. x: x,
  3616. leftX: leftX,
  3617. rightX: rightX,
  3618. pageX: m,
  3619. element: snap
  3620. }
  3621. if (snap.classList.contains(CLASS_ACTIVE)) {
  3622. this.currentPage = this.pages[m][0];
  3623. }
  3624. if (x >= this.maxScrollX) {
  3625. m++;
  3626. }
  3627. }
  3628. this.options.startX = this.currentPage.x || 0;
  3629. },
  3630. _getSnapX: function(offsetLeft) {
  3631. return Math.max(Math.min(0, -offsetLeft + (this.wrapperWidth / 2)), this.maxScrollX);
  3632. },
  3633. _gotoPage: function(index) {
  3634. this.currentPage = this.pages[Math.min(index, this.pages.length - 1)][0];
  3635. for (var i = 0, len = this.snaps.length; i < len; i++) {
  3636. if (i === index) {
  3637. this.snaps[i].classList.add(CLASS_ACTIVE);
  3638. } else {
  3639. this.snaps[i].classList.remove(CLASS_ACTIVE);
  3640. }
  3641. }
  3642. this.scrollTo(this.currentPage.x, 0, this.options.scrollTime);
  3643. },
  3644. _nearestSnap: function(x) {
  3645. if (!this.pages.length) {
  3646. return {
  3647. x: 0,
  3648. pageX: 0
  3649. };
  3650. }
  3651. var i = 0;
  3652. var length = this.pages.length;
  3653. if (x > 0) {
  3654. x = 0;
  3655. } else if (x < this.maxScrollX) {
  3656. x = this.maxScrollX;
  3657. }
  3658. for (; i < length; i++) {
  3659. var nearestX = this.direction === 'left' ? this.pages[i][0].leftX : this.pages[i][0].rightX;
  3660. if (x >= nearestX) {
  3661. return this.pages[i][0];
  3662. }
  3663. }
  3664. return {
  3665. x: 0,
  3666. pageX: 0
  3667. };
  3668. },
  3669. _initEvent: function(detach) {
  3670. var action = detach ? 'removeEventListener' : 'addEventListener';
  3671. window[action]('orientationchange', this);
  3672. window[action]('resize', this);
  3673. this.scroller[action]('webkitTransitionEnd', this);
  3674. this.wrapper[action]($.EVENT_START, this);
  3675. this.wrapper[action]($.EVENT_CANCEL, this);
  3676. this.wrapper[action]($.EVENT_END, this);
  3677. this.wrapper[action]('drag', this);
  3678. this.wrapper[action]('dragend', this);
  3679. this.wrapper[action]('flick', this);
  3680. this.wrapper[action]('scrollend', this);
  3681. if (this.options.scrollX) {
  3682. this.wrapper[action]('swiperight', this);
  3683. }
  3684. var segmentedControl = this.wrapper.querySelector('.mui-segmented-control');
  3685. if (segmentedControl) { //靠,这个bug排查了一下午,阻止hash跳转,一旦hash跳转会导致可拖拽选项卡的tab不见
  3686. mui(segmentedControl)[detach ? 'off' : 'on']('click', 'a', $.preventDefault);
  3687. }
  3688. this.wrapper[action]('scrollstart', this);
  3689. this.wrapper[action]('refresh', this);
  3690. },
  3691. _handleIndicatorScrollend: function() {
  3692. this.indicators.map(function(indicator) {
  3693. indicator.fade();
  3694. });
  3695. },
  3696. _handleIndicatorScrollstart: function() {
  3697. this.indicators.map(function(indicator) {
  3698. indicator.fade(1);
  3699. });
  3700. },
  3701. _handleIndicatorRefresh: function() {
  3702. this.indicators.map(function(indicator) {
  3703. indicator.refresh();
  3704. });
  3705. },
  3706. handleEvent: function(e) {
  3707. if (this.stopped) {
  3708. this.resetPosition();
  3709. return;
  3710. }
  3711. switch (e.type) {
  3712. case $.EVENT_START:
  3713. this._start(e);
  3714. break;
  3715. case 'drag':
  3716. this.options.stopPropagation && e.stopPropagation();
  3717. this._drag(e);
  3718. break;
  3719. case 'dragend':
  3720. case 'flick':
  3721. this.options.stopPropagation && e.stopPropagation();
  3722. this._flick(e);
  3723. break;
  3724. case $.EVENT_CANCEL:
  3725. case $.EVENT_END:
  3726. this._end(e);
  3727. break;
  3728. case 'webkitTransitionEnd':
  3729. this.transitionTimer && this.transitionTimer.cancel();
  3730. this._transitionEnd(e);
  3731. break;
  3732. case 'scrollstart':
  3733. this._handleIndicatorScrollstart(e);
  3734. break;
  3735. case 'scrollend':
  3736. this._handleIndicatorScrollend(e);
  3737. this._scrollend(e);
  3738. e.stopPropagation();
  3739. break;
  3740. case 'orientationchange':
  3741. case 'resize':
  3742. this._resize();
  3743. break;
  3744. case 'swiperight':
  3745. e.stopPropagation();
  3746. break;
  3747. case 'refresh':
  3748. this._handleIndicatorRefresh(e);
  3749. break;
  3750. }
  3751. },
  3752. _start: function(e) {
  3753. this.moved = this.needReset = false;
  3754. this._transitionTime();
  3755. if (this.isInTransition) {
  3756. this.needReset = true;
  3757. this.isInTransition = false;
  3758. var pos = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
  3759. this.setTranslate(Math.round(pos.x), Math.round(pos.y));
  3760. // this.resetPosition(); //reset
  3761. $.trigger(this.scroller, 'scrollend', this);
  3762. // e.stopPropagation();
  3763. e.preventDefault();
  3764. }
  3765. this.reLayout();
  3766. $.trigger(this.scroller, 'beforescrollstart', this);
  3767. },
  3768. _getDirectionByAngle: function(angle) {
  3769. if (angle < -80 && angle > -100) {
  3770. return 'up';
  3771. } else if (angle >= 80 && angle < 100) {
  3772. return 'down';
  3773. } else if (angle >= 170 || angle <= -170) {
  3774. return 'left';
  3775. } else if (angle >= -35 && angle <= 10) {
  3776. return 'right';
  3777. }
  3778. return null;
  3779. },
  3780. _drag: function(e) {
  3781. // if (this.needReset) {
  3782. // e.stopPropagation(); //disable parent drag(nested scroller)
  3783. // return;
  3784. // }
  3785. var detail = e.detail;
  3786. if (this.options.scrollY || detail.direction === 'up' || detail.direction === 'down') { //如果是竖向滚动或手势方向是上或下
  3787. //ios8 hack
  3788. if ($.os.ios && parseFloat($.os.version) >= 8) { //多webview时,离开当前webview会导致后续touch事件不触发
  3789. var clientY = detail.gesture.touches[0].clientY;
  3790. //下拉刷新 or 上拉加载
  3791. if ((clientY + 10) > window.innerHeight || clientY < 10) {
  3792. this.resetPosition(this.options.bounceTime);
  3793. return;
  3794. }
  3795. }
  3796. }
  3797. var isPreventDefault = isReturn = false;
  3798. var direction = this._getDirectionByAngle(detail.angle);
  3799. if (detail.direction === 'left' || detail.direction === 'right') {
  3800. if (this.options.scrollX) {
  3801. isPreventDefault = true;
  3802. if (!this.moved) { //识别角度(该角度导致轮播不灵敏)
  3803. // if (direction !== 'left' && direction !== 'right') {
  3804. // isReturn = true;
  3805. // } else {
  3806. $.gestures.session.lockDirection = true; //锁定方向
  3807. $.gestures.session.startDirection = detail.direction;
  3808. // }
  3809. }
  3810. } else if (this.options.scrollY && !this.moved) {
  3811. isReturn = true;
  3812. }
  3813. } else if (detail.direction === 'up' || detail.direction === 'down') {
  3814. if (this.options.scrollY) {
  3815. isPreventDefault = true;
  3816. // if (!this.moved) { //识别角度,竖向滚动似乎没必要进行小角度验证
  3817. // if (direction !== 'up' && direction !== 'down') {
  3818. // isReturn = true;
  3819. // }
  3820. // }
  3821. if (!this.moved) {
  3822. $.gestures.session.lockDirection = true; //锁定方向
  3823. $.gestures.session.startDirection = detail.direction;
  3824. }
  3825. } else if (this.options.scrollX && !this.moved) {
  3826. isReturn = true;
  3827. }
  3828. } else {
  3829. isReturn = true;
  3830. }
  3831. if (this.moved || isPreventDefault) {
  3832. e.stopPropagation(); //阻止冒泡(scroll类嵌套)
  3833. detail.gesture && detail.gesture.preventDefault();
  3834. }
  3835. if (isReturn) { //禁止非法方向滚动
  3836. return;
  3837. }
  3838. if (!this.moved) {
  3839. $.trigger(this.scroller, 'scrollstart', this);
  3840. } else {
  3841. e.stopPropagation(); //move期间阻止冒泡(scroll嵌套)
  3842. }
  3843. var deltaX = 0;
  3844. var deltaY = 0;
  3845. if (!this.moved) { //start
  3846. deltaX = detail.deltaX;
  3847. deltaY = detail.deltaY;
  3848. } else { //move
  3849. deltaX = detail.deltaX - $.gestures.session.prevTouch.deltaX;
  3850. deltaY = detail.deltaY - $.gestures.session.prevTouch.deltaY;
  3851. }
  3852. var absDeltaX = Math.abs(detail.deltaX);
  3853. var absDeltaY = Math.abs(detail.deltaY);
  3854. if (absDeltaX > absDeltaY + this.options.directionLockThreshold) {
  3855. deltaY = 0;
  3856. } else if (absDeltaY >= absDeltaX + this.options.directionLockThreshold) {
  3857. deltaX = 0;
  3858. }
  3859. deltaX = this.hasHorizontalScroll ? deltaX : 0;
  3860. deltaY = this.hasVerticalScroll ? deltaY : 0;
  3861. var newX = this.x + deltaX;
  3862. var newY = this.y + deltaY;
  3863. // Slow down if outside of the boundaries
  3864. if (newX > 0 || newX < this.maxScrollX) {
  3865. newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
  3866. }
  3867. if (newY > 0 || newY < this.maxScrollY) {
  3868. newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
  3869. }
  3870. if (!this.requestAnimationFrame) {
  3871. this._updateTranslate();
  3872. }
  3873. this.direction = detail.deltaX > 0 ? 'right' : 'left';
  3874. this.moved = true;
  3875. this.x = newX;
  3876. this.y = newY;
  3877. $.trigger(this.scroller, 'scroll', this);
  3878. },
  3879. _flick: function(e) {
  3880. // if (!this.moved || this.needReset) {
  3881. // return;
  3882. // }
  3883. if (!this.moved) {
  3884. return;
  3885. }
  3886. e.stopPropagation();
  3887. var detail = e.detail;
  3888. this._clearRequestAnimationFrame();
  3889. if (e.type === 'dragend' && detail.flick) { //dragend
  3890. return;
  3891. }
  3892. var newX = Math.round(this.x);
  3893. var newY = Math.round(this.y);
  3894. this.isInTransition = false;
  3895. // reset if we are outside of the boundaries
  3896. if (this.resetPosition(this.options.bounceTime)) {
  3897. return;
  3898. }
  3899. this.scrollTo(newX, newY); // ensures that the last position is rounded
  3900. if (e.type === 'dragend') { //dragend
  3901. $.trigger(this.scroller, 'scrollend', this);
  3902. return;
  3903. }
  3904. var time = 0;
  3905. var easing = '';
  3906. // start momentum animation if needed
  3907. if (this.options.momentum && detail.flickTime < 300) {
  3908. momentumX = this.hasHorizontalScroll ? this._momentum(this.x, detail.flickDistanceX, detail.flickTime, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : {
  3909. destination: newX,
  3910. duration: 0
  3911. };
  3912. momentumY = this.hasVerticalScroll ? this._momentum(this.y, detail.flickDistanceY, detail.flickTime, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : {
  3913. destination: newY,
  3914. duration: 0
  3915. };
  3916. newX = momentumX.destination;
  3917. newY = momentumY.destination;
  3918. time = Math.max(momentumX.duration, momentumY.duration);
  3919. this.isInTransition = true;
  3920. }
  3921. if (newX != this.x || newY != this.y) {
  3922. if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) {
  3923. easing = ease.quadratic;
  3924. }
  3925. this.scrollTo(newX, newY, time, easing);
  3926. return;
  3927. }
  3928. $.trigger(this.scroller, 'scrollend', this);
  3929. // e.stopPropagation();
  3930. },
  3931. _end: function(e) {
  3932. this.needReset = false;
  3933. if ((!this.moved && this.needReset) || e.type === $.EVENT_CANCEL) {
  3934. this.resetPosition();
  3935. }
  3936. },
  3937. _transitionEnd: function(e) {
  3938. if (e.target != this.scroller || !this.isInTransition) {
  3939. return;
  3940. }
  3941. this._transitionTime();
  3942. if (!this.resetPosition(this.options.bounceTime)) {
  3943. this.isInTransition = false;
  3944. $.trigger(this.scroller, 'scrollend', this);
  3945. }
  3946. },
  3947. _scrollend: function(e) {
  3948. if ((this.y === 0 && this.maxScrollY === 0) || (Math.abs(this.y) > 0 && this.y <= this.maxScrollY)) {
  3949. $.trigger(this.scroller, 'scrollbottom', this);
  3950. }
  3951. },
  3952. _resize: function() {
  3953. var that = this;
  3954. clearTimeout(that.resizeTimeout);
  3955. that.resizeTimeout = setTimeout(function() {
  3956. that.refresh();
  3957. }, that.options.resizePolling);
  3958. },
  3959. _transitionTime: function(time) {
  3960. time = time || 0;
  3961. this.scrollerStyle['webkitTransitionDuration'] = time + 'ms';
  3962. if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
  3963. this.parallaxStyle['webkitTransitionDuration'] = time + 'ms';
  3964. }
  3965. if (this.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
  3966. this.scrollerStyle['webkitTransitionDuration'] = '0.001s';
  3967. if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
  3968. this.parallaxStyle['webkitTransitionDuration'] = '0.001s';
  3969. }
  3970. }
  3971. if (this.indicators) {
  3972. for (var i = this.indicators.length; i--;) {
  3973. this.indicators[i].transitionTime(time);
  3974. }
  3975. }
  3976. if (time) { //自定义timer,保证webkitTransitionEnd始终触发
  3977. this.transitionTimer && this.transitionTimer.cancel();
  3978. this.transitionTimer = $.later(function() {
  3979. $.trigger(this.scroller, 'webkitTransitionEnd');
  3980. }, time + 100, this);
  3981. }
  3982. },
  3983. _transitionTimingFunction: function(easing) {
  3984. this.scrollerStyle['webkitTransitionTimingFunction'] = easing;
  3985. if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
  3986. this.parallaxStyle['webkitTransitionDuration'] = easing;
  3987. }
  3988. if (this.indicators) {
  3989. for (var i = this.indicators.length; i--;) {
  3990. this.indicators[i].transitionTimingFunction(easing);
  3991. }
  3992. }
  3993. },
  3994. _translate: function(x, y) {
  3995. this.x = x;
  3996. this.y = y;
  3997. },
  3998. _clearRequestAnimationFrame: function() {
  3999. if (this.requestAnimationFrame) {
  4000. cancelAnimationFrame(this.requestAnimationFrame);
  4001. this.requestAnimationFrame = null;
  4002. }
  4003. },
  4004. _updateTranslate: function() {
  4005. var self = this;
  4006. if (self.x !== self.lastX || self.y !== self.lastY) {
  4007. self.setTranslate(self.x, self.y);
  4008. }
  4009. self.requestAnimationFrame = requestAnimationFrame(function() {
  4010. self._updateTranslate();
  4011. });
  4012. },
  4013. _createScrollBar: function(clazz) {
  4014. var scrollbar = document.createElement('div');
  4015. var indicator = document.createElement('div');
  4016. scrollbar.className = CLASS_SCROLLBAR + ' ' + clazz;
  4017. indicator.className = CLASS_INDICATOR;
  4018. scrollbar.appendChild(indicator);
  4019. if (clazz === CLASS_SCROLLBAR_VERTICAL) {
  4020. this.scrollbarY = scrollbar;
  4021. this.scrollbarIndicatorY = indicator;
  4022. } else if (clazz === CLASS_SCROLLBAR_HORIZONTAL) {
  4023. this.scrollbarX = scrollbar;
  4024. this.scrollbarIndicatorX = indicator;
  4025. }
  4026. this.wrapper.appendChild(scrollbar);
  4027. return scrollbar;
  4028. },
  4029. _preventDefaultException: function(el, exceptions) {
  4030. for (var i in exceptions) {
  4031. if (exceptions[i].test(el[i])) {
  4032. return true;
  4033. }
  4034. }
  4035. return false;
  4036. },
  4037. _reLayout: function() {
  4038. if (!this.hasHorizontalScroll) {
  4039. this.maxScrollX = 0;
  4040. this.scrollerWidth = this.wrapperWidth;
  4041. }
  4042. if (!this.hasVerticalScroll) {
  4043. this.maxScrollY = 0;
  4044. this.scrollerHeight = this.wrapperHeight;
  4045. }
  4046. this.indicators.map(function(indicator) {
  4047. indicator.refresh();
  4048. });
  4049. //以防slider类嵌套使用
  4050. if (this.options.snap && typeof this.options.snap === 'string') {
  4051. var items = this.scroller.querySelectorAll(this.options.snap);
  4052. this.itemLength = 0;
  4053. this.snaps = [];
  4054. for (var i = 0, len = items.length; i < len; i++) {
  4055. var item = items[i];
  4056. if (item.parentNode === this.scroller) {
  4057. this.itemLength++;
  4058. this.snaps.push(item);
  4059. }
  4060. }
  4061. this._initSnap(); //需要每次都_initSnap么。其实init的时候执行一次,后续resize的时候执行一次就行了吧.先这么做吧,如果影响性能,再调整
  4062. }
  4063. },
  4064. _momentum: function(current, distance, time, lowerMargin, wrapperSize, deceleration) {
  4065. var speed = parseFloat(Math.abs(distance) / time),
  4066. destination,
  4067. duration;
  4068. deceleration = deceleration === undefined ? 0.0006 : deceleration;
  4069. destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1);
  4070. duration = speed / deceleration;
  4071. if (destination < lowerMargin) {
  4072. destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin;
  4073. distance = Math.abs(destination - current);
  4074. duration = distance / speed;
  4075. } else if (destination > 0) {
  4076. destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0;
  4077. distance = Math.abs(current) + destination;
  4078. duration = distance / speed;
  4079. }
  4080. return {
  4081. destination: Math.round(destination),
  4082. duration: duration
  4083. };
  4084. },
  4085. _getTranslateStr: function(x, y) {
  4086. if (this.options.hardwareAccelerated) {
  4087. return 'translate3d(' + x + 'px,' + y + 'px,0px) ' + this.translateZ;
  4088. }
  4089. return 'translate(' + x + 'px,' + y + 'px) ';
  4090. },
  4091. //API
  4092. setStopped: function(stopped) {
  4093. // this.stopped = !!stopped;
  4094. // fixed ios双webview模式下拉刷新
  4095. if(stopped) {
  4096. this.disablePullupToRefresh();
  4097. this.disablePulldownToRefresh();
  4098. } else {
  4099. this.enablePullupToRefresh();
  4100. this.enablePulldownToRefresh();
  4101. }
  4102. },
  4103. setTranslate: function(x, y) {
  4104. this.x = x;
  4105. this.y = y;
  4106. this.scrollerStyle['webkitTransform'] = this._getTranslateStr(x, y);
  4107. if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
  4108. var parallaxY = y * this.options.parallaxRatio;
  4109. var scale = 1 + parallaxY / ((this.parallaxHeight - parallaxY) / 2);
  4110. if (scale > 1) {
  4111. this.parallaxImgStyle['opacity'] = 1 - parallaxY / 100 * this.options.parallaxRatio;
  4112. this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -parallaxY) + ' scale(' + scale + ',' + scale + ')';
  4113. } else {
  4114. this.parallaxImgStyle['opacity'] = 1;
  4115. this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -1) + ' scale(1,1)';
  4116. }
  4117. }
  4118. if (this.indicators) {
  4119. for (var i = this.indicators.length; i--;) {
  4120. this.indicators[i].updatePosition();
  4121. }
  4122. }
  4123. this.lastX = this.x;
  4124. this.lastY = this.y;
  4125. $.trigger(this.scroller, 'scroll', this);
  4126. },
  4127. reLayout: function() {
  4128. this.wrapper.offsetHeight;
  4129. var paddingLeft = parseFloat($.getStyles(this.wrapper, 'padding-left')) || 0;
  4130. var paddingRight = parseFloat($.getStyles(this.wrapper, 'padding-right')) || 0;
  4131. var paddingTop = parseFloat($.getStyles(this.wrapper, 'padding-top')) || 0;
  4132. var paddingBottom = parseFloat($.getStyles(this.wrapper, 'padding-bottom')) || 0;
  4133. var clientWidth = this.wrapper.clientWidth;
  4134. var clientHeight = this.wrapper.clientHeight;
  4135. this.scrollerWidth = this.scroller.offsetWidth;
  4136. this.scrollerHeight = this.scroller.offsetHeight;
  4137. this.wrapperWidth = clientWidth - paddingLeft - paddingRight;
  4138. this.wrapperHeight = clientHeight - paddingTop - paddingBottom;
  4139. this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
  4140. this.maxScrollY = Math.min(this.wrapperHeight - this.scrollerHeight, 0);
  4141. this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
  4142. this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
  4143. this._reLayout();
  4144. },
  4145. resetPosition: function(time) {
  4146. var x = this.x,
  4147. y = this.y;
  4148. time = time || 0;
  4149. if (!this.hasHorizontalScroll || this.x > 0) {
  4150. x = 0;
  4151. } else if (this.x < this.maxScrollX) {
  4152. x = this.maxScrollX;
  4153. }
  4154. if (!this.hasVerticalScroll || this.y > 0) {
  4155. y = 0;
  4156. } else if (this.y < this.maxScrollY) {
  4157. y = this.maxScrollY;
  4158. }
  4159. if (x == this.x && y == this.y) {
  4160. return false;
  4161. }
  4162. this.scrollTo(x, y, time, this.options.scrollEasing);
  4163. return true;
  4164. },
  4165. _reInit: function() {
  4166. var groups = this.wrapper.querySelectorAll('.' + CLASS_SCROLL);
  4167. for (var i = 0, len = groups.length; i < len; i++) {
  4168. if (groups[i].parentNode === this.wrapper) {
  4169. this.scroller = groups[i];
  4170. break;
  4171. }
  4172. }
  4173. this.scrollerStyle = this.scroller && this.scroller.style;
  4174. },
  4175. refresh: function() {
  4176. this._reInit();
  4177. this.reLayout();
  4178. $.trigger(this.scroller, 'refresh', this);
  4179. this.resetPosition();
  4180. },
  4181. scrollTo: function(x, y, time, easing) {
  4182. var easing = easing || ease.circular;
  4183. // this.isInTransition = time > 0 && (this.lastX != x || this.lastY != y);
  4184. //暂不严格判断x,y,否则会导致部分版本上不正常触发轮播
  4185. this.isInTransition = time > 0;
  4186. if (this.isInTransition) {
  4187. this._clearRequestAnimationFrame();
  4188. this._transitionTimingFunction(easing.style);
  4189. this._transitionTime(time);
  4190. this.setTranslate(x, y);
  4191. } else {
  4192. this.setTranslate(x, y);
  4193. }
  4194. },
  4195. scrollToBottom: function(time, easing) {
  4196. time = time || this.options.scrollTime;
  4197. this.scrollTo(0, this.maxScrollY, time, easing);
  4198. },
  4199. gotoPage: function(index) {
  4200. this._gotoPage(index);
  4201. },
  4202. destroy: function() {
  4203. this._initEvent(true); //detach
  4204. delete $.data[this.wrapper.getAttribute('data-scroll')];
  4205. this.wrapper.setAttribute('data-scroll', '');
  4206. }
  4207. });
  4208. //Indicator
  4209. var Indicator = function(scroller, options) {
  4210. this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
  4211. this.wrapperStyle = this.wrapper.style;
  4212. this.indicator = this.wrapper.children[0];
  4213. this.indicatorStyle = this.indicator.style;
  4214. this.scroller = scroller;
  4215. this.options = $.extend({
  4216. listenX: true,
  4217. listenY: true,
  4218. fade: false,
  4219. speedRatioX: 0,
  4220. speedRatioY: 0
  4221. }, options);
  4222. this.sizeRatioX = 1;
  4223. this.sizeRatioY = 1;
  4224. this.maxPosX = 0;
  4225. this.maxPosY = 0;
  4226. if (this.options.fade) {
  4227. this.wrapperStyle['webkitTransform'] = this.scroller.translateZ;
  4228. this.wrapperStyle['webkitTransitionDuration'] = this.options.fixedBadAndorid && $.os.isBadAndroid ? '0.001s' : '0ms';
  4229. this.wrapperStyle.opacity = '0';
  4230. }
  4231. }
  4232. Indicator.prototype = {
  4233. handleEvent: function(e) {
  4234. },
  4235. transitionTime: function(time) {
  4236. time = time || 0;
  4237. this.indicatorStyle['webkitTransitionDuration'] = time + 'ms';
  4238. if (this.scroller.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
  4239. this.indicatorStyle['webkitTransitionDuration'] = '0.001s';
  4240. }
  4241. },
  4242. transitionTimingFunction: function(easing) {
  4243. this.indicatorStyle['webkitTransitionTimingFunction'] = easing;
  4244. },
  4245. refresh: function() {
  4246. this.transitionTime();
  4247. if (this.options.listenX && !this.options.listenY) {
  4248. this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
  4249. } else if (this.options.listenY && !this.options.listenX) {
  4250. this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
  4251. } else {
  4252. this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
  4253. }
  4254. this.wrapper.offsetHeight; // force refresh
  4255. if (this.options.listenX) {
  4256. this.wrapperWidth = this.wrapper.clientWidth;
  4257. this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
  4258. this.indicatorStyle.width = this.indicatorWidth + 'px';
  4259. this.maxPosX = this.wrapperWidth - this.indicatorWidth;
  4260. this.minBoundaryX = 0;
  4261. this.maxBoundaryX = this.maxPosX;
  4262. this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
  4263. }
  4264. if (this.options.listenY) {
  4265. this.wrapperHeight = this.wrapper.clientHeight;
  4266. this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
  4267. this.indicatorStyle.height = this.indicatorHeight + 'px';
  4268. this.maxPosY = this.wrapperHeight - this.indicatorHeight;
  4269. this.minBoundaryY = 0;
  4270. this.maxBoundaryY = this.maxPosY;
  4271. this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
  4272. }
  4273. this.updatePosition();
  4274. },
  4275. updatePosition: function() {
  4276. var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
  4277. y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
  4278. if (x < this.minBoundaryX) {
  4279. this.width = Math.max(this.indicatorWidth + x, 8);
  4280. this.indicatorStyle.width = this.width + 'px';
  4281. x = this.minBoundaryX;
  4282. } else if (x > this.maxBoundaryX) {
  4283. this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
  4284. this.indicatorStyle.width = this.width + 'px';
  4285. x = this.maxPosX + this.indicatorWidth - this.width;
  4286. } else if (this.width != this.indicatorWidth) {
  4287. this.width = this.indicatorWidth;
  4288. this.indicatorStyle.width = this.width + 'px';
  4289. }
  4290. if (y < this.minBoundaryY) {
  4291. this.height = Math.max(this.indicatorHeight + y * 3, 8);
  4292. this.indicatorStyle.height = this.height + 'px';
  4293. y = this.minBoundaryY;
  4294. } else if (y > this.maxBoundaryY) {
  4295. this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
  4296. this.indicatorStyle.height = this.height + 'px';
  4297. y = this.maxPosY + this.indicatorHeight - this.height;
  4298. } else if (this.height != this.indicatorHeight) {
  4299. this.height = this.indicatorHeight;
  4300. this.indicatorStyle.height = this.height + 'px';
  4301. }
  4302. this.x = x;
  4303. this.y = y;
  4304. this.indicatorStyle['webkitTransform'] = this.scroller._getTranslateStr(x, y);
  4305. },
  4306. fade: function(val, hold) {
  4307. if (hold && !this.visible) {
  4308. return;
  4309. }
  4310. clearTimeout(this.fadeTimeout);
  4311. this.fadeTimeout = null;
  4312. var time = val ? 250 : 500,
  4313. delay = val ? 0 : 300;
  4314. val = val ? '1' : '0';
  4315. this.wrapperStyle['webkitTransitionDuration'] = time + 'ms';
  4316. this.fadeTimeout = setTimeout((function(val) {
  4317. this.wrapperStyle.opacity = val;
  4318. this.visible = +val;
  4319. }).bind(this, val), delay);
  4320. }
  4321. };
  4322. $.Scroll = Scroll;
  4323. $.fn.scroll = function(options) {
  4324. var scrollApis = [];
  4325. this.each(function() {
  4326. var scrollApi = null;
  4327. var self = this;
  4328. var id = self.getAttribute('data-scroll');
  4329. if (!id) {
  4330. id = ++$.uuid;
  4331. var _options = $.extend({}, options);
  4332. if (self.classList.contains('mui-segmented-control')) {
  4333. _options = $.extend(_options, {
  4334. scrollY: false,
  4335. scrollX: true,
  4336. indicators: false,
  4337. snap: '.mui-control-item'
  4338. });
  4339. }
  4340. $.data[id] = scrollApi = new Scroll(self, _options);
  4341. self.setAttribute('data-scroll', id);
  4342. } else {
  4343. scrollApi = $.data[id];
  4344. }
  4345. scrollApis.push(scrollApi);
  4346. });
  4347. return scrollApis.length === 1 ? scrollApis[0] : scrollApis;
  4348. };
  4349. })(mui, window, document);
  4350. (function($, window, document, undefined) {
  4351. var CLASS_VISIBILITY = 'mui-visibility';
  4352. var CLASS_HIDDEN = 'mui-hidden';
  4353. var PullRefresh = $.Scroll.extend($.extend({
  4354. handleEvent: function(e) {
  4355. this._super(e);
  4356. if (e.type === 'scrollbottom') {
  4357. if (e.target === this.scroller) {
  4358. this._scrollbottom();
  4359. }
  4360. }
  4361. },
  4362. _scrollbottom: function() {
  4363. if (!this.pulldown && !this.loading) {
  4364. this.pulldown = false;
  4365. this._initPullupRefresh();
  4366. this.pullupLoading();
  4367. }
  4368. },
  4369. _start: function(e) {
  4370. //仅下拉刷新在start阻止默认事件
  4371. if (e.touches && e.touches.length && e.touches[0].clientX > 30) {
  4372. e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
  4373. }
  4374. if (!this.loading) {
  4375. this.pulldown = this.pullPocket = this.pullCaption = this.pullLoading = false
  4376. }
  4377. this._super(e);
  4378. },
  4379. _drag: function(e) {
  4380. if (this.y >= 0 && this.disablePulldown && e.detail.direction === 'down') { //禁用下拉刷新
  4381. return;
  4382. }
  4383. this._super(e);
  4384. if (!this.pulldown && !this.loading && this.topPocket && e.detail.direction === 'down' && this.y >= 0) {
  4385. this._initPulldownRefresh();
  4386. }
  4387. if (this.pulldown) {
  4388. this._setCaption(this.y > this.options.down.height ? this.options.down.contentover : this.options.down.contentdown);
  4389. }
  4390. },
  4391. _reLayout: function() {
  4392. this.hasVerticalScroll = true;
  4393. this._super();
  4394. },
  4395. //API
  4396. resetPosition: function(time) {
  4397. if (this.pulldown && !this.disablePulldown) {
  4398. if (this.y >= this.options.down.height) {
  4399. this.pulldownLoading(undefined, time || 0);
  4400. return true;
  4401. } else {
  4402. !this.loading && this.topPocket.classList.remove(CLASS_VISIBILITY);
  4403. }
  4404. }
  4405. return this._super(time);
  4406. },
  4407. pulldownLoading: function(y, time) {
  4408. typeof y === 'undefined' && (y = this.options.down.height); //默认高度
  4409. this.scrollTo(0, y, time, this.options.bounceEasing);
  4410. if (this.loading) {
  4411. return;
  4412. }
  4413. // if (!this.pulldown) {
  4414. this._initPulldownRefresh();
  4415. // }
  4416. this._setCaption(this.options.down.contentrefresh);
  4417. this.loading = true;
  4418. this.indicators.map(function(indicator) {
  4419. indicator.fade(0);
  4420. });
  4421. var callback = this.options.down.callback;
  4422. callback && callback.call(this);
  4423. },
  4424. endPulldownToRefresh: function() {
  4425. var self = this;
  4426. if (self.topPocket && self.loading && this.pulldown) {
  4427. self.scrollTo(0, 0, self.options.bounceTime, self.options.bounceEasing);
  4428. self.loading = false;
  4429. self._setCaption(self.options.down.contentdown, true);
  4430. setTimeout(function() {
  4431. self.loading || self.topPocket.classList.remove(CLASS_VISIBILITY);
  4432. }, 350);
  4433. }
  4434. },
  4435. pullupLoading: function(callback, x, time) {
  4436. x = x || 0;
  4437. this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing);
  4438. if (this.loading) {
  4439. return;
  4440. }
  4441. this._initPullupRefresh();
  4442. this._setCaption(this.options.up.contentrefresh);
  4443. this.indicators.map(function(indicator) {
  4444. indicator.fade(0);
  4445. });
  4446. this.loading = true;
  4447. callback = callback || this.options.up.callback;
  4448. callback && callback.call(this);
  4449. },
  4450. endPullupToRefresh: function(finished) {
  4451. var self = this;
  4452. if (self.bottomPocket) { // && self.loading && !this.pulldown
  4453. self.loading = false;
  4454. if (finished) {
  4455. this.finished = true;
  4456. self._setCaption(self.options.up.contentnomore);
  4457. // self.bottomPocket.classList.remove(CLASS_VISIBILITY);
  4458. // self.bottomPocket.classList.add(CLASS_HIDDEN);
  4459. self.wrapper.removeEventListener('scrollbottom', self);
  4460. } else {
  4461. self._setCaption(self.options.up.contentdown);
  4462. // setTimeout(function() {
  4463. self.loading || self.bottomPocket.classList.remove(CLASS_VISIBILITY);
  4464. // }, 300);
  4465. }
  4466. }
  4467. },
  4468. disablePullupToRefresh: function() {
  4469. this._initPullupRefresh();
  4470. this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
  4471. this.wrapper.removeEventListener('scrollbottom', this);
  4472. },
  4473. disablePulldownToRefresh: function() {
  4474. this._initPulldownRefresh();
  4475. this.topPocket.className = 'mui-pull-top-pocket' + ' ' + CLASS_HIDDEN;
  4476. this.disablePulldown = true;
  4477. },
  4478. enablePulldownToRefresh: function() {
  4479. this._initPulldownRefresh();
  4480. this.topPocket.classList.remove(CLASS_HIDDEN);
  4481. this._setCaption(this.options.down.contentdown);
  4482. this.disablePulldown = false;
  4483. },
  4484. enablePullupToRefresh: function() {
  4485. this._initPullupRefresh();
  4486. this.bottomPocket.classList.remove(CLASS_HIDDEN);
  4487. this._setCaption(this.options.up.contentdown);
  4488. this.wrapper.addEventListener('scrollbottom', this);
  4489. },
  4490. refresh: function(isReset) {
  4491. if (isReset && this.finished) {
  4492. this.enablePullupToRefresh();
  4493. this.finished = false;
  4494. }
  4495. this._super();
  4496. },
  4497. }, $.PullRefresh));
  4498. $.fn.pullRefresh = function(options) {
  4499. if (this.length === 1) {
  4500. var self = this[0];
  4501. var pullRefreshApi = null;
  4502. var id = self.getAttribute('data-pullrefresh');
  4503. if (!id && typeof options === 'undefined') {
  4504. return false;
  4505. }
  4506. options = options || {};
  4507. if (!id) {
  4508. id = ++$.uuid;
  4509. $.data[id] = pullRefreshApi = new PullRefresh(self, options);
  4510. self.setAttribute('data-pullrefresh', id);
  4511. } else {
  4512. pullRefreshApi = $.data[id];
  4513. }
  4514. if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
  4515. pullRefreshApi.pulldownLoading(options.down.autoY);
  4516. } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
  4517. pullRefreshApi.pullupLoading();
  4518. }
  4519. //暂不提供这种调用方式吧
  4520. // if (typeof options === 'string') {
  4521. // var methodValue = pullRefreshApi[options].apply(pullRefreshApi, $.slice.call(arguments, 1));
  4522. // if (methodValue !== undefined) {
  4523. // return methodValue;
  4524. // }
  4525. // }
  4526. return pullRefreshApi;
  4527. }
  4528. };
  4529. })(mui, window, document);
  4530. /**
  4531. * snap 重构
  4532. * @param {Object} $
  4533. * @param {Object} window
  4534. */
  4535. (function($, window) {
  4536. var CLASS_SLIDER = 'mui-slider';
  4537. var CLASS_SLIDER_GROUP = 'mui-slider-group';
  4538. var CLASS_SLIDER_LOOP = 'mui-slider-loop';
  4539. var CLASS_SLIDER_INDICATOR = 'mui-slider-indicator';
  4540. var CLASS_ACTION_PREVIOUS = 'mui-action-previous';
  4541. var CLASS_ACTION_NEXT = 'mui-action-next';
  4542. var CLASS_SLIDER_ITEM = 'mui-slider-item';
  4543. var CLASS_ACTIVE = 'mui-active';
  4544. var SELECTOR_SLIDER_ITEM = '.' + CLASS_SLIDER_ITEM;
  4545. var SELECTOR_SLIDER_INDICATOR = '.' + CLASS_SLIDER_INDICATOR;
  4546. var SELECTOR_SLIDER_PROGRESS_BAR = '.mui-slider-progress-bar';
  4547. var Slider = $.Slider = $.Scroll.extend({
  4548. init: function(element, options) {
  4549. this._super(element, $.extend(true, {
  4550. fingers: 1,
  4551. interval: 0, //设置为0,则不定时轮播
  4552. scrollY: false,
  4553. scrollX: true,
  4554. indicators: false,
  4555. scrollTime: 1000,
  4556. startX: false,
  4557. slideTime: 0, //滑动动画时间
  4558. snap: SELECTOR_SLIDER_ITEM
  4559. }, options));
  4560. if (this.options.startX) {
  4561. // $.trigger(this.wrapper, 'scrollend', this);
  4562. }
  4563. },
  4564. _init: function() {
  4565. this._reInit();
  4566. if (this.scroller) {
  4567. this.scrollerStyle = this.scroller.style;
  4568. this.progressBar = this.wrapper.querySelector(SELECTOR_SLIDER_PROGRESS_BAR);
  4569. if (this.progressBar) {
  4570. this.progressBarWidth = this.progressBar.offsetWidth;
  4571. this.progressBarStyle = this.progressBar.style;
  4572. }
  4573. //忘记这个代码是干什么的了?
  4574. // this.x = this._getScroll();
  4575. // if (this.options.startX === false) {
  4576. // this.options.startX = this.x;
  4577. // }
  4578. //根据active修正startX
  4579. this._super();
  4580. this._initTimer();
  4581. }
  4582. },
  4583. _triggerSlide: function() {
  4584. var self = this;
  4585. self.isInTransition = false;
  4586. var page = self.currentPage;
  4587. self.slideNumber = self._fixedSlideNumber();
  4588. if (self.loop) {
  4589. if (self.slideNumber === 0) {
  4590. self.setTranslate(self.pages[1][0].x, 0);
  4591. } else if (self.slideNumber === self.itemLength - 3) {
  4592. self.setTranslate(self.pages[self.itemLength - 2][0].x, 0);
  4593. }
  4594. }
  4595. if (self.lastSlideNumber != self.slideNumber) {
  4596. self.lastSlideNumber = self.slideNumber;
  4597. self.lastPage = self.currentPage;
  4598. $.trigger(self.wrapper, 'slide', {
  4599. slideNumber: self.slideNumber
  4600. });
  4601. }
  4602. self._initTimer();
  4603. },
  4604. _handleSlide: function(e) {
  4605. var self = this;
  4606. if (e.target !== self.wrapper) {
  4607. return;
  4608. }
  4609. var detail = e.detail;
  4610. detail.slideNumber = detail.slideNumber || 0;
  4611. var temps = self.scroller.querySelectorAll(SELECTOR_SLIDER_ITEM);
  4612. var items = [];
  4613. for (var i = 0, len = temps.length; i < len; i++) {
  4614. var item = temps[i];
  4615. if (item.parentNode === self.scroller) {
  4616. items.push(item);
  4617. }
  4618. }
  4619. var _slideNumber = detail.slideNumber;
  4620. if (self.loop) {
  4621. _slideNumber += 1;
  4622. }
  4623. if (!self.wrapper.classList.contains('mui-segmented-control')) {
  4624. for (var i = 0, len = items.length; i < len; i++) {
  4625. var item = items[i];
  4626. if (item.parentNode === self.scroller) {
  4627. if (i === _slideNumber) {
  4628. item.classList.add(CLASS_ACTIVE);
  4629. } else {
  4630. item.classList.remove(CLASS_ACTIVE);
  4631. }
  4632. }
  4633. }
  4634. }
  4635. var indicatorWrap = self.wrapper.querySelector('.mui-slider-indicator');
  4636. if (indicatorWrap) {
  4637. if (indicatorWrap.getAttribute('data-scroll')) { //scroll
  4638. $(indicatorWrap).scroll().gotoPage(detail.slideNumber);
  4639. }
  4640. var indicators = indicatorWrap.querySelectorAll('.mui-indicator');
  4641. if (indicators.length > 0) { //图片轮播
  4642. for (var i = 0, len = indicators.length; i < len; i++) {
  4643. indicators[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
  4644. }
  4645. } else {
  4646. var number = indicatorWrap.querySelector('.mui-number span');
  4647. if (number) { //图文表格
  4648. number.innerText = (detail.slideNumber + 1);
  4649. } else { //segmented controls
  4650. var controlItems = indicatorWrap.querySelectorAll('.mui-control-item');
  4651. for (var i = 0, len = controlItems.length; i < len; i++) {
  4652. controlItems[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
  4653. }
  4654. }
  4655. }
  4656. }
  4657. e.stopPropagation();
  4658. },
  4659. _handleTabShow: function(e) {
  4660. var self = this;
  4661. self.gotoItem((e.detail.tabNumber || 0), self.options.slideTime);
  4662. },
  4663. _handleIndicatorTap: function(event) {
  4664. var self = this;
  4665. var target = event.target;
  4666. if (target.classList.contains(CLASS_ACTION_PREVIOUS) || target.classList.contains(CLASS_ACTION_NEXT)) {
  4667. self[target.classList.contains(CLASS_ACTION_PREVIOUS) ? 'prevItem' : 'nextItem']();
  4668. event.stopPropagation();
  4669. }
  4670. },
  4671. _initEvent: function(detach) {
  4672. var self = this;
  4673. self._super(detach);
  4674. var action = detach ? 'removeEventListener' : 'addEventListener';
  4675. self.wrapper[action]('slide', this);
  4676. self.wrapper[action]($.eventName('shown', 'tab'), this);
  4677. },
  4678. handleEvent: function(e) {
  4679. this._super(e);
  4680. switch (e.type) {
  4681. case 'slide':
  4682. this._handleSlide(e);
  4683. break;
  4684. case $.eventName('shown', 'tab'):
  4685. if (~this.snaps.indexOf(e.target)) { //避免嵌套监听错误的tab show
  4686. this._handleTabShow(e);
  4687. }
  4688. break;
  4689. }
  4690. },
  4691. _scrollend: function(e) {
  4692. this._super(e);
  4693. this._triggerSlide(e);
  4694. },
  4695. _drag: function(e) {
  4696. this._super(e);
  4697. var direction = e.detail.direction;
  4698. if (direction === 'left' || direction === 'right') {
  4699. //拖拽期间取消定时
  4700. var slidershowTimer = this.wrapper.getAttribute('data-slidershowTimer');
  4701. slidershowTimer && window.clearTimeout(slidershowTimer);
  4702. e.stopPropagation();
  4703. }
  4704. },
  4705. _initTimer: function() {
  4706. var self = this;
  4707. var slider = self.wrapper;
  4708. var interval = self.options.interval;
  4709. var slidershowTimer = slider.getAttribute('data-slidershowTimer');
  4710. slidershowTimer && window.clearTimeout(slidershowTimer);
  4711. if (interval) {
  4712. slidershowTimer = window.setTimeout(function() {
  4713. if (!slider) {
  4714. return;
  4715. }
  4716. //仅slider显示状态进行自动轮播
  4717. if (!!(slider.offsetWidth || slider.offsetHeight)) {
  4718. self.nextItem(true);
  4719. //下一个
  4720. }
  4721. self._initTimer();
  4722. }, interval);
  4723. slider.setAttribute('data-slidershowTimer', slidershowTimer);
  4724. }
  4725. },
  4726. _fixedSlideNumber: function(page) {
  4727. page = page || this.currentPage;
  4728. var slideNumber = page.pageX;
  4729. if (this.loop) {
  4730. if (page.pageX === 0) {
  4731. slideNumber = this.itemLength - 3;
  4732. } else if (page.pageX === (this.itemLength - 1)) {
  4733. slideNumber = 0;
  4734. } else {
  4735. slideNumber = page.pageX - 1;
  4736. }
  4737. }
  4738. return slideNumber;
  4739. },
  4740. _reLayout: function() {
  4741. this.hasHorizontalScroll = true;
  4742. this.loop = this.scroller.classList.contains(CLASS_SLIDER_LOOP);
  4743. this._super();
  4744. },
  4745. _getScroll: function() {
  4746. var result = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
  4747. return result ? result.x : 0;
  4748. },
  4749. _transitionEnd: function(e) {
  4750. if (e.target !== this.scroller || !this.isInTransition) {
  4751. return;
  4752. }
  4753. this._transitionTime();
  4754. this.isInTransition = false;
  4755. $.trigger(this.wrapper, 'scrollend', this);
  4756. },
  4757. _flick: function(e) {
  4758. if (!this.moved) { //无moved
  4759. return;
  4760. }
  4761. var detail = e.detail;
  4762. var direction = detail.direction;
  4763. this._clearRequestAnimationFrame();
  4764. this.isInTransition = true;
  4765. // if (direction === 'up' || direction === 'down') {
  4766. // this.resetPosition(this.options.bounceTime);
  4767. // return;
  4768. // }
  4769. if (e.type === 'flick') {
  4770. if (detail.deltaTime < 200) { //flick,太容易触发,额外校验一下deltaTime
  4771. this.x = this._getPage((this.slideNumber + (direction === 'right' ? -1 : 1)), true).x;
  4772. }
  4773. this.resetPosition(this.options.bounceTime);
  4774. } else if (e.type === 'dragend' && !detail.flick) {
  4775. this.resetPosition(this.options.bounceTime);
  4776. }
  4777. e.stopPropagation();
  4778. },
  4779. _initSnap: function() {
  4780. this.scrollerWidth = this.itemLength * this.scrollerWidth;
  4781. this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
  4782. this._super();
  4783. if (!this.currentPage.x) {
  4784. //当slider处于隐藏状态时,导致snap计算是错误的,临时先这么判断一下,后续要考虑解决所有scroll在隐藏状态下初始化属性不正确的问题
  4785. var currentPage = this.pages[this.loop ? 1 : 0];
  4786. currentPage = currentPage || this.pages[0];
  4787. if (!currentPage) {
  4788. return;
  4789. }
  4790. this.currentPage = currentPage[0];
  4791. this.slideNumber = 0;
  4792. this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? 0 : this.lastSlideNumber;
  4793. } else {
  4794. this.slideNumber = this._fixedSlideNumber();
  4795. this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? this.slideNumber : this.lastSlideNumber;
  4796. }
  4797. this.options.startX = this.currentPage.x || 0;
  4798. },
  4799. _getSnapX: function(offsetLeft) {
  4800. return Math.max(-offsetLeft, this.maxScrollX);
  4801. },
  4802. _getPage: function(slideNumber, isFlick) {
  4803. if (this.loop) {
  4804. if (slideNumber > (this.itemLength - (isFlick ? 2 : 3))) {
  4805. slideNumber = 1;
  4806. time = 0;
  4807. } else if (slideNumber < (isFlick ? -1 : 0)) {
  4808. slideNumber = this.itemLength - 2;
  4809. time = 0;
  4810. } else {
  4811. slideNumber += 1;
  4812. }
  4813. } else {
  4814. if (!isFlick) {
  4815. if (slideNumber > (this.itemLength - 1)) {
  4816. slideNumber = 0;
  4817. time = 0;
  4818. } else if (slideNumber < 0) {
  4819. slideNumber = this.itemLength - 1;
  4820. time = 0;
  4821. }
  4822. }
  4823. slideNumber = Math.min(Math.max(0, slideNumber), this.itemLength - 1);
  4824. }
  4825. return this.pages[slideNumber][0];
  4826. },
  4827. _gotoItem: function(slideNumber, time) {
  4828. this.currentPage = this._getPage(slideNumber, true); //此处传true。可保证程序切换时,动画与人手操作一致(第一张,最后一张的切换动画)
  4829. this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
  4830. if (time === 0) {
  4831. $.trigger(this.wrapper, 'scrollend', this);
  4832. }
  4833. },
  4834. //API
  4835. setTranslate: function(x, y) {
  4836. this._super(x, y);
  4837. var progressBar = this.progressBar;
  4838. if (progressBar) {
  4839. this.progressBarStyle.webkitTransform = this._getTranslateStr((-x * (this.progressBarWidth / this.wrapperWidth)), 0);
  4840. }
  4841. },
  4842. resetPosition: function(time) {
  4843. time = time || 0;
  4844. if (this.x > 0) {
  4845. this.x = 0;
  4846. } else if (this.x < this.maxScrollX) {
  4847. this.x = this.maxScrollX;
  4848. }
  4849. this.currentPage = this._nearestSnap(this.x);
  4850. this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
  4851. return true;
  4852. },
  4853. gotoItem: function(slideNumber, time) {
  4854. this._gotoItem(slideNumber, typeof time === 'undefined' ? this.options.scrollTime : time);
  4855. },
  4856. nextItem: function() {
  4857. this._gotoItem(this.slideNumber + 1, this.options.scrollTime);
  4858. },
  4859. prevItem: function() {
  4860. this._gotoItem(this.slideNumber - 1, this.options.scrollTime);
  4861. },
  4862. getSlideNumber: function() {
  4863. return this.slideNumber || 0;
  4864. },
  4865. _reInit: function() {
  4866. var groups = this.wrapper.querySelectorAll('.' + CLASS_SLIDER_GROUP);
  4867. for (var i = 0, len = groups.length; i < len; i++) {
  4868. if (groups[i].parentNode === this.wrapper) {
  4869. this.scroller = groups[i];
  4870. break;
  4871. }
  4872. }
  4873. this.scrollerStyle = this.scroller && this.scroller.style;
  4874. if (this.progressBar) {
  4875. this.progressBarWidth = this.progressBar.offsetWidth;
  4876. this.progressBarStyle = this.progressBar.style;
  4877. }
  4878. },
  4879. refresh: function(options) {
  4880. if (options) {
  4881. $.extend(this.options, options);
  4882. this._super();
  4883. this._initTimer();
  4884. } else {
  4885. this._super();
  4886. }
  4887. },
  4888. destroy: function() {
  4889. this._initEvent(true); //detach
  4890. delete $.data[this.wrapper.getAttribute('data-slider')];
  4891. this.wrapper.setAttribute('data-slider', '');
  4892. }
  4893. });
  4894. $.fn.slider = function(options) {
  4895. var slider = null;
  4896. this.each(function() {
  4897. var sliderElement = this;
  4898. if (!this.classList.contains(CLASS_SLIDER)) {
  4899. sliderElement = this.querySelector('.' + CLASS_SLIDER);
  4900. }
  4901. if (sliderElement && sliderElement.querySelector(SELECTOR_SLIDER_ITEM)) {
  4902. var id = sliderElement.getAttribute('data-slider');
  4903. if (!id) {
  4904. id = ++$.uuid;
  4905. $.data[id] = slider = new Slider(sliderElement, options);
  4906. sliderElement.setAttribute('data-slider', id);
  4907. } else {
  4908. slider = $.data[id];
  4909. if (slider && options) {
  4910. slider.refresh(options);
  4911. }
  4912. }
  4913. }
  4914. });
  4915. return slider;
  4916. };
  4917. $.ready(function() {
  4918. // setTimeout(function() {
  4919. $('.mui-slider').slider();
  4920. $('.mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control').scroll({
  4921. scrollY: false,
  4922. scrollX: true,
  4923. indicators: false,
  4924. snap: '.mui-control-item'
  4925. });
  4926. // }, 500); //临时处理slider宽度计算不正确的问题(初步确认是scrollbar导致的)
  4927. });
  4928. })(mui, window);
  4929. /**
  4930. * pullRefresh 5+
  4931. * @param {type} $
  4932. * @returns {undefined}
  4933. */
  4934. (function($, document) {
  4935. if (!($.os.plus)) { //仅在5+android支持多webview的使用
  4936. return;
  4937. }
  4938. $.plusReady(function() {
  4939. if (window.__NWin_Enable__ === false) { //不支持多webview,则不用5+下拉刷新
  4940. return;
  4941. }
  4942. var CLASS_PLUS_PULLREFRESH = 'mui-plus-pullrefresh';
  4943. var CLASS_VISIBILITY = 'mui-visibility';
  4944. var CLASS_HIDDEN = 'mui-hidden';
  4945. var CLASS_BLOCK = 'mui-block';
  4946. var CLASS_PULL_CAPTION = 'mui-pull-caption';
  4947. var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
  4948. var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
  4949. var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
  4950. var PlusPullRefresh = $.Class.extend({
  4951. init: function(element, options) {
  4952. this.element = element;
  4953. this.options = options;
  4954. this.wrapper = this.scroller = element;
  4955. this._init();
  4956. this._initPulldownRefreshEvent();
  4957. },
  4958. _init: function() {
  4959. var self = this;
  4960. //document.addEventListener('plusscrollbottom', this);
  4961. window.addEventListener('dragup', self);
  4962. document.addEventListener("plusscrollbottom", self);
  4963. self.scrollInterval = window.setInterval(function() {
  4964. if (self.isScroll && !self.loading) {
  4965. if (window.pageYOffset + window.innerHeight + 10 >= document.documentElement.scrollHeight) {
  4966. self.isScroll = false; //放在这里是因为快速滚动的话,有可能检测时,还没到底,所以只要有滚动,没到底之前一直检测高度变化
  4967. if (self.bottomPocket) {
  4968. self.pullupLoading();
  4969. }
  4970. }
  4971. }
  4972. }, 100);
  4973. },
  4974. _initPulldownRefreshEvent: function() {
  4975. var self = this;
  4976. $.plusReady(function() {
  4977. if (self.options.down.style == "circle") {
  4978. //单webview、原生转圈
  4979. self.options.webview = plus.webview.currentWebview();
  4980. self.options.webview.setPullToRefresh({
  4981. support: true,
  4982. color: self.options.down.color || '#2BD009',
  4983. height: self.options.down.height || '50px',
  4984. range: self.options.down.range || '100px',
  4985. style: 'circle',
  4986. offset: self.options.down.offset || '0px'
  4987. }, function() {
  4988. self.options.down.callback();
  4989. });
  4990. } else if (self.topPocket && self.options.webviewId) {
  4991. var webview = plus.webview.getWebviewById(self.options.webviewId); //子窗口
  4992. if (!webview) {
  4993. return;
  4994. }
  4995. self.options.webview = webview;
  4996. var downOptions = self.options.down;
  4997. var height = downOptions.height;
  4998. webview.addEventListener('close', function() {
  4999. var attrWebviewId = self.options.webviewId && self.options.webviewId.replace(/\//g, "_"); //替换所有"/"
  5000. self.element.removeAttribute('data-pullrefresh-plus-' + attrWebviewId);
  5001. });
  5002. webview.addEventListener("dragBounce", function(e) {
  5003. if (!self.pulldown) {
  5004. self._initPulldownRefresh();
  5005. } else {
  5006. self.pullPocket.classList.add(CLASS_BLOCK);
  5007. }
  5008. switch (e.status) {
  5009. case "beforeChangeOffset": //下拉可刷新状态
  5010. self._setCaption(downOptions.contentdown);
  5011. break;
  5012. case "afterChangeOffset": //松开可刷新状态
  5013. self._setCaption(downOptions.contentover);
  5014. break;
  5015. case "dragEndAfterChangeOffset": //正在刷新状态
  5016. //执行下拉刷新所在webview的回调函数
  5017. webview.evalJS("window.mui&&mui.options.pullRefresh.down.callback()");
  5018. self._setCaption(downOptions.contentrefresh);
  5019. break;
  5020. default:
  5021. break;
  5022. }
  5023. }, false);
  5024. webview.setBounce({
  5025. position: {
  5026. top: height * 2 + 'px'
  5027. },
  5028. changeoffset: {
  5029. top: height + 'px'
  5030. }
  5031. });
  5032. }
  5033. });
  5034. },
  5035. handleEvent: function(e) {
  5036. var self = this;
  5037. if (self.stopped) {
  5038. return;
  5039. }
  5040. self.isScroll = false;
  5041. if (e.type === 'dragup' || e.type === 'plusscrollbottom') {
  5042. self.isScroll = true;
  5043. setTimeout(function() {
  5044. self.isScroll = false;
  5045. }, 1000);
  5046. }
  5047. }
  5048. }).extend($.extend({
  5049. setStopped: function(stopped) { //该方法是子页面调用的
  5050. this.stopped = !!stopped;
  5051. // TODO 此处需要设置当前webview的bounce为none,目前5+有BUG
  5052. if (this.stopped) {
  5053. this.disablePullupToRefresh();
  5054. this.disablePulldownToRefresh();
  5055. } else {
  5056. this.enablePullupToRefresh();
  5057. this.enablePulldownToRefresh();
  5058. }
  5059. },
  5060. beginPulldown: function() {
  5061. var self = this;
  5062. $.plusReady(function() {
  5063. //这里延时的目的是为了保证下拉刷新组件初始化完成,后续应该做成有状态的
  5064. setTimeout(function() {
  5065. if (self.options.down.style == "circle") { //单webview下拉刷新
  5066. plus.webview.currentWebview().beginPullToRefresh();
  5067. } else { //双webview模式
  5068. var webview = self.options.webview;
  5069. if (webview) {
  5070. webview.setBounce({
  5071. offset: {
  5072. top: self.options.down.height + "px"
  5073. }
  5074. });
  5075. }
  5076. }
  5077. }, 15);
  5078. }.bind(this));
  5079. },
  5080. pulldownLoading: function() { //该方法是子页面调用的,兼容老的历史API
  5081. this.beginPulldown();
  5082. },
  5083. _pulldownLoading: function() { //该方法是父页面调用的
  5084. var self = this;
  5085. $.plusReady(function() {
  5086. var childWebview = plus.webview.getWebviewById(self.options.webviewId);
  5087. childWebview && childWebview.setBounce({
  5088. offset: {
  5089. top: self.options.down.height + "px"
  5090. }
  5091. });
  5092. });
  5093. },
  5094. endPulldown: function() {
  5095. var _wv = plus.webview.currentWebview();
  5096. //双webview的下拉刷新,需要修改父窗口提示信息
  5097. if (_wv.parent() && this.options.down.style !== "circle") {
  5098. _wv.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify({
  5099. webviewId: _wv.id
  5100. }) + "')._endPulldownToRefresh()");
  5101. } else {
  5102. _wv.endPullToRefresh();
  5103. }
  5104. },
  5105. endPulldownToRefresh: function() { //该方法是子页面调用的,兼容老的历史API
  5106. this.endPulldown();
  5107. },
  5108. _endPulldownToRefresh: function() { //该方法是父页面调用的
  5109. var self = this;
  5110. if (self.topPocket && self.options.webview) {
  5111. self.options.webview.endPullToRefresh(); //下拉刷新所在webview回弹
  5112. self.loading = false;
  5113. self._setCaption(self.options.down.contentdown, true);
  5114. setTimeout(function() {
  5115. self.loading || self.topPocket.classList.remove(CLASS_BLOCK);
  5116. }, 350);
  5117. }
  5118. },
  5119. beginPullup: function(callback) { //开始上拉加载
  5120. var self = this;
  5121. if (self.isLoading) return;
  5122. self.isLoading = true;
  5123. if (self.pulldown !== false) {
  5124. self._initPullupRefresh();
  5125. } else {
  5126. this.pullPocket.classList.add(CLASS_BLOCK);
  5127. }
  5128. setTimeout(function() {
  5129. self.pullLoading.classList.add(CLASS_VISIBILITY);
  5130. self.pullLoading.classList.remove(CLASS_HIDDEN);
  5131. self.pullCaption.innerHTML = ''; //修正5+里边第一次加载时,文字显示的bug(还会显示出来个“多”,猜测应该是渲染问题导致的)
  5132. self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH;
  5133. self.pullCaption.innerHTML = self.options.up.contentrefresh;
  5134. callback = callback || self.options.up.callback;
  5135. callback && callback.call(self);
  5136. }, 300);
  5137. },
  5138. pullupLoading: function(callback) { //兼容老的API
  5139. this.beginPullup(callback);
  5140. },
  5141. endPullup: function(finished) { //上拉加载结束
  5142. var self = this;
  5143. if (self.pullLoading) {
  5144. self.pullLoading.classList.remove(CLASS_VISIBILITY);
  5145. self.pullLoading.classList.add(CLASS_HIDDEN);
  5146. self.isLoading = false;
  5147. if (finished) {
  5148. self.finished = true;
  5149. self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
  5150. self.pullCaption.innerHTML = self.options.up.contentnomore;
  5151. //取消5+的plusscrollbottom事件
  5152. document.removeEventListener('plusscrollbottom', self);
  5153. window.removeEventListener('dragup', self);
  5154. } else { //初始化时隐藏,后续不再隐藏
  5155. self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
  5156. self.pullCaption.innerHTML = self.options.up.contentdown;
  5157. }
  5158. }
  5159. },
  5160. endPullupToRefresh: function(finished) { //上拉加载结束,兼容老的API
  5161. this.endPullup(finished);
  5162. },
  5163. disablePulldownToRefresh: function() {
  5164. var webview = plus.webview.currentWebview();
  5165. if (this.options.down.style && this.options.down.style == 'circle') { // 单webview模式禁止原生下拉刷新
  5166. this.options.webview.setPullToRefresh({
  5167. support: false,
  5168. style: 'circle'
  5169. });
  5170. } else { // 双webview模式禁止下拉刷新
  5171. webview.setStyle({
  5172. bounce: 'none'
  5173. });
  5174. webview.setBounce({
  5175. position: {
  5176. top: 'none'
  5177. }
  5178. });
  5179. }
  5180. },
  5181. enablePulldownToRefresh: function() {
  5182. var self = this,
  5183. webview = plus.webview.currentWebview(),
  5184. height = this.options.down.height;
  5185. // 单webview模式禁止原生下拉刷新
  5186. if (this.options.down.style && this.options.down.style == 'circle') {
  5187. webview.setPullToRefresh({
  5188. support: true,
  5189. height: height || '50px',
  5190. range: self.options.down.range || '100px',
  5191. style: 'circle',
  5192. offset: self.options.down.offset || '0px'
  5193. });
  5194. } else { // 重新初始化双webview模式下拉刷新
  5195. webview.setStyle({
  5196. bounce: 'vertical'
  5197. });
  5198. webview.setBounce({
  5199. position: {
  5200. top: height * 2 + 'px'
  5201. },
  5202. changeoffset: {
  5203. top: height + 'px'
  5204. }
  5205. });
  5206. }
  5207. },
  5208. disablePullupToRefresh: function() {
  5209. this._initPullupRefresh();
  5210. this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
  5211. window.removeEventListener('dragup', this);
  5212. },
  5213. enablePullupToRefresh: function() {
  5214. this._initPullupRefresh();
  5215. this.bottomPocket.classList.remove(CLASS_HIDDEN);
  5216. this.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
  5217. this.pullCaption.innerHTML = this.options.up.contentdown;
  5218. document.addEventListener("plusscrollbottom", this);
  5219. window.addEventListener('dragup', this);
  5220. },
  5221. scrollTo: function(x, y, time) {
  5222. $.scrollTo(y, time);
  5223. },
  5224. scrollToBottom: function(time) {
  5225. $.scrollTo(document.documentElement.scrollHeight, time);
  5226. },
  5227. refresh: function(isReset) {
  5228. if (isReset && this.finished) {
  5229. this.enablePullupToRefresh();
  5230. this.finished = false;
  5231. }
  5232. }
  5233. }, $.PullRefresh));
  5234. //override h5 pullRefresh
  5235. $.fn.pullRefresh_native = function(options) {
  5236. var self;
  5237. if (this.length === 0) {
  5238. self = document.createElement('div');
  5239. self.className = 'mui-content';
  5240. document.body.appendChild(self);
  5241. } else {
  5242. self = this[0];
  5243. }
  5244. var args = options;
  5245. //一个父需要支持多个子下拉刷新
  5246. options = options || {}
  5247. if (typeof options === 'string') {
  5248. options = $.parseJSON(options);
  5249. };
  5250. !options.webviewId && (options.webviewId = (plus.webview.currentWebview().id || plus.webview.currentWebview().getURL()));
  5251. var pullRefreshApi = null;
  5252. var attrWebviewId = options.webviewId && options.webviewId.replace(/\//g, "_"); //替换所有"/"
  5253. var id = self.getAttribute('data-pullrefresh-plus-' + attrWebviewId);
  5254. if (!id && typeof args === 'undefined') {
  5255. return false;
  5256. }
  5257. if (!id) { //避免重复初始化5+ pullrefresh
  5258. id = ++$.uuid;
  5259. self.setAttribute('data-pullrefresh-plus-' + attrWebviewId, id);
  5260. document.body.classList.add(CLASS_PLUS_PULLREFRESH);
  5261. $.data[id] = pullRefreshApi = new PlusPullRefresh(self, options);
  5262. } else {
  5263. pullRefreshApi = $.data[id];
  5264. }
  5265. if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
  5266. //pullRefreshApi._pulldownLoading(); //parent webview
  5267. pullRefreshApi.beginPulldown();
  5268. } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
  5269. pullRefreshApi.beginPullup();
  5270. }
  5271. return pullRefreshApi;
  5272. };
  5273. });
  5274. })(mui, document);
  5275. /**
  5276. * off-canvas
  5277. * @param {type} $
  5278. * @param {type} window
  5279. * @param {type} document
  5280. * @param {type} action
  5281. * @returns {undefined}
  5282. */
  5283. (function($, window, document, name) {
  5284. var CLASS_OFF_CANVAS_LEFT = 'mui-off-canvas-left';
  5285. var CLASS_OFF_CANVAS_RIGHT = 'mui-off-canvas-right';
  5286. var CLASS_ACTION_BACKDROP = 'mui-off-canvas-backdrop';
  5287. var CLASS_OFF_CANVAS_WRAP = 'mui-off-canvas-wrap';
  5288. var CLASS_SLIDE_IN = 'mui-slide-in';
  5289. var CLASS_ACTIVE = 'mui-active';
  5290. var CLASS_TRANSITIONING = 'mui-transitioning';
  5291. var SELECTOR_INNER_WRAP = '.mui-inner-wrap';
  5292. var OffCanvas = $.Class.extend({
  5293. init: function(element, options) {
  5294. this.wrapper = this.element = element;
  5295. this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
  5296. this.classList = this.wrapper.classList;
  5297. if (this.scroller) {
  5298. this.options = $.extend(true, {
  5299. dragThresholdX: 10,
  5300. scale: 0.8,
  5301. opacity: 0.1,
  5302. preventDefaultException: {
  5303. tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
  5304. },
  5305. }, options);
  5306. document.body.classList.add('mui-fullscreen'); //fullscreen
  5307. this.refresh();
  5308. this.initEvent();
  5309. }
  5310. },
  5311. _preventDefaultException: function(el, exceptions) {
  5312. for (var i in exceptions) {
  5313. if (exceptions[i].test(el[i])) {
  5314. return true;
  5315. }
  5316. }
  5317. return false;
  5318. },
  5319. refresh: function(offCanvas) {
  5320. // offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE);
  5321. this.slideIn = this.classList.contains(CLASS_SLIDE_IN);
  5322. this.scalable = this.classList.contains('mui-scalable') && !this.slideIn;
  5323. this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
  5324. // !offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING);
  5325. // !offCanvas && this.scroller.setAttribute('style', '');
  5326. this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT);
  5327. this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT);
  5328. if (offCanvas) {
  5329. if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
  5330. this.offCanvasLeft = offCanvas;
  5331. } else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
  5332. this.offCanvasRight = offCanvas;
  5333. }
  5334. } else {
  5335. this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT);
  5336. this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT);
  5337. }
  5338. this.offCanvasRightWidth = this.offCanvasLeftWidth = 0;
  5339. this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false;
  5340. if (this.offCanvasRight) {
  5341. this.offCanvasRightWidth = this.offCanvasRight.offsetWidth;
  5342. this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper);
  5343. // this.offCanvasRight.classList.remove(CLASS_TRANSITIONING);
  5344. // this.offCanvasRight.classList.remove(CLASS_ACTIVE);
  5345. // this.offCanvasRight.setAttribute('style', '');
  5346. }
  5347. if (this.offCanvasLeft) {
  5348. this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth;
  5349. this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper);
  5350. // this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING);
  5351. // this.offCanvasLeft.classList.remove(CLASS_ACTIVE);
  5352. // this.offCanvasLeft.setAttribute('style', '');
  5353. }
  5354. this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP);
  5355. this.options.dragThresholdX = this.options.dragThresholdX || 10;
  5356. this.visible = false;
  5357. this.startX = null;
  5358. this.lastX = null;
  5359. this.offsetX = null;
  5360. this.lastTranslateX = null;
  5361. },
  5362. handleEvent: function(e) {
  5363. switch (e.type) {
  5364. case $.EVENT_START:
  5365. e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
  5366. break;
  5367. case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况
  5368. if (e.target === this.scroller) {
  5369. this._dispatchEvent();
  5370. }
  5371. break;
  5372. case 'drag':
  5373. var detail = e.detail;
  5374. if (!this.startX) {
  5375. this.startX = detail.center.x;
  5376. this.lastX = this.startX;
  5377. } else {
  5378. this.lastX = detail.center.x;
  5379. }
  5380. if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) {
  5381. if (this.slideIn) {
  5382. this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
  5383. if (this.classList.contains(CLASS_ACTIVE)) {
  5384. if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) {
  5385. this.offCanvas = this.offCanvasRight;
  5386. this.offCanvasWidth = this.offCanvasRightWidth;
  5387. } else {
  5388. this.offCanvas = this.offCanvasLeft;
  5389. this.offCanvasWidth = this.offCanvasLeftWidth;
  5390. }
  5391. } else {
  5392. if (detail.direction === 'left' && this.offCanvasRight) {
  5393. this.offCanvas = this.offCanvasRight;
  5394. this.offCanvasWidth = this.offCanvasRightWidth;
  5395. } else if (detail.direction === 'right' && this.offCanvasLeft) {
  5396. this.offCanvas = this.offCanvasLeft;
  5397. this.offCanvasWidth = this.offCanvasLeftWidth;
  5398. } else {
  5399. this.scroller = null;
  5400. }
  5401. }
  5402. } else {
  5403. if (this.classList.contains(CLASS_ACTIVE)) {
  5404. if (detail.direction === 'left') {
  5405. this.offCanvas = this.offCanvasLeft;
  5406. this.offCanvasWidth = this.offCanvasLeftWidth;
  5407. } else {
  5408. this.offCanvas = this.offCanvasRight;
  5409. this.offCanvasWidth = this.offCanvasRightWidth;
  5410. }
  5411. } else {
  5412. if (detail.direction === 'right') {
  5413. this.offCanvas = this.offCanvasLeft;
  5414. this.offCanvasWidth = this.offCanvasLeftWidth;
  5415. } else {
  5416. this.offCanvas = this.offCanvasRight;
  5417. this.offCanvasWidth = this.offCanvasRightWidth;
  5418. }
  5419. }
  5420. }
  5421. if (this.offCanvas && this.scroller) {
  5422. this.startX = this.lastX;
  5423. this.isDragging = true;
  5424. $.gestures.session.lockDirection = true; //锁定方向
  5425. $.gestures.session.startDirection = detail.direction;
  5426. this.offCanvas.classList.remove(CLASS_TRANSITIONING);
  5427. this.scroller.classList.remove(CLASS_TRANSITIONING);
  5428. this.offsetX = this.getTranslateX();
  5429. this._initOffCanvasVisible();
  5430. }
  5431. }
  5432. if (this.isDragging) {
  5433. this.updateTranslate(this.offsetX + (this.lastX - this.startX));
  5434. detail.gesture.preventDefault();
  5435. e.stopPropagation();
  5436. }
  5437. break;
  5438. case 'dragend':
  5439. if (this.isDragging) {
  5440. var detail = e.detail;
  5441. var direction = detail.direction;
  5442. this.isDragging = false;
  5443. this.offCanvas.classList.add(CLASS_TRANSITIONING);
  5444. this.scroller.classList.add(CLASS_TRANSITIONING);
  5445. var ratio = 0;
  5446. var x = this.getTranslateX();
  5447. if (!this.slideIn) {
  5448. if (x >= 0) {
  5449. ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
  5450. } else {
  5451. ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
  5452. }
  5453. if (ratio === 0) {
  5454. this.openPercentage(0);
  5455. this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch
  5456. return;
  5457. }
  5458. if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开
  5459. this.openPercentage(100);
  5460. } else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭
  5461. this.openPercentage(0);
  5462. } else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭
  5463. this.openPercentage(0);
  5464. } else if (direction === 'right' && ratio < 0.5) { //右滑还原打开
  5465. this.openPercentage(-100);
  5466. } else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开
  5467. this.openPercentage(-100);
  5468. } else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭
  5469. this.openPercentage(0);
  5470. } else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭
  5471. this.openPercentage(0);
  5472. } else if (direction === 'left' && ratio > 0.5) { //左滑还原打开
  5473. this.openPercentage(100);
  5474. } else { //默认关闭
  5475. this.openPercentage(0);
  5476. }
  5477. if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch
  5478. this._dispatchEvent();
  5479. }
  5480. } else {
  5481. if (x >= 0) {
  5482. ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
  5483. } else {
  5484. ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
  5485. }
  5486. if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开
  5487. this.openPercentage(100);
  5488. } else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭
  5489. this.openPercentage(0);
  5490. } else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭
  5491. this.openPercentage(0);
  5492. } else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开
  5493. this.openPercentage(-100);
  5494. } else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开
  5495. this.openPercentage(-100);
  5496. } else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭
  5497. this.openPercentage(0);
  5498. } else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭
  5499. this.openPercentage(0);
  5500. } else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开
  5501. this.openPercentage(100);
  5502. } else {
  5503. this.openPercentage(0);
  5504. }
  5505. if (ratio === 1 || ratio === -1 || ratio === 0) {
  5506. this._dispatchEvent();
  5507. return;
  5508. }
  5509. }
  5510. }
  5511. break;
  5512. }
  5513. },
  5514. _dispatchEvent: function() {
  5515. if (this.classList.contains(CLASS_ACTIVE)) {
  5516. $.trigger(this.wrapper, 'shown', this);
  5517. } else {
  5518. $.trigger(this.wrapper, 'hidden', this);
  5519. }
  5520. },
  5521. _initOffCanvasVisible: function() {
  5522. if (!this.visible) {
  5523. this.visible = true;
  5524. if (this.offCanvasLeft) {
  5525. this.offCanvasLeft.style.visibility = 'visible';
  5526. }
  5527. if (this.offCanvasRight) {
  5528. this.offCanvasRight.style.visibility = 'visible';
  5529. }
  5530. }
  5531. },
  5532. initEvent: function() {
  5533. var self = this;
  5534. if (self.backdrop) {
  5535. self.backdrop.addEventListener('tap', function(e) {
  5536. self.close();
  5537. e.detail.gesture.preventDefault();
  5538. });
  5539. }
  5540. if (this.classList.contains('mui-draggable')) {
  5541. this.wrapper.addEventListener($.EVENT_START, this); //临时处理
  5542. this.wrapper.addEventListener('drag', this);
  5543. this.wrapper.addEventListener('dragend', this);
  5544. }
  5545. this.wrapper.addEventListener('webkitTransitionEnd', this);
  5546. },
  5547. openPercentage: function(percentage) {
  5548. var p = percentage / 100;
  5549. if (!this.slideIn) {
  5550. if (this.offCanvasLeft && percentage >= 0) {
  5551. this.updateTranslate(this.offCanvasLeftWidth * p);
  5552. this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
  5553. } else if (this.offCanvasRight && percentage <= 0) {
  5554. this.updateTranslate(this.offCanvasRightWidth * p);
  5555. this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
  5556. }
  5557. this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
  5558. } else {
  5559. if (this.offCanvasLeft && percentage >= 0) {
  5560. p = p === 0 ? -1 : 0;
  5561. this.updateTranslate(this.offCanvasLeftWidth * p);
  5562. this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
  5563. } else if (this.offCanvasRight && percentage <= 0) {
  5564. p = p === 0 ? 1 : 0;
  5565. this.updateTranslate(this.offCanvasRightWidth * p);
  5566. this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
  5567. }
  5568. this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
  5569. }
  5570. },
  5571. updateTranslate: function(x) {
  5572. if (x !== this.lastTranslateX) {
  5573. if (!this.slideIn) {
  5574. if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) {
  5575. this.setTranslateX(0);
  5576. return;
  5577. }
  5578. if (this.leftShowing && x > this.offCanvasLeftWidth) {
  5579. this.setTranslateX(this.offCanvasLeftWidth);
  5580. return;
  5581. }
  5582. if (this.rightShowing && x < -this.offCanvasRightWidth) {
  5583. this.setTranslateX(-this.offCanvasRightWidth);
  5584. return;
  5585. }
  5586. this.setTranslateX(x);
  5587. if (x >= 0) {
  5588. this.leftShowing = true;
  5589. this.rightShowing = false;
  5590. if (x > 0) {
  5591. if (this.offCanvasLeft) {
  5592. $.each(this.offCanvasLefts, function(index, offCanvas) {
  5593. if (offCanvas === this.offCanvasLeft) {
  5594. this.offCanvasLeft.style.zIndex = 0;
  5595. } else {
  5596. offCanvas.style.zIndex = -1;
  5597. }
  5598. }.bind(this));
  5599. }
  5600. if (this.offCanvasRight) {
  5601. this.offCanvasRight.style.zIndex = -1;
  5602. }
  5603. }
  5604. } else {
  5605. this.rightShowing = true;
  5606. this.leftShowing = false;
  5607. if (this.offCanvasRight) {
  5608. $.each(this.offCanvasRights, function(index, offCanvas) {
  5609. if (offCanvas === this.offCanvasRight) {
  5610. offCanvas.style.zIndex = 0;
  5611. } else {
  5612. offCanvas.style.zIndex = -1;
  5613. }
  5614. }.bind(this));
  5615. }
  5616. if (this.offCanvasLeft) {
  5617. this.offCanvasLeft.style.zIndex = -1;
  5618. }
  5619. }
  5620. } else {
  5621. if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
  5622. if (x < 0) {
  5623. this.setTranslateX(0);
  5624. return;
  5625. }
  5626. if (x > this.offCanvasRightWidth) {
  5627. this.setTranslateX(this.offCanvasRightWidth);
  5628. return;
  5629. }
  5630. } else {
  5631. if (x > 0) {
  5632. this.setTranslateX(0);
  5633. return;
  5634. }
  5635. if (x < -this.offCanvasLeftWidth) {
  5636. this.setTranslateX(-this.offCanvasLeftWidth);
  5637. return;
  5638. }
  5639. }
  5640. this.setTranslateX(x);
  5641. }
  5642. this.lastTranslateX = x;
  5643. }
  5644. },
  5645. setTranslateX: $.animationFrame(function(x) {
  5646. if (this.scroller) {
  5647. if (this.scalable && this.offCanvas.parentNode === this.wrapper) {
  5648. var percent = Math.abs(x) / this.offCanvasWidth;
  5649. var zoomOutScale = 1 - (1 - this.options.scale) * percent;
  5650. var zoomInScale = this.options.scale + (1 - this.options.scale) * percent;
  5651. var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent;
  5652. var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent;
  5653. if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
  5654. this.offCanvas.style.webkitTransformOrigin = '-100%';
  5655. this.scroller.style.webkitTransformOrigin = 'left';
  5656. } else {
  5657. this.offCanvas.style.webkitTransformOrigin = '200%';
  5658. this.scroller.style.webkitTransformOrigin = 'right';
  5659. }
  5660. this.offCanvas.style.opacity = zoomInOpacity;
  5661. this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')';
  5662. this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')';
  5663. } else {
  5664. if (this.slideIn) {
  5665. this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
  5666. } else {
  5667. this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
  5668. }
  5669. }
  5670. }
  5671. }),
  5672. getTranslateX: function() {
  5673. if (this.offCanvas) {
  5674. var scroller = this.slideIn ? this.offCanvas : this.scroller;
  5675. var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform'));
  5676. return (result && result.x) || 0;
  5677. }
  5678. return 0;
  5679. },
  5680. isShown: function(direction) {
  5681. var shown = false;
  5682. if (!this.slideIn) {
  5683. var x = this.getTranslateX();
  5684. if (direction === 'right') {
  5685. shown = this.classList.contains(CLASS_ACTIVE) && x < 0;
  5686. } else if (direction === 'left') {
  5687. shown = this.classList.contains(CLASS_ACTIVE) && x > 0;
  5688. } else {
  5689. shown = this.classList.contains(CLASS_ACTIVE) && x !== 0;
  5690. }
  5691. } else {
  5692. if (direction === 'left') {
  5693. shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
  5694. } else if (direction === 'right') {
  5695. shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE);
  5696. } else {
  5697. shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE));
  5698. }
  5699. }
  5700. return shown;
  5701. },
  5702. close: function() {
  5703. this._initOffCanvasVisible();
  5704. this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
  5705. this.offCanvasWidth = this.offCanvas.offsetWidth;
  5706. if (this.scroller) {
  5707. this.offCanvas.offsetHeight;
  5708. this.offCanvas.classList.add(CLASS_TRANSITIONING);
  5709. this.scroller.classList.add(CLASS_TRANSITIONING);
  5710. this.openPercentage(0);
  5711. }
  5712. },
  5713. show: function(direction) {
  5714. this._initOffCanvasVisible();
  5715. if (this.isShown(direction)) {
  5716. return false;
  5717. }
  5718. if (!direction) {
  5719. direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left';
  5720. }
  5721. if (direction === 'right') {
  5722. this.offCanvas = this.offCanvasRight;
  5723. this.offCanvasWidth = this.offCanvasRightWidth;
  5724. } else {
  5725. this.offCanvas = this.offCanvasLeft;
  5726. this.offCanvasWidth = this.offCanvasLeftWidth;
  5727. }
  5728. if (this.scroller) {
  5729. this.offCanvas.offsetHeight;
  5730. this.offCanvas.classList.add(CLASS_TRANSITIONING);
  5731. this.scroller.classList.add(CLASS_TRANSITIONING);
  5732. this.openPercentage(direction === 'left' ? 100 : -100);
  5733. }
  5734. return true;
  5735. },
  5736. toggle: function(directionOrOffCanvas) {
  5737. var direction = directionOrOffCanvas;
  5738. if (directionOrOffCanvas && directionOrOffCanvas.classList) {
  5739. direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right';
  5740. this.refresh(directionOrOffCanvas);
  5741. }
  5742. if (!this.show(direction)) {
  5743. this.close();
  5744. }
  5745. }
  5746. });
  5747. //hash to offcanvas
  5748. var findOffCanvasContainer = function(target) {
  5749. parentNode = target.parentNode;
  5750. if (parentNode) {
  5751. if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
  5752. return parentNode;
  5753. } else {
  5754. parentNode = parentNode.parentNode;
  5755. if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
  5756. return parentNode;
  5757. }
  5758. }
  5759. }
  5760. };
  5761. var handle = function(event, target) {
  5762. if (target.tagName === 'A' && target.hash) {
  5763. var offcanvas = document.getElementById(target.hash.replace('#', ''));
  5764. if (offcanvas) {
  5765. var container = findOffCanvasContainer(offcanvas);
  5766. if (container) {
  5767. $.targets._container = container;
  5768. return offcanvas;
  5769. }
  5770. }
  5771. }
  5772. return false;
  5773. };
  5774. $.registerTarget({
  5775. name: name,
  5776. index: 60,
  5777. handle: handle,
  5778. target: false,
  5779. isReset: false,
  5780. isContinue: true
  5781. });
  5782. window.addEventListener('tap', function(e) {
  5783. if (!$.targets.offcanvas) {
  5784. return;
  5785. }
  5786. //TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好
  5787. var target = e.target;
  5788. for (; target && target !== document; target = target.parentNode) {
  5789. if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) {
  5790. e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange
  5791. $($.targets._container).offCanvas().toggle($.targets.offcanvas);
  5792. $.targets.offcanvas = $.targets._container = null;
  5793. break;
  5794. }
  5795. }
  5796. });
  5797. $.fn.offCanvas = function(options) {
  5798. var offCanvasApis = [];
  5799. this.each(function() {
  5800. var offCanvasApi = null;
  5801. var self = this;
  5802. //hack old version
  5803. if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
  5804. self = findOffCanvasContainer(self);
  5805. }
  5806. var id = self.getAttribute('data-offCanvas');
  5807. if (!id) {
  5808. id = ++$.uuid;
  5809. $.data[id] = offCanvasApi = new OffCanvas(self, options);
  5810. self.setAttribute('data-offCanvas', id);
  5811. } else {
  5812. offCanvasApi = $.data[id];
  5813. }
  5814. if (options === 'show' || options === 'close' || options === 'toggle') {
  5815. offCanvasApi.toggle();
  5816. }
  5817. offCanvasApis.push(offCanvasApi);
  5818. });
  5819. return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis;
  5820. };
  5821. $.ready(function() {
  5822. $('.mui-off-canvas-wrap').offCanvas();
  5823. });
  5824. })(mui, window, document, 'offcanvas');
  5825. /**
  5826. * actions
  5827. * @param {type} $
  5828. * @param {type} name
  5829. * @returns {undefined}
  5830. */
  5831. (function($, name) {
  5832. var CLASS_ACTION = 'mui-action';
  5833. var handle = function(event, target) {
  5834. var className = target.className || '';
  5835. if (typeof className !== 'string') { //svg className(SVGAnimatedString)
  5836. className = '';
  5837. }
  5838. if (className && ~className.indexOf(CLASS_ACTION)) {
  5839. if (target.classList.contains('mui-action-back')) {
  5840. event.preventDefault();
  5841. }
  5842. return target;
  5843. }
  5844. return false;
  5845. };
  5846. $.registerTarget({
  5847. name: name,
  5848. index: 50,
  5849. handle: handle,
  5850. target: false,
  5851. isContinue: true
  5852. });
  5853. })(mui, 'action');
  5854. /**
  5855. * Modals
  5856. * @param {type} $
  5857. * @param {type} window
  5858. * @param {type} document
  5859. * @param {type} name
  5860. * @returns {undefined}
  5861. */
  5862. (function($, window, document, name) {
  5863. var CLASS_MODAL = 'mui-modal';
  5864. var handle = function(event, target) {
  5865. if (target.tagName === 'A' && target.hash) {
  5866. var modal = document.getElementById(target.hash.replace('#', ''));
  5867. if (modal && modal.classList.contains(CLASS_MODAL)) {
  5868. return modal;
  5869. }
  5870. }
  5871. return false;
  5872. };
  5873. $.registerTarget({
  5874. name: name,
  5875. index: 50,
  5876. handle: handle,
  5877. target: false,
  5878. isReset: false,
  5879. isContinue: true
  5880. });
  5881. window.addEventListener('tap', function(event) {
  5882. if ($.targets.modal) {
  5883. event.detail.gesture.preventDefault(); //fixed hashchange
  5884. $.targets.modal.classList.toggle('mui-active');
  5885. }
  5886. });
  5887. })(mui, window, document, 'modal');
  5888. /**
  5889. * Popovers
  5890. * @param {type} $
  5891. * @param {type} window
  5892. * @param {type} document
  5893. * @param {type} name
  5894. * @param {type} undefined
  5895. * @returns {undefined}
  5896. */
  5897. (function($, window, document, name) {
  5898. var CLASS_POPOVER = 'mui-popover';
  5899. var CLASS_POPOVER_ARROW = 'mui-popover-arrow';
  5900. var CLASS_ACTION_POPOVER = 'mui-popover-action';
  5901. var CLASS_BACKDROP = 'mui-backdrop';
  5902. var CLASS_BAR_POPOVER = 'mui-bar-popover';
  5903. var CLASS_BAR_BACKDROP = 'mui-bar-backdrop';
  5904. var CLASS_ACTION_BACKDROP = 'mui-backdrop-action';
  5905. var CLASS_ACTIVE = 'mui-active';
  5906. var CLASS_BOTTOM = 'mui-bottom';
  5907. var handle = function(event, target) {
  5908. if (target.tagName === 'A' && target.hash) {
  5909. $.targets._popover = document.getElementById(target.hash.replace('#', ''));
  5910. if ($.targets._popover && $.targets._popover.classList.contains(CLASS_POPOVER)) {
  5911. return target;
  5912. } else {
  5913. $.targets._popover = null;
  5914. }
  5915. }
  5916. return false;
  5917. };
  5918. $.registerTarget({
  5919. name: name,
  5920. index: 60,
  5921. handle: handle,
  5922. target: false,
  5923. isReset: false,
  5924. isContinue: true
  5925. });
  5926. var onPopoverShown = function(e) {
  5927. this.removeEventListener('webkitTransitionEnd', onPopoverShown);
  5928. this.addEventListener($.EVENT_MOVE, $.preventDefault);
  5929. $.trigger(this, 'shown', this);
  5930. }
  5931. var onPopoverHidden = function(e) {
  5932. setStyle(this, 'none');
  5933. this.removeEventListener('webkitTransitionEnd', onPopoverHidden);
  5934. this.removeEventListener($.EVENT_MOVE, $.preventDefault);
  5935. $.trigger(this, 'hidden', this);
  5936. };
  5937. var backdrop = (function() {
  5938. var element = document.createElement('div');
  5939. element.classList.add(CLASS_BACKDROP);
  5940. element.addEventListener($.EVENT_MOVE, $.preventDefault);
  5941. element.addEventListener('tap', function(e) {
  5942. var popover = $.targets._popover;
  5943. if (popover) {
  5944. popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
  5945. popover.classList.remove(CLASS_ACTIVE);
  5946. removeBackdrop(popover);
  5947. }
  5948. });
  5949. return element;
  5950. }());
  5951. var removeBackdropTimer;
  5952. var removeBackdrop = function(popover) {
  5953. backdrop.setAttribute('style', 'opacity:0');
  5954. $.targets.popover = $.targets._popover = null; //reset
  5955. removeBackdropTimer = $.later(function() {
  5956. if (!popover.classList.contains(CLASS_ACTIVE) && backdrop.parentNode && backdrop.parentNode === document.body) {
  5957. document.body.removeChild(backdrop);
  5958. }
  5959. }, 350);
  5960. };
  5961. window.addEventListener('tap', function(e) {
  5962. if (!$.targets.popover) {
  5963. return;
  5964. }
  5965. var toggle = false;
  5966. var target = e.target;
  5967. for (; target && target !== document; target = target.parentNode) {
  5968. if (target === $.targets.popover) {
  5969. toggle = true;
  5970. }
  5971. }
  5972. if (toggle) {
  5973. e.detail.gesture.preventDefault(); //fixed hashchange
  5974. togglePopover($.targets._popover, $.targets.popover);
  5975. }
  5976. });
  5977. var togglePopover = function(popover, anchor, state) {
  5978. if ((state === 'show' && popover.classList.contains(CLASS_ACTIVE)) || (state === 'hide' && !popover.classList.contains(CLASS_ACTIVE))) {
  5979. return;
  5980. }
  5981. removeBackdropTimer && removeBackdropTimer.cancel(); //取消remove的timer
  5982. //remove一遍,以免来回快速切换,导致webkitTransitionEnd不触发,无法remove
  5983. popover.removeEventListener('webkitTransitionEnd', onPopoverShown);
  5984. popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
  5985. backdrop.classList.remove(CLASS_BAR_BACKDROP);
  5986. backdrop.classList.remove(CLASS_ACTION_BACKDROP);
  5987. var _popover = document.querySelector('.mui-popover.mui-active');
  5988. if (_popover) {
  5989. // _popover.setAttribute('style', '');
  5990. _popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
  5991. _popover.classList.remove(CLASS_ACTIVE);
  5992. // _popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
  5993. //同一个弹出则直接返回,解决同一个popover的toggle
  5994. if (popover === _popover) {
  5995. removeBackdrop(_popover);
  5996. return;
  5997. }
  5998. }
  5999. var isActionSheet = false;
  6000. if (popover.classList.contains(CLASS_BAR_POPOVER) || popover.classList.contains(CLASS_ACTION_POPOVER)) { //navBar
  6001. if (popover.classList.contains(CLASS_ACTION_POPOVER)) { //action sheet popover
  6002. isActionSheet = true;
  6003. backdrop.classList.add(CLASS_ACTION_BACKDROP);
  6004. } else { //bar popover
  6005. backdrop.classList.add(CLASS_BAR_BACKDROP);
  6006. // if (anchor) {
  6007. // if (anchor.parentNode) {
  6008. // var offsetWidth = anchor.offsetWidth;
  6009. // var offsetLeft = anchor.offsetLeft;
  6010. // var innerWidth = window.innerWidth;
  6011. // popover.style.left = (Math.min(Math.max(offsetLeft, defaultPadding), innerWidth - offsetWidth - defaultPadding)) + "px";
  6012. // } else {
  6013. // //TODO anchor is position:{left,top,bottom,right}
  6014. // }
  6015. // }
  6016. }
  6017. }
  6018. setStyle(popover, 'block'); //actionsheet transform
  6019. popover.offsetHeight;
  6020. popover.classList.add(CLASS_ACTIVE);
  6021. backdrop.setAttribute('style', '');
  6022. document.body.appendChild(backdrop);
  6023. calPosition(popover, anchor, isActionSheet); //position
  6024. backdrop.classList.add(CLASS_ACTIVE);
  6025. popover.addEventListener('webkitTransitionEnd', onPopoverShown);
  6026. };
  6027. var setStyle = function(popover, display, top, left) {
  6028. var style = popover.style;
  6029. if (typeof display !== 'undefined')
  6030. style.display = display;
  6031. if (typeof top !== 'undefined')
  6032. style.top = top + 'px';
  6033. if (typeof left !== 'undefined')
  6034. style.left = left + 'px';
  6035. };
  6036. var calPosition = function(popover, anchor, isActionSheet) {
  6037. if (!popover || !anchor) {
  6038. return;
  6039. }
  6040. if (isActionSheet) { //actionsheet
  6041. setStyle(popover, 'block')
  6042. return;
  6043. }
  6044. var wWidth = window.innerWidth;
  6045. var wHeight = window.innerHeight;
  6046. var pWidth = popover.offsetWidth;
  6047. var pHeight = popover.offsetHeight;
  6048. var aWidth = anchor.offsetWidth;
  6049. var aHeight = anchor.offsetHeight;
  6050. var offset = $.offset(anchor);
  6051. var arrow = popover.querySelector('.' + CLASS_POPOVER_ARROW);
  6052. if (!arrow) {
  6053. arrow = document.createElement('div');
  6054. arrow.className = CLASS_POPOVER_ARROW;
  6055. popover.appendChild(arrow);
  6056. }
  6057. var arrowSize = arrow && arrow.offsetWidth / 2 || 0;
  6058. var pTop = 0;
  6059. var pLeft = 0;
  6060. var diff = 0;
  6061. var arrowLeft = 0;
  6062. var defaultPadding = popover.classList.contains(CLASS_ACTION_POPOVER) ? 0 : 5;
  6063. var position = 'top';
  6064. if ((pHeight + arrowSize) < (offset.top - window.pageYOffset)) { //top
  6065. pTop = offset.top - pHeight - arrowSize;
  6066. } else if ((pHeight + arrowSize) < (wHeight - (offset.top - window.pageYOffset) - aHeight)) { //bottom
  6067. position = 'bottom';
  6068. pTop = offset.top + aHeight + arrowSize;
  6069. } else { //middle
  6070. position = 'middle';
  6071. pTop = Math.max((wHeight - pHeight) / 2 + window.pageYOffset, 0);
  6072. pLeft = Math.max((wWidth - pWidth) / 2 + window.pageXOffset, 0);
  6073. }
  6074. if (position === 'top' || position === 'bottom') {
  6075. pLeft = aWidth / 2 + offset.left - pWidth / 2;
  6076. diff = pLeft;
  6077. if (pLeft < defaultPadding) pLeft = defaultPadding;
  6078. if (pLeft + pWidth > wWidth) pLeft = wWidth - pWidth - defaultPadding;
  6079. if (arrow) {
  6080. if (position === 'top') {
  6081. arrow.classList.add(CLASS_BOTTOM);
  6082. } else {
  6083. arrow.classList.remove(CLASS_BOTTOM);
  6084. }
  6085. diff = diff - pLeft;
  6086. arrowLeft = (pWidth / 2 - arrowSize / 2 + diff);
  6087. arrowLeft = Math.max(Math.min(arrowLeft, pWidth - arrowSize * 2 - 6), 6);
  6088. arrow.setAttribute('style', 'left:' + arrowLeft + 'px');
  6089. }
  6090. } else if (position === 'middle') {
  6091. arrow.setAttribute('style', 'display:none');
  6092. }
  6093. setStyle(popover, 'block', pTop, pLeft);
  6094. };
  6095. $.createMask = function(callback) {
  6096. var element = document.createElement('div');
  6097. element.classList.add(CLASS_BACKDROP);
  6098. element.addEventListener($.EVENT_MOVE, $.preventDefault);
  6099. element.addEventListener('tap', function() {
  6100. mask.close();
  6101. });
  6102. var mask = [element];
  6103. mask._show = false;
  6104. mask.show = function() {
  6105. mask._show = true;
  6106. element.setAttribute('style', 'opacity:1');
  6107. document.body.appendChild(element);
  6108. return mask;
  6109. };
  6110. mask._remove = function() {
  6111. if (mask._show) {
  6112. mask._show = false;
  6113. element.setAttribute('style', 'opacity:0');
  6114. $.later(function() {
  6115. var body = document.body;
  6116. element.parentNode === body && body.removeChild(element);
  6117. }, 350);
  6118. }
  6119. return mask;
  6120. };
  6121. mask.close = function() {
  6122. if (callback) {
  6123. if (callback() !== false) {
  6124. mask._remove();
  6125. }
  6126. } else {
  6127. mask._remove();
  6128. }
  6129. };
  6130. return mask;
  6131. };
  6132. $.fn.popover = function() {
  6133. var args = arguments;
  6134. this.each(function() {
  6135. $.targets._popover = this;
  6136. if (args[0] === 'show' || args[0] === 'hide' || args[0] === 'toggle') {
  6137. togglePopover(this, args[1], args[0]);
  6138. }
  6139. });
  6140. };
  6141. })(mui, window, document, 'popover');
  6142. /**
  6143. * segmented-controllers
  6144. * @param {type} $
  6145. * @param {type} window
  6146. * @param {type} document
  6147. * @param {type} undefined
  6148. * @returns {undefined}
  6149. */
  6150. (function($, window, document, name, undefined) {
  6151. var CLASS_CONTROL_ITEM = 'mui-control-item';
  6152. var CLASS_SEGMENTED_CONTROL = 'mui-segmented-control';
  6153. var CLASS_SEGMENTED_CONTROL_VERTICAL = 'mui-segmented-control-vertical';
  6154. var CLASS_CONTROL_CONTENT = 'mui-control-content';
  6155. var CLASS_TAB_BAR = 'mui-bar-tab';
  6156. var CLASS_TAB_ITEM = 'mui-tab-item';
  6157. var CLASS_SLIDER_ITEM = 'mui-slider-item';
  6158. var handle = function(event, target) {
  6159. if (target.classList && (target.classList.contains(CLASS_CONTROL_ITEM) || target.classList.contains(CLASS_TAB_ITEM))) {
  6160. if (target.parentNode && target.parentNode.classList && target.parentNode.classList.contains(CLASS_SEGMENTED_CONTROL_VERTICAL)) {
  6161. //vertical 如果preventDefault会导致无法滚动
  6162. } else {
  6163. event.preventDefault();
  6164. // if(target.tagName == 'A') {
  6165. // // fixed 底部选项卡href 无法跳转 && stop hash change
  6166. // var curr_href = location.hostname + location.pathname,
  6167. // target_href = target.hostname + target.pathname;
  6168. // if (curr_href == target_href && target.hash !== "") {
  6169. // event.preventDefault();
  6170. // return target;
  6171. // }else{
  6172. // return false
  6173. // }
  6174. // }
  6175. }
  6176. // if (target.hash) {
  6177. return target;
  6178. // }
  6179. }
  6180. return false;
  6181. };
  6182. $.registerTarget({
  6183. name: name,
  6184. index: 80,
  6185. handle: handle,
  6186. target: false
  6187. });
  6188. window.addEventListener('tap', function(e) {
  6189. var targetTab = $.targets.tab;
  6190. if (!targetTab) {
  6191. return;
  6192. }
  6193. var activeTab;
  6194. var activeBodies;
  6195. var targetBody;
  6196. var className = 'mui-active';
  6197. var classSelector = '.' + className;
  6198. var segmentedControl = targetTab.parentNode;
  6199. for (; segmentedControl && segmentedControl !== document; segmentedControl = segmentedControl.parentNode) {
  6200. if (segmentedControl.classList.contains(CLASS_SEGMENTED_CONTROL)) {
  6201. activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_CONTROL_ITEM);
  6202. break;
  6203. } else if (segmentedControl.classList.contains(CLASS_TAB_BAR)) {
  6204. activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_TAB_ITEM);
  6205. }
  6206. }
  6207. if (activeTab) {
  6208. activeTab.classList.remove(className);
  6209. }
  6210. var isLastActive = targetTab === activeTab;
  6211. if (targetTab) {
  6212. targetTab.classList.add(className);
  6213. }
  6214. if (!targetTab.hash) {
  6215. return;
  6216. }
  6217. targetBody = document.getElementById(targetTab.hash.replace('#', ''));
  6218. if (!targetBody) {
  6219. return;
  6220. }
  6221. if (!targetBody.classList.contains(CLASS_CONTROL_CONTENT)) { //tab bar popover
  6222. targetTab.classList[isLastActive ? 'remove' : 'add'](className);
  6223. return;
  6224. }
  6225. if (isLastActive) { //same
  6226. return;
  6227. }
  6228. var parentNode = targetBody.parentNode;
  6229. activeBodies = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT + classSelector);
  6230. for (var i = 0; i < activeBodies.length; i++) {
  6231. var activeBody = activeBodies[i];
  6232. activeBody.parentNode === parentNode && activeBody.classList.remove(className);
  6233. }
  6234. targetBody.classList.add(className);
  6235. var contents = [];
  6236. var _contents = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT);
  6237. for (var i = 0; i < _contents.length; i++) { //查找直属子节点
  6238. _contents[i].parentNode === parentNode && (contents.push(_contents[i]));
  6239. }
  6240. $.trigger(targetBody, $.eventName('shown', name), {
  6241. tabNumber: Array.prototype.indexOf.call(contents, targetBody)
  6242. });
  6243. e.detail && e.detail.gesture.preventDefault(); //fixed hashchange
  6244. });
  6245. })(mui, window, document, 'tab');
  6246. /**
  6247. * Toggles switch
  6248. * @param {type} $
  6249. * @param {type} window
  6250. * @param {type} name
  6251. * @returns {undefined}
  6252. */
  6253. (function($, window, name) {
  6254. var CLASS_SWITCH = 'mui-switch';
  6255. var CLASS_SWITCH_HANDLE = 'mui-switch-handle';
  6256. var CLASS_ACTIVE = 'mui-active';
  6257. var CLASS_DRAGGING = 'mui-dragging';
  6258. var CLASS_DISABLED = 'mui-disabled';
  6259. var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE;
  6260. var handle = function(event, target) {
  6261. if (target.classList && target.classList.contains(CLASS_SWITCH)) {
  6262. return target;
  6263. }
  6264. return false;
  6265. };
  6266. $.registerTarget({
  6267. name: name,
  6268. index: 100,
  6269. handle: handle,
  6270. target: false
  6271. });
  6272. var Toggle = function(element) {
  6273. this.element = element;
  6274. this.classList = this.element.classList;
  6275. this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE);
  6276. this.init();
  6277. this.initEvent();
  6278. };
  6279. Toggle.prototype.init = function() {
  6280. this.toggleWidth = this.element.offsetWidth;
  6281. this.handleWidth = this.handle.offsetWidth;
  6282. this.handleX = this.toggleWidth - this.handleWidth - 3;
  6283. };
  6284. Toggle.prototype.initEvent = function() {
  6285. this.element.addEventListener($.EVENT_START, this);
  6286. this.element.addEventListener('drag', this);
  6287. this.element.addEventListener('swiperight', this);
  6288. this.element.addEventListener($.EVENT_END, this);
  6289. this.element.addEventListener($.EVENT_CANCEL, this);
  6290. };
  6291. Toggle.prototype.handleEvent = function(e) {
  6292. if (this.classList.contains(CLASS_DISABLED)) {
  6293. return;
  6294. }
  6295. switch (e.type) {
  6296. case $.EVENT_START:
  6297. this.start(e);
  6298. break;
  6299. case 'drag':
  6300. this.drag(e);
  6301. break;
  6302. case 'swiperight':
  6303. this.swiperight();
  6304. break;
  6305. case $.EVENT_END:
  6306. case $.EVENT_CANCEL:
  6307. this.end(e);
  6308. break;
  6309. }
  6310. };
  6311. Toggle.prototype.start = function(e) {
  6312. this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
  6313. this.classList.add(CLASS_DRAGGING);
  6314. if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化
  6315. this.init();
  6316. }
  6317. };
  6318. Toggle.prototype.drag = function(e) {
  6319. var detail = e.detail;
  6320. if (!this.isDragging) {
  6321. if (detail.direction === 'left' || detail.direction === 'right') {
  6322. this.isDragging = true;
  6323. this.lastChanged = undefined;
  6324. this.initialState = this.classList.contains(CLASS_ACTIVE);
  6325. }
  6326. }
  6327. if (this.isDragging) {
  6328. this.setTranslateX(detail.deltaX);
  6329. e.stopPropagation();
  6330. detail.gesture.preventDefault();
  6331. }
  6332. };
  6333. Toggle.prototype.swiperight = function(e) {
  6334. if (this.isDragging) {
  6335. e.stopPropagation();
  6336. }
  6337. };
  6338. Toggle.prototype.end = function(e) {
  6339. this.classList.remove(CLASS_DRAGGING);
  6340. if (this.isDragging) {
  6341. this.isDragging = false;
  6342. e.stopPropagation();
  6343. $.trigger(this.element, 'toggle', {
  6344. isActive: this.classList.contains(CLASS_ACTIVE)
  6345. });
  6346. } else {
  6347. this.toggle();
  6348. }
  6349. };
  6350. Toggle.prototype.toggle = function(animate) {
  6351. var classList = this.classList;
  6352. if (animate === false) {
  6353. this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s';
  6354. } else {
  6355. this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
  6356. }
  6357. if (classList.contains(CLASS_ACTIVE)) {
  6358. classList.remove(CLASS_ACTIVE);
  6359. this.handle.style.webkitTransform = 'translate(0,0)';
  6360. } else {
  6361. classList.add(CLASS_ACTIVE);
  6362. this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)';
  6363. }
  6364. $.trigger(this.element, 'toggle', {
  6365. isActive: this.classList.contains(CLASS_ACTIVE)
  6366. });
  6367. };
  6368. Toggle.prototype.setTranslateX = $.animationFrame(function(x) {
  6369. if (!this.isDragging) {
  6370. return;
  6371. }
  6372. var isChanged = false;
  6373. if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) {
  6374. isChanged = true;
  6375. }
  6376. if (this.lastChanged !== isChanged) {
  6377. if (isChanged) {
  6378. this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)';
  6379. this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE);
  6380. } else {
  6381. this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)';
  6382. this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE);
  6383. }
  6384. this.lastChanged = isChanged;
  6385. }
  6386. });
  6387. $.fn['switch'] = function(options) {
  6388. var switchApis = [];
  6389. this.each(function() {
  6390. var switchApi = null;
  6391. var id = this.getAttribute('data-switch');
  6392. if (!id) {
  6393. id = ++$.uuid;
  6394. $.data[id] = new Toggle(this);
  6395. this.setAttribute('data-switch', id);
  6396. } else {
  6397. switchApi = $.data[id];
  6398. }
  6399. switchApis.push(switchApi);
  6400. });
  6401. return switchApis.length > 1 ? switchApis : switchApis[0];
  6402. };
  6403. $.ready(function() {
  6404. $('.' + CLASS_SWITCH)['switch']();
  6405. });
  6406. })(mui, window, 'toggle');
  6407. /**
  6408. * Tableviews
  6409. * @param {type} $
  6410. * @param {type} window
  6411. * @param {type} document
  6412. * @returns {undefined}
  6413. */
  6414. (function($, window, document) {
  6415. var CLASS_ACTIVE = 'mui-active';
  6416. var CLASS_SELECTED = 'mui-selected';
  6417. var CLASS_GRID_VIEW = 'mui-grid-view';
  6418. var CLASS_RADIO_VIEW = 'mui-table-view-radio';
  6419. var CLASS_TABLE_VIEW_CELL = 'mui-table-view-cell';
  6420. var CLASS_COLLAPSE_CONTENT = 'mui-collapse-content';
  6421. var CLASS_DISABLED = 'mui-disabled';
  6422. var CLASS_TOGGLE = 'mui-switch';
  6423. var CLASS_BTN = 'mui-btn';
  6424. var CLASS_SLIDER_HANDLE = 'mui-slider-handle';
  6425. var CLASS_SLIDER_LEFT = 'mui-slider-left';
  6426. var CLASS_SLIDER_RIGHT = 'mui-slider-right';
  6427. var CLASS_TRANSITIONING = 'mui-transitioning';
  6428. var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE;
  6429. var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT;
  6430. var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT;
  6431. var SELECTOR_SELECTED = '.' + CLASS_SELECTED;
  6432. var SELECTOR_BUTTON = '.' + CLASS_BTN;
  6433. var overFactor = 0.8;
  6434. var cell, a;
  6435. var isMoved = isOpened = openedActions = progress = false;
  6436. var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
  6437. var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0;
  6438. var toggleActive = function(isActive) {
  6439. if (isActive) {
  6440. if (a) {
  6441. a.classList.add(CLASS_ACTIVE);
  6442. } else if (cell) {
  6443. cell.classList.add(CLASS_ACTIVE);
  6444. }
  6445. } else {
  6446. timer && timer.cancel();
  6447. if (a) {
  6448. a.classList.remove(CLASS_ACTIVE);
  6449. } else if (cell) {
  6450. cell.classList.remove(CLASS_ACTIVE);
  6451. }
  6452. }
  6453. };
  6454. var updateTranslate = function() {
  6455. if (translateX !== lastTranslateX) {
  6456. if (buttonsRight && buttonsRight.length > 0) {
  6457. progress = translateX / sliderActionRightWidth;
  6458. if (translateX < -sliderActionRightWidth) {
  6459. translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor);
  6460. }
  6461. for (var i = 0, len = buttonsRight.length; i < len; i++) {
  6462. var buttonRight = buttonsRight[i];
  6463. if (typeof buttonRight._buttonOffset === 'undefined') {
  6464. buttonRight._buttonOffset = buttonRight.offsetLeft;
  6465. }
  6466. buttonOffset = buttonRight._buttonOffset;
  6467. setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1))));
  6468. }
  6469. }
  6470. if (buttonsLeft && buttonsLeft.length > 0) {
  6471. progress = translateX / sliderActionLeftWidth;
  6472. if (translateX > sliderActionLeftWidth) {
  6473. translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor);
  6474. }
  6475. for (var i = 0, len = buttonsLeft.length; i < len; i++) {
  6476. var buttonLeft = buttonsLeft[i];
  6477. if (typeof buttonLeft._buttonOffset === 'undefined') {
  6478. buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
  6479. }
  6480. buttonOffset = buttonLeft._buttonOffset;
  6481. if (buttonsLeft.length > 1) {
  6482. buttonLeft.style.zIndex = buttonsLeft.length - i;
  6483. }
  6484. setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1))));
  6485. }
  6486. }
  6487. setTranslate(sliderHandle, translateX);
  6488. lastTranslateX = translateX;
  6489. }
  6490. sliderRequestAnimationFrame = requestAnimationFrame(function() {
  6491. updateTranslate();
  6492. });
  6493. };
  6494. var setTranslate = function(element, x) {
  6495. if (element) {
  6496. element.style.webkitTransform = 'translate(' + x + 'px,0)';
  6497. }
  6498. };
  6499. window.addEventListener($.EVENT_START, function(event) {
  6500. if (cell) {
  6501. toggleActive(false);
  6502. }
  6503. cell = a = false;
  6504. isMoved = isOpened = openedActions = false;
  6505. var target = event.target;
  6506. var isDisabled = false;
  6507. for (; target && target !== document; target = target.parentNode) {
  6508. if (target.classList) {
  6509. var classList = target.classList;
  6510. if ((target.tagName === 'INPUT' && target.type !== 'radio' && target.type !== 'checkbox') || target.tagName === 'BUTTON' || classList.contains(CLASS_TOGGLE) || classList.contains(CLASS_BTN) || classList.contains(CLASS_DISABLED)) {
  6511. isDisabled = true;
  6512. }
  6513. if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content
  6514. break;
  6515. }
  6516. if (classList.contains(CLASS_TABLE_VIEW_CELL)) {
  6517. cell = target;
  6518. //TODO swipe to delete close
  6519. var selected = cell.parentNode.querySelector(SELECTOR_SELECTED);
  6520. if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) {
  6521. $.swipeoutClose(selected);
  6522. cell = isDisabled = false;
  6523. return;
  6524. }
  6525. if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) {
  6526. var link = cell.querySelector('a');
  6527. if (link && link.parentNode === cell) { //li>a
  6528. a = link;
  6529. }
  6530. }
  6531. var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
  6532. if (handle) {
  6533. toggleEvents(cell);
  6534. event.stopPropagation();
  6535. }
  6536. if (!isDisabled) {
  6537. if (handle) {
  6538. if (timer) {
  6539. timer.cancel();
  6540. }
  6541. timer = $.later(function() {
  6542. toggleActive(true);
  6543. }, 100);
  6544. } else {
  6545. toggleActive(true);
  6546. }
  6547. }
  6548. break;
  6549. }
  6550. }
  6551. }
  6552. });
  6553. window.addEventListener($.EVENT_MOVE, function(event) {
  6554. toggleActive(false);
  6555. });
  6556. var handleEvent = {
  6557. handleEvent: function(event) {
  6558. switch (event.type) {
  6559. case 'drag':
  6560. this.drag(event);
  6561. break;
  6562. case 'dragend':
  6563. this.dragend(event);
  6564. break;
  6565. case 'flick':
  6566. this.flick(event);
  6567. break;
  6568. case 'swiperight':
  6569. this.swiperight(event);
  6570. break;
  6571. case 'swipeleft':
  6572. this.swipeleft(event);
  6573. break;
  6574. }
  6575. },
  6576. drag: function(event) {
  6577. if (!cell) {
  6578. return;
  6579. }
  6580. if (!isMoved) { //init
  6581. sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
  6582. sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
  6583. if (sliderHandle) {
  6584. sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT);
  6585. sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT);
  6586. if (sliderActionLeft) {
  6587. sliderActionLeftWidth = sliderActionLeft.offsetWidth;
  6588. buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON);
  6589. }
  6590. if (sliderActionRight) {
  6591. sliderActionRightWidth = sliderActionRight.offsetWidth;
  6592. buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON);
  6593. }
  6594. cell.classList.remove(CLASS_TRANSITIONING);
  6595. isOpened = cell.classList.contains(CLASS_SELECTED);
  6596. if (isOpened) {
  6597. openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right';
  6598. }
  6599. }
  6600. }
  6601. var detail = event.detail;
  6602. var direction = detail.direction;
  6603. var angle = detail.angle;
  6604. if (direction === 'left' && (angle > 150 || angle < -150)) {
  6605. if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态
  6606. isMoved = true;
  6607. }
  6608. } else if (direction === 'right' && (angle > -30 && angle < 30)) {
  6609. if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态
  6610. isMoved = true;
  6611. }
  6612. }
  6613. if (isMoved) {
  6614. event.stopPropagation();
  6615. event.detail.gesture.preventDefault();
  6616. var translate = event.detail.deltaX;
  6617. if (isOpened) {
  6618. if (openedActions === 'right') {
  6619. translate = translate - sliderActionRightWidth;
  6620. } else {
  6621. translate = translate + sliderActionLeftWidth;
  6622. }
  6623. }
  6624. if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) {
  6625. if (!isOpened) {
  6626. return;
  6627. }
  6628. translate = 0;
  6629. }
  6630. if (translate < 0) {
  6631. sliderDirection = 'toLeft';
  6632. } else if (translate > 0) {
  6633. sliderDirection = 'toRight';
  6634. } else {
  6635. if (!sliderDirection) {
  6636. sliderDirection = 'toLeft';
  6637. }
  6638. }
  6639. if (!sliderRequestAnimationFrame) {
  6640. updateTranslate();
  6641. }
  6642. translateX = translate;
  6643. }
  6644. },
  6645. flick: function(event) {
  6646. if (isMoved) {
  6647. event.stopPropagation();
  6648. }
  6649. },
  6650. swipeleft: function(event) {
  6651. if (isMoved) {
  6652. event.stopPropagation();
  6653. }
  6654. },
  6655. swiperight: function(event) {
  6656. if (isMoved) {
  6657. event.stopPropagation();
  6658. }
  6659. },
  6660. dragend: function(event) {
  6661. if (!isMoved) {
  6662. return;
  6663. }
  6664. event.stopPropagation();
  6665. if (sliderRequestAnimationFrame) {
  6666. cancelAnimationFrame(sliderRequestAnimationFrame);
  6667. sliderRequestAnimationFrame = null;
  6668. }
  6669. var detail = event.detail;
  6670. isMoved = false;
  6671. var action = 'close';
  6672. var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth;
  6673. var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2);
  6674. if (isToggle) {
  6675. if (!isOpened) {
  6676. action = 'open';
  6677. } else if (detail.direction === 'left' && openedActions === 'right') {
  6678. action = 'open';
  6679. } else if (detail.direction === 'right' && openedActions === 'left') {
  6680. action = 'open';
  6681. }
  6682. }
  6683. cell.classList.add(CLASS_TRANSITIONING);
  6684. var buttons;
  6685. if (action === 'open') {
  6686. var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth;
  6687. setTranslate(sliderHandle, newTranslate);
  6688. buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft;
  6689. if (typeof buttons !== 'undefined') {
  6690. var button = null;
  6691. for (var i = 0; i < buttons.length; i++) {
  6692. button = buttons[i];
  6693. setTranslate(button, newTranslate);
  6694. }
  6695. button.parentNode.classList.add(CLASS_SELECTED);
  6696. cell.classList.add(CLASS_SELECTED);
  6697. if (!isOpened) {
  6698. $.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright');
  6699. }
  6700. }
  6701. } else {
  6702. setTranslate(sliderHandle, 0);
  6703. sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED);
  6704. sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED);
  6705. cell.classList.remove(CLASS_SELECTED);
  6706. }
  6707. var buttonOffset;
  6708. if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {
  6709. for (var i = 0, len = buttonsLeft.length; i < len; i++) {
  6710. var buttonLeft = buttonsLeft[i];
  6711. buttonOffset = buttonLeft._buttonOffset;
  6712. if (typeof buttonOffset === 'undefined') {
  6713. buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
  6714. }
  6715. setTranslate(buttonLeft, buttonOffset);
  6716. }
  6717. }
  6718. if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {
  6719. for (var i = 0, len = buttonsRight.length; i < len; i++) {
  6720. var buttonRight = buttonsRight[i];
  6721. buttonOffset = buttonRight._buttonOffset;
  6722. if (typeof buttonOffset === 'undefined') {
  6723. buttonRight._buttonOffset = buttonRight.offsetLeft;
  6724. }
  6725. setTranslate(buttonRight, -buttonOffset);
  6726. }
  6727. }
  6728. }
  6729. };
  6730. function toggleEvents(element, isRemove) {
  6731. var method = !!isRemove ? 'removeEventListener' : 'addEventListener';
  6732. element[method]('drag', handleEvent);
  6733. element[method]('dragend', handleEvent);
  6734. element[method]('swiperight', handleEvent);
  6735. element[method]('swipeleft', handleEvent);
  6736. element[method]('flick', handleEvent);
  6737. };
  6738. /**
  6739. * 打开滑动菜单
  6740. * @param {Object} el
  6741. * @param {Object} direction
  6742. */
  6743. $.swipeoutOpen = function(el, direction) {
  6744. if (!el) return;
  6745. var classList = el.classList;
  6746. if (classList.contains(CLASS_SELECTED)) return;
  6747. if (!direction) {
  6748. if (el.querySelector(SELECTOR_SLIDER_RIGHT)) {
  6749. direction = 'right';
  6750. } else {
  6751. direction = 'left';
  6752. }
  6753. }
  6754. var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
  6755. if (!swipeoutAction) return;
  6756. swipeoutAction.classList.add(CLASS_SELECTED);
  6757. classList.add(CLASS_SELECTED);
  6758. classList.remove(CLASS_TRANSITIONING);
  6759. var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
  6760. var swipeoutWidth = swipeoutAction.offsetWidth;
  6761. var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth;
  6762. var length = buttons.length;
  6763. var button;
  6764. for (var i = 0; i < length; i++) {
  6765. button = buttons[i];
  6766. if (direction === 'right') {
  6767. setTranslate(button, -button.offsetLeft);
  6768. } else {
  6769. setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
  6770. }
  6771. }
  6772. classList.add(CLASS_TRANSITIONING);
  6773. for (var i = 0; i < length; i++) {
  6774. setTranslate(buttons[i], translate);
  6775. }
  6776. setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate);
  6777. };
  6778. /**
  6779. * 关闭滑动菜单
  6780. * @param {Object} el
  6781. */
  6782. $.swipeoutClose = function(el) {
  6783. if (!el) return;
  6784. var classList = el.classList;
  6785. if (!classList.contains(CLASS_SELECTED)) return;
  6786. var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left';
  6787. var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
  6788. if (!swipeoutAction) return;
  6789. swipeoutAction.classList.remove(CLASS_SELECTED);
  6790. classList.remove(CLASS_SELECTED);
  6791. classList.add(CLASS_TRANSITIONING);
  6792. var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
  6793. var swipeoutWidth = swipeoutAction.offsetWidth;
  6794. var length = buttons.length;
  6795. var button;
  6796. setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0);
  6797. for (var i = 0; i < length; i++) {
  6798. button = buttons[i];
  6799. if (direction === 'right') {
  6800. setTranslate(button, (-button.offsetLeft));
  6801. } else {
  6802. setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
  6803. }
  6804. }
  6805. };
  6806. window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
  6807. if (!cell) {
  6808. return;
  6809. }
  6810. toggleActive(false);
  6811. sliderHandle && toggleEvents(cell, true);
  6812. });
  6813. window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
  6814. if (!cell) {
  6815. return;
  6816. }
  6817. toggleActive(false);
  6818. sliderHandle && toggleEvents(cell, true);
  6819. });
  6820. var radioOrCheckboxClick = function(event) {
  6821. var type = event.target && event.target.type || '';
  6822. if (type === 'radio' || type === 'checkbox') {
  6823. return;
  6824. }
  6825. var classList = cell.classList;
  6826. if (classList.contains('mui-radio')) {
  6827. var input = cell.querySelector('input[type=radio]');
  6828. if (input) {
  6829. // input.click();
  6830. if (!input.disabled && !input.readOnly) {
  6831. input.checked = !input.checked;
  6832. $.trigger(input, 'change');
  6833. }
  6834. }
  6835. } else if (classList.contains('mui-checkbox')) {
  6836. var input = cell.querySelector('input[type=checkbox]');
  6837. if (input) {
  6838. // input.click();
  6839. if (!input.disabled && !input.readOnly) {
  6840. input.checked = !input.checked;
  6841. $.trigger(input, 'change');
  6842. }
  6843. }
  6844. }
  6845. };
  6846. //fixed hashchange(android)
  6847. window.addEventListener($.EVENT_CLICK, function(e) {
  6848. if (cell && cell.classList.contains('mui-collapse')) {
  6849. e.preventDefault();
  6850. }
  6851. });
  6852. window.addEventListener('doubletap', function(event) {
  6853. if (cell) {
  6854. radioOrCheckboxClick(event);
  6855. }
  6856. });
  6857. var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
  6858. window.addEventListener('tap', function(event) {
  6859. if (!cell) {
  6860. return;
  6861. }
  6862. var isExpand = false;
  6863. var classList = cell.classList;
  6864. var ul = cell.parentNode;
  6865. if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) {
  6866. if (classList.contains(CLASS_SELECTED)) {
  6867. return;
  6868. }
  6869. var selected = ul.querySelector('li' + SELECTOR_SELECTED);
  6870. if (selected) {
  6871. selected.classList.remove(CLASS_SELECTED);
  6872. }
  6873. classList.add(CLASS_SELECTED);
  6874. $.trigger(cell, 'selected', {
  6875. el: cell
  6876. });
  6877. return;
  6878. }
  6879. if (classList.contains('mui-collapse') && !cell.parentNode.classList.contains('mui-unfold')) {
  6880. if (!preventDefaultException.test(event.target.tagName)) {
  6881. event.detail.gesture.preventDefault();
  6882. }
  6883. if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类
  6884. var collapse = cell.parentNode.querySelector('.mui-collapse.mui-active');
  6885. if (collapse) {
  6886. collapse.classList.remove(CLASS_ACTIVE);
  6887. }
  6888. isExpand = true;
  6889. }
  6890. classList.toggle(CLASS_ACTIVE);
  6891. if (isExpand) {
  6892. //触发展开事件
  6893. $.trigger(cell, 'expand');
  6894. //scroll
  6895. //暂不滚动
  6896. // var offsetTop = $.offset(cell).top;
  6897. // var scrollTop = document.body.scrollTop;
  6898. // var height = window.innerHeight;
  6899. // var offsetHeight = cell.offsetHeight;
  6900. // var cellHeight = (offsetTop - scrollTop + offsetHeight);
  6901. // if (offsetHeight > height) {
  6902. // $.scrollTo(offsetTop, 300);
  6903. // } else if (cellHeight > height) {
  6904. // $.scrollTo(cellHeight - height + scrollTop, 300);
  6905. // }
  6906. }
  6907. } else {
  6908. radioOrCheckboxClick(event);
  6909. }
  6910. });
  6911. })(mui, window, document);
  6912. (function($, window) {
  6913. /**
  6914. * 警告消息框
  6915. */
  6916. $.alert = function(message, title, btnValue, callback) {
  6917. if ($.os.plus) {
  6918. if (typeof message === 'undefined') {
  6919. return;
  6920. } else {
  6921. if (typeof title === 'function') {
  6922. callback = title;
  6923. title = null;
  6924. btnValue = '确定';
  6925. } else if (typeof btnValue === 'function') {
  6926. callback = btnValue;
  6927. btnValue = null;
  6928. }
  6929. $.plusReady(function() {
  6930. plus.nativeUI.alert(message, callback, title, btnValue);
  6931. });
  6932. }
  6933. } else {
  6934. //TODO H5版本
  6935. window.alert(message);
  6936. }
  6937. };
  6938. })(mui, window);
  6939. (function($, window) {
  6940. /**
  6941. * 确认消息框
  6942. */
  6943. $.confirm = function(message, title, btnArray, callback) {
  6944. if ($.os.plus) {
  6945. if (typeof message === 'undefined') {
  6946. return;
  6947. } else {
  6948. if (typeof title === 'function') {
  6949. callback = title;
  6950. title = null;
  6951. btnArray = null;
  6952. } else if (typeof btnArray === 'function') {
  6953. callback = btnArray;
  6954. btnArray = null;
  6955. }
  6956. $.plusReady(function() {
  6957. plus.nativeUI.confirm(message, callback, title, btnArray);
  6958. });
  6959. }
  6960. } else {
  6961. //H5版本,0为确认,1为取消
  6962. if (window.confirm(message)) {
  6963. callback({
  6964. index: 0
  6965. });
  6966. } else {
  6967. callback({
  6968. index: 1
  6969. });
  6970. }
  6971. }
  6972. };
  6973. })(mui, window);
  6974. (function($, window) {
  6975. /**
  6976. * 输入对话框
  6977. */
  6978. $.prompt = function(text, defaultText, title, btnArray, callback) {
  6979. if ($.os.plus) {
  6980. if (typeof message === 'undefined') {
  6981. return;
  6982. } else {
  6983. if (typeof defaultText === 'function') {
  6984. callback = defaultText;
  6985. defaultText = null;
  6986. title = null;
  6987. btnArray = null;
  6988. } else if (typeof title === 'function') {
  6989. callback = title;
  6990. title = null;
  6991. btnArray = null;
  6992. } else if (typeof btnArray === 'function') {
  6993. callback = btnArray;
  6994. btnArray = null;
  6995. }
  6996. $.plusReady(function() {
  6997. plus.nativeUI.prompt(text, callback, title, defaultText, btnArray);
  6998. });
  6999. }
  7000. } else {
  7001. //H5版本(确认index为0,取消index为1)
  7002. var result = window.prompt(text);
  7003. if (result) {
  7004. callback({
  7005. index: 0,
  7006. value: result
  7007. });
  7008. } else {
  7009. callback({
  7010. index: 1,
  7011. value: ''
  7012. });
  7013. }
  7014. }
  7015. };
  7016. })(mui, window);
  7017. (function($, window) {
  7018. var CLASS_ACTIVE = 'mui-active';
  7019. /**
  7020. * 自动消失提示框
  7021. */
  7022. $.toast = function(message,options) {
  7023. var durations = {
  7024. 'long': 3500,
  7025. 'short': 2000
  7026. };
  7027. //计算显示时间
  7028. options = $.extend({
  7029. duration: 'short'
  7030. }, options || {});
  7031. if ($.os.plus && options.type !== 'div') {
  7032. //默认显示在底部;
  7033. $.plusReady(function() {
  7034. plus.nativeUI.toast(message, {
  7035. verticalAlign: 'bottom',
  7036. duration:options.duration
  7037. });
  7038. });
  7039. } else {
  7040. if (typeof options.duration === 'number') {
  7041. duration = options.duration>0 ? options.duration:durations['short'];
  7042. } else {
  7043. duration = durations[options.duration];
  7044. }
  7045. if (!duration) {
  7046. duration = durations['short'];
  7047. }
  7048. var toast = document.createElement('div');
  7049. toast.classList.add('mui-toast-container');
  7050. toast.innerHTML = '<div class="' + 'mui-toast-message' + '">' + message + '</div>';
  7051. toast.addEventListener('webkitTransitionEnd', function() {
  7052. if (!toast.classList.contains(CLASS_ACTIVE)) {
  7053. toast.parentNode.removeChild(toast);
  7054. toast = null;
  7055. }
  7056. });
  7057. //点击则自动消失
  7058. toast.addEventListener('click', function() {
  7059. toast.parentNode.removeChild(toast);
  7060. toast = null;
  7061. });
  7062. document.body.appendChild(toast);
  7063. toast.offsetHeight;
  7064. toast.classList.add(CLASS_ACTIVE);
  7065. setTimeout(function() {
  7066. toast && toast.classList.remove(CLASS_ACTIVE);
  7067. }, duration);
  7068. return {
  7069. isVisible: function() {return !!toast;}
  7070. }
  7071. }
  7072. };
  7073. })(mui, window);
  7074. /**
  7075. * Popup(alert,confirm,prompt)
  7076. * @param {Object} $
  7077. * @param {Object} window
  7078. * @param {Object} document
  7079. */
  7080. (function($, window, document) {
  7081. var CLASS_POPUP = 'mui-popup';
  7082. var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
  7083. var CLASS_POPUP_IN = 'mui-popup-in';
  7084. var CLASS_POPUP_OUT = 'mui-popup-out';
  7085. var CLASS_POPUP_INNER = 'mui-popup-inner';
  7086. var CLASS_POPUP_TITLE = 'mui-popup-title';
  7087. var CLASS_POPUP_TEXT = 'mui-popup-text';
  7088. var CLASS_POPUP_INPUT = 'mui-popup-input';
  7089. var CLASS_POPUP_BUTTONS = 'mui-popup-buttons';
  7090. var CLASS_POPUP_BUTTON = 'mui-popup-button';
  7091. var CLASS_POPUP_BUTTON_BOLD = 'mui-popup-button-bold';
  7092. var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
  7093. var CLASS_ACTIVE = 'mui-active';
  7094. var popupStack = [];
  7095. var backdrop = (function() {
  7096. var element = document.createElement('div');
  7097. element.classList.add(CLASS_POPUP_BACKDROP);
  7098. element.addEventListener($.EVENT_MOVE, $.preventDefault);
  7099. element.addEventListener('webkitTransitionEnd', function() {
  7100. if (!this.classList.contains(CLASS_ACTIVE)) {
  7101. element.parentNode && element.parentNode.removeChild(element);
  7102. }
  7103. });
  7104. return element;
  7105. }());
  7106. var createInput = function(placeholder) {
  7107. return '<div class="' + CLASS_POPUP_INPUT + '"><input type="text" autofocus placeholder="' + (placeholder || '') + '"/></div>';
  7108. };
  7109. var createInner = function(message, title, extra) {
  7110. return '<div class="' + CLASS_POPUP_INNER + '"><div class="' + CLASS_POPUP_TITLE + '">' + title + '</div><div class="' + CLASS_POPUP_TEXT + '">' + message.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>") + '</div>' + (extra || '') + '</div>';
  7111. };
  7112. var createButtons = function(btnArray) {
  7113. var length = btnArray.length;
  7114. var btns = [];
  7115. for (var i = 0; i < length; i++) {
  7116. btns.push('<span class="' + CLASS_POPUP_BUTTON + (i === length - 1 ? (' ' + CLASS_POPUP_BUTTON_BOLD) : '') + '">' + btnArray[i] + '</span>');
  7117. }
  7118. return '<div class="' + CLASS_POPUP_BUTTONS + '">' + btns.join('') + '</div>';
  7119. };
  7120. var createPopup = function(html, callback) {
  7121. var popupElement = document.createElement('div');
  7122. popupElement.className = CLASS_POPUP;
  7123. popupElement.innerHTML = html;
  7124. var removePopupElement = function() {
  7125. popupElement.parentNode && popupElement.parentNode.removeChild(popupElement);
  7126. popupElement = null;
  7127. };
  7128. popupElement.addEventListener($.EVENT_MOVE, $.preventDefault);
  7129. popupElement.addEventListener('webkitTransitionEnd', function(e) {
  7130. if (popupElement && e.target === popupElement && popupElement.classList.contains(CLASS_POPUP_OUT)) {
  7131. removePopupElement();
  7132. }
  7133. });
  7134. popupElement.style.display = 'block';
  7135. document.body.appendChild(popupElement);
  7136. popupElement.offsetHeight;
  7137. popupElement.classList.add(CLASS_POPUP_IN);
  7138. if (!backdrop.classList.contains(CLASS_ACTIVE)) {
  7139. backdrop.style.display = 'block';
  7140. document.body.appendChild(backdrop);
  7141. backdrop.offsetHeight;
  7142. backdrop.classList.add(CLASS_ACTIVE);
  7143. }
  7144. var btns = $.qsa('.' + CLASS_POPUP_BUTTON, popupElement);
  7145. var input = popupElement.querySelector('.' + CLASS_POPUP_INPUT + ' input');
  7146. var popup = {
  7147. element: popupElement,
  7148. close: function(index, animate) {
  7149. if (popupElement) {
  7150. var result = callback && callback({
  7151. index: index || 0,
  7152. value: input && input.value || ''
  7153. });
  7154. if (result === false) { //返回false则不关闭当前popup
  7155. return;
  7156. }
  7157. if (animate !== false) {
  7158. popupElement.classList.remove(CLASS_POPUP_IN);
  7159. popupElement.classList.add(CLASS_POPUP_OUT);
  7160. } else {
  7161. removePopupElement();
  7162. }
  7163. popupStack.pop();
  7164. //如果还有其他popup,则不remove backdrop
  7165. if (popupStack.length) {
  7166. popupStack[popupStack.length - 1]['show'](animate);
  7167. } else {
  7168. backdrop.classList.remove(CLASS_ACTIVE);
  7169. }
  7170. }
  7171. }
  7172. };
  7173. var handleEvent = function(e) {
  7174. popup.close(btns.indexOf(e.target));
  7175. };
  7176. $(popupElement).on('tap', '.' + CLASS_POPUP_BUTTON, handleEvent);
  7177. if (popupStack.length) {
  7178. popupStack[popupStack.length - 1]['hide']();
  7179. }
  7180. popupStack.push({
  7181. close: popup.close,
  7182. show: function(animate) {
  7183. popupElement.style.display = 'block';
  7184. popupElement.offsetHeight;
  7185. popupElement.classList.add(CLASS_POPUP_IN);
  7186. },
  7187. hide: function() {
  7188. popupElement.style.display = 'none';
  7189. popupElement.classList.remove(CLASS_POPUP_IN);
  7190. }
  7191. });
  7192. return popup;
  7193. };
  7194. var createAlert = function(message, title, btnValue, callback, type) {
  7195. if (typeof message === 'undefined') {
  7196. return;
  7197. } else {
  7198. if (typeof title === 'function') {
  7199. callback = title;
  7200. type = btnValue;
  7201. title = null;
  7202. btnValue = null;
  7203. } else if (typeof btnValue === 'function') {
  7204. type = callback;
  7205. callback = btnValue;
  7206. btnValue = null;
  7207. }
  7208. }
  7209. if (!$.os.plus || type === 'div') {
  7210. return createPopup(createInner(message, title || '提示') + createButtons([btnValue || '确定']), callback);
  7211. }
  7212. return plus.nativeUI.alert(message, callback, title || '提示', btnValue || '确定');
  7213. };
  7214. var createConfirm = function(message, title, btnArray, callback, type) {
  7215. if (typeof message === 'undefined') {
  7216. return;
  7217. } else {
  7218. if (typeof title === 'function') {
  7219. callback = title;
  7220. type = btnArray;
  7221. title = null;
  7222. btnArray = null;
  7223. } else if (typeof btnArray === 'function') {
  7224. type = callback;
  7225. callback = btnArray;
  7226. btnArray = null;
  7227. }
  7228. }
  7229. if (!$.os.plus || type === 'div') {
  7230. return createPopup(createInner(message, title || '提示') + createButtons(btnArray || ['取消', '确认']), callback);
  7231. }
  7232. return plus.nativeUI.confirm(message, callback, title, btnArray || ['取消', '确认']);
  7233. };
  7234. var createPrompt = function(message, placeholder, title, btnArray, callback, type) {
  7235. if (typeof message === 'undefined') {
  7236. return;
  7237. } else {
  7238. if (typeof placeholder === 'function') {
  7239. callback = placeholder;
  7240. type = title;
  7241. placeholder = null;
  7242. title = null;
  7243. btnArray = null;
  7244. } else if (typeof title === 'function') {
  7245. callback = title;
  7246. type = btnArray;
  7247. title = null;
  7248. btnArray = null;
  7249. } else if (typeof btnArray === 'function') {
  7250. type = callback;
  7251. callback = btnArray;
  7252. btnArray = null;
  7253. }
  7254. }
  7255. if (!$.os.plus || type === 'div') {
  7256. return createPopup(createInner(message, title || '提示', createInput(placeholder)) + createButtons(btnArray || ['取消', '确认']), callback);
  7257. }
  7258. return plus.nativeUI.prompt(message, callback, title || '提示', placeholder, btnArray || ['取消', '确认']);
  7259. };
  7260. var closePopup = function() {
  7261. if (popupStack.length) {
  7262. popupStack[popupStack.length - 1]['close']();
  7263. return true;
  7264. } else {
  7265. return false;
  7266. }
  7267. };
  7268. var closePopups = function() {
  7269. while (popupStack.length) {
  7270. popupStack[popupStack.length - 1]['close']();
  7271. }
  7272. };
  7273. $.closePopup = closePopup;
  7274. $.closePopups = closePopups;
  7275. $.alert = createAlert;
  7276. $.confirm = createConfirm;
  7277. $.prompt = createPrompt;
  7278. })(mui, window, document);
  7279. (function($, document) {
  7280. var CLASS_PROGRESSBAR = 'mui-progressbar';
  7281. var CLASS_PROGRESSBAR_IN = 'mui-progressbar-in';
  7282. var CLASS_PROGRESSBAR_OUT = 'mui-progressbar-out';
  7283. var CLASS_PROGRESSBAR_INFINITE = 'mui-progressbar-infinite';
  7284. var SELECTOR_PROGRESSBAR = '.mui-progressbar';
  7285. var _findProgressbar = function(container) {
  7286. container = $(container || 'body');
  7287. if (container.length === 0) return;
  7288. container = container[0];
  7289. if (container.classList.contains(CLASS_PROGRESSBAR)) {
  7290. return container;
  7291. }
  7292. var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR);
  7293. if (progressbars) {
  7294. for (var i = 0, len = progressbars.length; i < len; i++) {
  7295. var progressbar = progressbars[i];
  7296. if (progressbar.parentNode === container) {
  7297. return progressbar;
  7298. }
  7299. }
  7300. }
  7301. };
  7302. /**
  7303. * 创建并显示进度条
  7304. * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
  7305. * @param {Object} progress 可选,undefined表示循环,数字表示具体进度
  7306. * @param {Object} color 可选,指定颜色样式(目前暂未提供实际样式,可暂时不暴露此参数)
  7307. */
  7308. var showProgressbar = function(container, progress, color) {
  7309. if (typeof container === 'number') {
  7310. color = progress;
  7311. progress = container;
  7312. container = 'body';
  7313. }
  7314. container = $(container || 'body');
  7315. if (container.length === 0) return;
  7316. container = container[0];
  7317. var progressbar;
  7318. if (container.classList.contains(CLASS_PROGRESSBAR)) {
  7319. progressbar = container;
  7320. } else {
  7321. var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR + ':not(.' + CLASS_PROGRESSBAR_OUT + ')');
  7322. if (progressbars) {
  7323. for (var i = 0, len = progressbars.length; i < len; i++) {
  7324. var _progressbar = progressbars[i];
  7325. if (_progressbar.parentNode === container) {
  7326. progressbar = _progressbar;
  7327. break;
  7328. }
  7329. }
  7330. }
  7331. if (!progressbar) {
  7332. progressbar = document.createElement('span');
  7333. progressbar.className = CLASS_PROGRESSBAR + ' ' + CLASS_PROGRESSBAR_IN + (typeof progress !== 'undefined' ? '' : (' ' + CLASS_PROGRESSBAR_INFINITE)) + (color ? (' ' + CLASS_PROGRESSBAR + '-' + color) : '');
  7334. if (typeof progress !== 'undefined') {
  7335. progressbar.innerHTML = '<span></span>';
  7336. }
  7337. container.appendChild(progressbar);
  7338. } else {
  7339. progressbar.classList.add(CLASS_PROGRESSBAR_IN);
  7340. }
  7341. }
  7342. if (progress) setProgressbar(container, progress);
  7343. return progressbar;
  7344. };
  7345. /**
  7346. * 关闭进度条
  7347. * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
  7348. */
  7349. var hideProgressbar = function(container) {
  7350. var progressbar = _findProgressbar(container);
  7351. if (!progressbar) {
  7352. return;
  7353. }
  7354. var classList = progressbar.classList;
  7355. if (!classList.contains(CLASS_PROGRESSBAR_IN) || classList.contains(CLASS_PROGRESSBAR_OUT)) {
  7356. return;
  7357. }
  7358. classList.remove(CLASS_PROGRESSBAR_IN);
  7359. classList.add(CLASS_PROGRESSBAR_OUT);
  7360. progressbar.addEventListener('webkitAnimationEnd', function() {
  7361. progressbar.parentNode && progressbar.parentNode.removeChild(progressbar);
  7362. progressbar = null;
  7363. });
  7364. return;
  7365. };
  7366. /**
  7367. * 设置指定进度条进度
  7368. * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
  7369. * @param {Object} progress 可选,默认0 取值范围[0-100]
  7370. * @param {Object} speed 进度条动画时间
  7371. */
  7372. var setProgressbar = function(container, progress, speed) {
  7373. if (typeof container === 'number') {
  7374. speed = progress;
  7375. progress = container;
  7376. container = false;
  7377. }
  7378. var progressbar = _findProgressbar(container);
  7379. if (!progressbar || progressbar.classList.contains(CLASS_PROGRESSBAR_INFINITE)) {
  7380. return;
  7381. }
  7382. if (progress) progress = Math.min(Math.max(progress, 0), 100);
  7383. progressbar.offsetHeight;
  7384. var span = progressbar.querySelector('span');
  7385. if (span) {
  7386. var style = span.style;
  7387. style.webkitTransform = 'translate3d(' + (-100 + progress) + '%,0,0)';
  7388. if (typeof speed !== 'undefined') {
  7389. style.webkitTransitionDuration = speed + 'ms';
  7390. } else {
  7391. style.webkitTransitionDuration = '';
  7392. }
  7393. }
  7394. return progressbar;
  7395. };
  7396. $.fn.progressbar = function(options) {
  7397. var progressbarApis = [];
  7398. options = options || {};
  7399. this.each(function() {
  7400. var self = this;
  7401. var progressbarApi = self.mui_plugin_progressbar;
  7402. if (!progressbarApi) {
  7403. self.mui_plugin_progressbar = progressbarApi = {
  7404. options: options,
  7405. setOptions: function(options) {
  7406. this.options = options;
  7407. },
  7408. show: function() {
  7409. return showProgressbar(self, this.options.progress, this.options.color);
  7410. },
  7411. setProgress: function(progress) {
  7412. return setProgressbar(self, progress);
  7413. },
  7414. hide: function() {
  7415. return hideProgressbar(self);
  7416. }
  7417. };
  7418. } else if (options) {
  7419. progressbarApi.setOptions(options);
  7420. }
  7421. progressbarApis.push(progressbarApi);
  7422. });
  7423. return progressbarApis.length === 1 ? progressbarApis[0] : progressbarApis;
  7424. };
  7425. // $.setProgressbar = setProgressbar;
  7426. // $.showProgressbar = showProgressbar;
  7427. // $.hideProgressbar = hideProgressbar;
  7428. })(mui, document);
  7429. /**
  7430. * Input(TODO resize)
  7431. * @param {type} $
  7432. * @param {type} window
  7433. * @param {type} document
  7434. * @returns {undefined}
  7435. */
  7436. (function($, window, document) {
  7437. var CLASS_ICON = 'mui-icon';
  7438. var CLASS_ICON_CLEAR = 'mui-icon-clear';
  7439. var CLASS_ICON_SPEECH = 'mui-icon-speech';
  7440. var CLASS_ICON_SEARCH = 'mui-icon-search';
  7441. var CLASS_ICON_PASSWORD = 'mui-icon-eye';
  7442. var CLASS_INPUT_ROW = 'mui-input-row';
  7443. var CLASS_PLACEHOLDER = 'mui-placeholder';
  7444. var CLASS_TOOLTIP = 'mui-tooltip';
  7445. var CLASS_HIDDEN = 'mui-hidden';
  7446. var CLASS_FOCUSIN = 'mui-focusin';
  7447. var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR;
  7448. var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH;
  7449. var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD;
  7450. var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER;
  7451. var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP;
  7452. var findRow = function(target) {
  7453. for (; target && target !== document; target = target.parentNode) {
  7454. if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) {
  7455. return target;
  7456. }
  7457. }
  7458. return null;
  7459. };
  7460. var Input = function(element, options) {
  7461. this.element = element;
  7462. this.options = options || {
  7463. actions: 'clear'
  7464. };
  7465. if (~this.options.actions.indexOf('slider')) { //slider
  7466. this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN;
  7467. this.sliderActionSelector = SELECTOR_TOOLTIP;
  7468. } else { //clear,speech,search
  7469. if (~this.options.actions.indexOf('clear')) {
  7470. this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN;
  7471. this.clearActionSelector = SELECTOR_ICON_CLOSE;
  7472. }
  7473. if (~this.options.actions.indexOf('speech')) { //only for 5+
  7474. this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH;
  7475. this.speechActionSelector = SELECTOR_ICON_SPEECH;
  7476. }
  7477. if (~this.options.actions.indexOf('search')) {
  7478. this.searchActionClass = CLASS_PLACEHOLDER;
  7479. this.searchActionSelector = SELECTOR_PLACEHOLDER;
  7480. }
  7481. if (~this.options.actions.indexOf('password')) {
  7482. this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD;
  7483. this.passwordActionSelector = SELECTOR_ICON_PASSWORD;
  7484. }
  7485. }
  7486. this.init();
  7487. };
  7488. Input.prototype.init = function() {
  7489. this.initAction();
  7490. this.initElementEvent();
  7491. };
  7492. Input.prototype.initAction = function() {
  7493. var self = this;
  7494. var row = self.element.parentNode;
  7495. if (row) {
  7496. if (self.sliderActionClass) {
  7497. self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector);
  7498. } else {
  7499. if (self.searchActionClass) {
  7500. self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector);
  7501. self.searchAction.addEventListener('tap', function(e) {
  7502. $.focus(self.element);
  7503. e.stopPropagation();
  7504. });
  7505. }
  7506. if (self.speechActionClass) {
  7507. self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector);
  7508. self.speechAction.addEventListener('click', $.stopPropagation);
  7509. self.speechAction.addEventListener('tap', function(event) {
  7510. self.speechActionClick(event);
  7511. });
  7512. }
  7513. if (self.clearActionClass) {
  7514. self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector);
  7515. self.clearAction.addEventListener('tap', function(event) {
  7516. self.clearActionClick(event);
  7517. });
  7518. }
  7519. if (self.passwordActionClass) {
  7520. self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector);
  7521. self.passwordAction.addEventListener('tap', function(event) {
  7522. self.passwordActionClick(event);
  7523. });
  7524. }
  7525. }
  7526. }
  7527. };
  7528. Input.prototype.createAction = function(row, actionClass, actionSelector) {
  7529. var action = row.querySelector(actionSelector);
  7530. if (!action) {
  7531. var action = document.createElement('span');
  7532. action.className = actionClass;
  7533. if (actionClass === this.searchActionClass) {
  7534. action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>';
  7535. this.element.setAttribute('placeholder', '');
  7536. if (this.element.value.trim()) {
  7537. row.classList.add('mui-active');
  7538. }
  7539. }
  7540. row.insertBefore(action, this.element.nextSibling);
  7541. }
  7542. return action;
  7543. };
  7544. Input.prototype.initElementEvent = function() {
  7545. var element = this.element;
  7546. if (this.sliderActionClass) {
  7547. var tooltip = this.sliderAction;
  7548. var timer = null;
  7549. var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的
  7550. tooltip.classList.remove(CLASS_HIDDEN);
  7551. var offsetLeft = element.offsetLeft;
  7552. var width = element.offsetWidth - 28;
  7553. var tooltipWidth = tooltip.offsetWidth;
  7554. var distince = Math.abs(element.max - element.min);
  7555. var scaleWidth = (width / distince) * Math.abs(element.value - element.min);
  7556. tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px';
  7557. tooltip.innerText = element.value;
  7558. if (timer) {
  7559. clearTimeout(timer);
  7560. }
  7561. timer = setTimeout(function() {
  7562. tooltip.classList.add(CLASS_HIDDEN);
  7563. }, 1000);
  7564. };
  7565. element.addEventListener('input', showTip);
  7566. element.addEventListener('tap', showTip);
  7567. element.addEventListener($.EVENT_MOVE, function(e) {
  7568. e.stopPropagation();
  7569. });
  7570. } else {
  7571. if (this.clearActionClass) {
  7572. var action = this.clearAction;
  7573. if (!action) {
  7574. return;
  7575. }
  7576. $.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) {
  7577. (function(type) {
  7578. element.addEventListener(type, function() {
  7579. action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN);
  7580. });
  7581. })(type);
  7582. });
  7583. element.addEventListener('blur', function() {
  7584. action.classList.add(CLASS_HIDDEN);
  7585. });
  7586. }
  7587. if (this.searchActionClass) {
  7588. element.addEventListener('focus', function() {
  7589. element.parentNode.classList.add('mui-active');
  7590. });
  7591. element.addEventListener('blur', function() {
  7592. if (!element.value.trim()) {
  7593. element.parentNode.classList.remove('mui-active');
  7594. }
  7595. });
  7596. }
  7597. }
  7598. };
  7599. Input.prototype.setPlaceholder = function(text) {
  7600. if (this.searchActionClass) {
  7601. var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER);
  7602. placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text);
  7603. } else {
  7604. this.element.setAttribute('placeholder', text);
  7605. }
  7606. };
  7607. Input.prototype.passwordActionClick = function(event) {
  7608. if (this.element.type === 'text') {
  7609. this.element.type = 'password';
  7610. } else {
  7611. this.element.type = 'text';
  7612. }
  7613. this.passwordAction.classList.toggle('mui-active');
  7614. event.preventDefault();
  7615. };
  7616. Input.prototype.clearActionClick = function(event) {
  7617. var self = this;
  7618. self.element.value = '';
  7619. $.focus(self.element);
  7620. self.clearAction.classList.add(CLASS_HIDDEN);
  7621. event.preventDefault();
  7622. };
  7623. Input.prototype.speechActionClick = function(event) {
  7624. if (window.plus) {
  7625. var self = this;
  7626. var oldValue = self.element.value;
  7627. self.element.value = '';
  7628. document.body.classList.add(CLASS_FOCUSIN);
  7629. plus.speech.startRecognize({
  7630. engine: 'iFly'
  7631. }, function(s) {
  7632. self.element.value += s;
  7633. $.focus(self.element);
  7634. plus.speech.stopRecognize();
  7635. $.trigger(self.element, 'recognized', {
  7636. value: self.element.value
  7637. });
  7638. if (oldValue !== self.element.value) {
  7639. $.trigger(self.element, 'change');
  7640. $.trigger(self.element, 'input');
  7641. }
  7642. // document.body.classList.remove(CLASS_FOCUSIN);
  7643. }, function(e) {
  7644. document.body.classList.remove(CLASS_FOCUSIN);
  7645. });
  7646. } else {
  7647. alert('only for 5+');
  7648. }
  7649. event.preventDefault();
  7650. };
  7651. $.fn.input = function(options) {
  7652. var inputApis = [];
  7653. this.each(function() {
  7654. var inputApi = null;
  7655. var actions = [];
  7656. var row = findRow(this.parentNode);
  7657. if (this.type === 'range' && row.classList.contains('mui-input-range')) {
  7658. actions.push('slider');
  7659. } else {
  7660. var classList = this.classList;
  7661. if (classList.contains('mui-input-clear')) {
  7662. actions.push('clear');
  7663. }
  7664. if (!($.os.android && $.os.stream) && classList.contains('mui-input-speech')) {
  7665. actions.push('speech');
  7666. }
  7667. if (classList.contains('mui-input-password')) {
  7668. actions.push('password');
  7669. }
  7670. if (this.type === 'search' && row.classList.contains('mui-search')) {
  7671. actions.push('search');
  7672. }
  7673. }
  7674. var id = this.getAttribute('data-input-' + actions[0]);
  7675. if (!id) {
  7676. id = ++$.uuid;
  7677. inputApi = $.data[id] = new Input(this, {
  7678. actions: actions.join(',')
  7679. });
  7680. for (var i = 0, len = actions.length; i < len; i++) {
  7681. this.setAttribute('data-input-' + actions[i], id);
  7682. }
  7683. } else {
  7684. inputApi = $.data[id];
  7685. }
  7686. inputApis.push(inputApi);
  7687. });
  7688. return inputApis.length === 1 ? inputApis[0] : inputApis;
  7689. };
  7690. $.ready(function() {
  7691. $('.mui-input-row input').input();
  7692. });
  7693. })(mui, window, document);
  7694. (function($, window) {
  7695. var CLASS_ACTIVE = 'mui-active';
  7696. var rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/;
  7697. var getColor = function(colorStr) {
  7698. var matches = colorStr.match(rgbaRegex);
  7699. if (matches && matches.length === 5) {
  7700. return [
  7701. matches[1],
  7702. matches[2],
  7703. matches[3],
  7704. matches[4]
  7705. ];
  7706. }
  7707. return [];
  7708. };
  7709. var Transparent = function(element, options) {
  7710. this.element = element;
  7711. this.options = $.extend({
  7712. top: 0, //距离顶部高度(到达该高度即触发)
  7713. offset: 150, //滚动透明距离
  7714. duration: 16, //过渡时间
  7715. scrollby: window//监听滚动距离容器
  7716. }, options || {});
  7717. this.scrollByElem = this.options.scrollby || window;
  7718. if (!this.scrollByElem) {
  7719. throw new Error("监听滚动的元素不存在");
  7720. }
  7721. this.isNativeScroll = false;
  7722. if (this.scrollByElem === window) {
  7723. this.isNativeScroll = true;
  7724. } else if (!~this.scrollByElem.className.indexOf('mui-scroll-wrapper')) {
  7725. this.isNativeScroll = true;
  7726. }
  7727. this._style = this.element.style;
  7728. this._bgColor = this._style.backgroundColor;
  7729. var color = getColor(mui.getStyles(this.element, 'backgroundColor'));
  7730. if (color.length) {
  7731. this._R = color[0];
  7732. this._G = color[1];
  7733. this._B = color[2];
  7734. this._A = parseFloat(color[3]);
  7735. this.lastOpacity = this._A;
  7736. this._bufferFn = $.buffer(this.handleScroll, this.options.duration, this);
  7737. this.initEvent();
  7738. } else {
  7739. throw new Error("元素背景颜色必须为RGBA");
  7740. }
  7741. };
  7742. Transparent.prototype.initEvent = function() {
  7743. this.scrollByElem.addEventListener('scroll', this._bufferFn);
  7744. if (this.isNativeScroll) { //原生scroll
  7745. this.scrollByElem.addEventListener($.EVENT_MOVE, this._bufferFn);
  7746. }
  7747. }
  7748. Transparent.prototype.handleScroll = function(e) {
  7749. var y = window.scrollY;
  7750. if (!this.isNativeScroll && e && e.detail) {
  7751. y = -e.detail.y;
  7752. }
  7753. var opacity = (y - this.options.top) / this.options.offset + this._A;
  7754. opacity = Math.min(Math.max(this._A, opacity), 1);
  7755. this._style.backgroundColor = 'rgba(' + this._R + ',' + this._G + ',' + this._B + ',' + opacity + ')';
  7756. if (opacity > this._A) {
  7757. this.element.classList.add(CLASS_ACTIVE);
  7758. } else {
  7759. this.element.classList.remove(CLASS_ACTIVE);
  7760. }
  7761. if (this.lastOpacity !== opacity) {
  7762. $.trigger(this.element, 'alpha', {
  7763. alpha: opacity
  7764. });
  7765. this.lastOpacity = opacity;
  7766. }
  7767. };
  7768. Transparent.prototype.destory = function() {
  7769. this.scrollByElem.removeEventListener('scroll', this._bufferFn);
  7770. this.scrollByElem.removeEventListener($.EVENT_MOVE, this._bufferFn);
  7771. this.element.style.backgroundColor = this._bgColor;
  7772. this.element.mui_plugin_transparent = null;
  7773. };
  7774. $.fn.transparent = function(options) {
  7775. options = options || {};
  7776. var transparentApis = [];
  7777. this.each(function() {
  7778. var transparentApi = this.mui_plugin_transparent;
  7779. if (!transparentApi) {
  7780. var top = this.getAttribute('data-top');
  7781. var offset = this.getAttribute('data-offset');
  7782. var duration = this.getAttribute('data-duration');
  7783. var scrollby = this.getAttribute('data-scrollby');
  7784. if (top !== null && typeof options.top === 'undefined') {
  7785. options.top = top;
  7786. }
  7787. if (offset !== null && typeof options.offset === 'undefined') {
  7788. options.offset = offset;
  7789. }
  7790. if (duration !== null && typeof options.duration === 'undefined') {
  7791. options.duration = duration;
  7792. }
  7793. if (scrollby !== null && typeof options.scrollby === 'undefined') {
  7794. options.scrollby = document.querySelector(scrollby) || window;
  7795. }
  7796. transparentApi = this.mui_plugin_transparent = new Transparent(this, options);
  7797. }
  7798. transparentApis.push(transparentApi);
  7799. });
  7800. return transparentApis.length === 1 ? transparentApis[0] : transparentApis;
  7801. };
  7802. $.ready(function() {
  7803. $('.mui-bar-transparent').transparent();
  7804. });
  7805. })(mui, window);
  7806. /**
  7807. * 数字输入框
  7808. * varstion 1.0.1
  7809. * by Houfeng
  7810. * Houfeng@DCloud.io
  7811. */
  7812. (function($) {
  7813. var touchSupport = ('ontouchstart' in document);
  7814. var tapEventName = touchSupport ? 'tap' : 'click';
  7815. var changeEventName = 'change';
  7816. var holderClassName = 'mui-numbox';
  7817. var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus';
  7818. var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus';
  7819. var inputClassSelector = '.mui-input-numbox,.mui-numbox-input';
  7820. var Numbox = $.Numbox = $.Class.extend({
  7821. /**
  7822. * 构造函数
  7823. **/
  7824. init: function(holder, options) {
  7825. var self = this;
  7826. if (!holder) {
  7827. throw "构造 numbox 时缺少容器元素";
  7828. }
  7829. self.holder = holder;
  7830. options = options || {};
  7831. options.step = parseInt(options.step || 1);
  7832. self.options = options;
  7833. self.input = $.qsa(inputClassSelector, self.holder)[0];
  7834. self.plus = $.qsa(plusClassSelector, self.holder)[0];
  7835. self.minus = $.qsa(minusClassSelector, self.holder)[0];
  7836. self.checkValue();
  7837. self.initEvent();
  7838. },
  7839. /**
  7840. * 初始化事件绑定
  7841. **/
  7842. initEvent: function() {
  7843. var self = this;
  7844. self.plus.addEventListener(tapEventName, function(event) {
  7845. var val = parseInt(self.input.value) + self.options.step;
  7846. self.input.value = val.toString();
  7847. $.trigger(self.input, changeEventName, null);
  7848. });
  7849. self.minus.addEventListener(tapEventName, function(event) {
  7850. var val = parseInt(self.input.value) - self.options.step;
  7851. self.input.value = val.toString();
  7852. $.trigger(self.input, changeEventName, null);
  7853. });
  7854. self.input.addEventListener(changeEventName, function(event) {
  7855. self.checkValue();
  7856. var val = parseInt(self.input.value);
  7857. //触发顶层容器
  7858. $.trigger(self.holder, changeEventName, {
  7859. value: val
  7860. });
  7861. });
  7862. },
  7863. /**
  7864. * 获取当前值
  7865. **/
  7866. getValue: function() {
  7867. var self = this;
  7868. return parseInt(self.input.value);
  7869. },
  7870. /**
  7871. * 验证当前值是法合法
  7872. **/
  7873. checkValue: function() {
  7874. var self = this;
  7875. var val = self.input.value;
  7876. if (val == null || val == '' || isNaN(val)) {
  7877. self.input.value = self.options.min || 0;
  7878. self.minus.disabled = self.options.min != null;
  7879. } else {
  7880. var val = parseInt(val);
  7881. if (self.options.max != null && !isNaN(self.options.max) && val >= parseInt(self.options.max)) {
  7882. val = self.options.max;
  7883. self.plus.disabled = true;
  7884. } else {
  7885. self.plus.disabled = false;
  7886. }
  7887. if (self.options.min != null && !isNaN(self.options.min) && val <= parseInt(self.options.min)) {
  7888. val = self.options.min;
  7889. self.minus.disabled = true;
  7890. } else {
  7891. self.minus.disabled = false;
  7892. }
  7893. self.input.value = val;
  7894. }
  7895. },
  7896. /**
  7897. * 更新选项
  7898. **/
  7899. setOption: function(name, value) {
  7900. var self = this;
  7901. self.options[name] = value;
  7902. },
  7903. /**
  7904. * 动态设置新值
  7905. **/
  7906. setValue: function(value) {
  7907. this.input.value = value;
  7908. this.checkValue();
  7909. }
  7910. });
  7911. $.fn.numbox = function(options) {
  7912. var instanceArray = [];
  7913. //遍历选择的元素
  7914. this.each(function(i, element) {
  7915. if (element.numbox) {
  7916. return;
  7917. }
  7918. if (options) {
  7919. element.numbox = new Numbox(element, options);
  7920. } else {
  7921. var optionsText = element.getAttribute('data-numbox-options');
  7922. var options = optionsText ? JSON.parse(optionsText) : {};
  7923. options.step = element.getAttribute('data-numbox-step') || options.step;
  7924. options.min = element.getAttribute('data-numbox-min') || options.min;
  7925. options.max = element.getAttribute('data-numbox-max') || options.max;
  7926. element.numbox = new Numbox(element, options);
  7927. }
  7928. });
  7929. return this[0] ? this[0].numbox : null;
  7930. }
  7931. //自动处理 class='mui-locker' 的 dom
  7932. $.ready(function() {
  7933. $('.' + holderClassName).numbox();
  7934. });
  7935. }(mui));
  7936. /**
  7937. * Button
  7938. * @param {type} $
  7939. * @param {type} window
  7940. * @param {type} document
  7941. * @returns {undefined}
  7942. */
  7943. (function($, window, document) {
  7944. var CLASS_ICON = 'mui-icon';
  7945. var CLASS_DISABLED = 'mui-disabled';
  7946. var STATE_RESET = 'reset';
  7947. var STATE_LOADING = 'loading';
  7948. var defaultOptions = {
  7949. loadingText: 'Loading...', //文案
  7950. loadingIcon: 'mui-spinner' + ' ' + 'mui-spinner-white', //图标,可为空
  7951. loadingIconPosition: 'left' //图标所处位置,仅支持left|right
  7952. };
  7953. var Button = function(element, options) {
  7954. this.element = element;
  7955. this.options = $.extend({}, defaultOptions, options);
  7956. if (!this.options.loadingText) {
  7957. this.options.loadingText = defaultOptions.loadingText;
  7958. }
  7959. if (this.options.loadingIcon === null) {
  7960. this.options.loadingIcon = 'mui-spinner';
  7961. if ($.getStyles(this.element, 'color') === 'rgb(255, 255, 255)') {
  7962. this.options.loadingIcon += ' ' + 'mui-spinner-white';
  7963. }
  7964. }
  7965. this.isInput = this.element.tagName === 'INPUT';
  7966. this.resetHTML = this.isInput ? this.element.value : this.element.innerHTML;
  7967. this.state = '';
  7968. };
  7969. Button.prototype.loading = function() {
  7970. this.setState(STATE_LOADING);
  7971. };
  7972. Button.prototype.reset = function() {
  7973. this.setState(STATE_RESET);
  7974. };
  7975. Button.prototype.setState = function(state) {
  7976. if (this.state === state) {
  7977. return false;
  7978. }
  7979. this.state = state;
  7980. if (state === STATE_RESET) {
  7981. this.element.disabled = false;
  7982. this.element.classList.remove(CLASS_DISABLED);
  7983. this.setHtml(this.resetHTML);
  7984. } else if (state === STATE_LOADING) {
  7985. this.element.disabled = true;
  7986. this.element.classList.add(CLASS_DISABLED);
  7987. var html = this.isInput ? this.options.loadingText : ('<span>' + this.options.loadingText + '</span>');
  7988. if (this.options.loadingIcon && !this.isInput) {
  7989. if (this.options.loadingIconPosition === 'right') {
  7990. html += '&nbsp;<span class="' + this.options.loadingIcon + '"></span>';
  7991. } else {
  7992. html = '<span class="' + this.options.loadingIcon + '"></span>&nbsp;' + html;
  7993. }
  7994. }
  7995. this.setHtml(html);
  7996. }
  7997. };
  7998. Button.prototype.setHtml = function(html) {
  7999. if (this.isInput) {
  8000. this.element.value = html;
  8001. } else {
  8002. this.element.innerHTML = html;
  8003. }
  8004. }
  8005. $.fn.button = function(state) {
  8006. var buttonApis = [];
  8007. this.each(function() {
  8008. var buttonApi = this.mui_plugin_button;
  8009. if (!buttonApi) {
  8010. var loadingText = this.getAttribute('data-loading-text');
  8011. var loadingIcon = this.getAttribute('data-loading-icon');
  8012. var loadingIconPosition = this.getAttribute('data-loading-icon-position');
  8013. this.mui_plugin_button = buttonApi = new Button(this, {
  8014. loadingText: loadingText,
  8015. loadingIcon: loadingIcon,
  8016. loadingIconPosition: loadingIconPosition
  8017. });
  8018. }
  8019. if (state === STATE_LOADING || state === STATE_RESET) {
  8020. buttonApi.setState(state);
  8021. }
  8022. buttonApis.push(buttonApi);
  8023. });
  8024. return buttonApis.length === 1 ? buttonApis[0] : buttonApis;
  8025. };
  8026. })(mui, window, document);