1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386 |
- /*!
- * =====================================================
- * Mui v3.7.2 (http://dev.dcloud.net.cn/mui)
- * =====================================================
- */
- /**
- * MUI核心JS
- * @type _L4.$|Function
- */
- var mui = (function(document, undefined) {
- var readyRE = /complete|loaded|interactive/;
- var idSelectorRE = /^#([\w-]+)$/;
- var classSelectorRE = /^\.([\w-]+)$/;
- var tagSelectorRE = /^[\w-]+$/;
- var translateRE = /translate(?:3d)?\((.+?)\)/;
- var translateMatrixRE = /matrix(3d)?\((.+?)\)/;
- var $ = function(selector, context) {
- context = context || document;
- if (!selector)
- return wrap();
- if (typeof selector === 'object')
- if ($.isArrayLike(selector)) {
- return wrap($.slice.call(selector), null);
- } else {
- return wrap([selector], null);
- }
- if (typeof selector === 'function')
- return $.ready(selector);
- if (typeof selector === 'string') {
- try {
- selector = selector.trim();
- if (idSelectorRE.test(selector)) {
- var found = document.getElementById(RegExp.$1);
- return wrap(found ? [found] : []);
- }
- return wrap($.qsa(selector, context), selector);
- } catch (e) {}
- }
- return wrap();
- };
- var wrap = function(dom, selector) {
- dom = dom || [];
- Object.setPrototypeOf(dom, $.fn);
- dom.selector = selector || '';
- return dom;
- };
- $.uuid = 0;
- $.data = {};
- /**
- * extend(simple)
- * @param {type} target
- * @param {type} source
- * @param {type} deep
- * @returns {unresolved}
- */
- $.extend = function() { //from jquery2
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
- if (typeof target === "boolean") {
- deep = target;
- target = arguments[i] || {};
- i++;
- }
- if (typeof target !== "object" && !$.isFunction(target)) {
- target = {};
- }
- if (i === length) {
- target = this;
- i--;
- }
- for (; i < length; i++) {
- if ((options = arguments[i]) != null) {
- for (name in options) {
- src = target[name];
- copy = options[name];
- if (target === copy) {
- continue;
- }
- if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {
- if (copyIsArray) {
- copyIsArray = false;
- clone = src && $.isArray(src) ? src : [];
- } else {
- clone = src && $.isPlainObject(src) ? src : {};
- }
- target[name] = $.extend(deep, clone, copy);
- } else if (copy !== undefined) {
- target[name] = copy;
- }
- }
- }
- }
- return target;
- };
- /**
- * mui noop(function)
- */
- $.noop = function() {};
- /**
- * mui slice(array)
- */
- $.slice = [].slice;
- /**
- * mui filter(array)
- */
- $.filter = [].filter;
- $.type = function(obj) {
- return obj == null ? String(obj) : class2type[{}.toString.call(obj)] || "object";
- };
- /**
- * mui isArray
- */
- $.isArray = Array.isArray ||
- function(object) {
- return object instanceof Array;
- };
- /**
- * mui isArrayLike
- * @param {Object} obj
- */
- $.isArrayLike = function(obj) {
- var length = !!obj && "length" in obj && obj.length;
- var type = $.type(obj);
- if (type === "function" || $.isWindow(obj)) {
- return false;
- }
- return type === "array" || length === 0 ||
- typeof length === "number" && length > 0 && (length - 1) in obj;
- };
- /**
- * mui isWindow(需考虑obj为undefined的情况)
- */
- $.isWindow = function(obj) {
- return obj != null && obj === obj.window;
- };
- /**
- * mui isObject
- */
- $.isObject = function(obj) {
- return $.type(obj) === "object";
- };
- /**
- * mui isPlainObject
- */
- $.isPlainObject = function(obj) {
- return $.isObject(obj) && !$.isWindow(obj) && Object.getPrototypeOf(obj) === Object.prototype;
- };
- /**
- * mui isEmptyObject
- * @param {Object} o
- */
- $.isEmptyObject = function(o) {
- for (var p in o) {
- if (p !== undefined) {
- return false;
- }
- }
- return true;
- };
- /**
- * mui isFunction
- */
- $.isFunction = function(value) {
- return $.type(value) === "function";
- };
- /**
- * mui querySelectorAll
- * @param {type} selector
- * @param {type} context
- * @returns {Array}
- */
- $.qsa = function(selector, context) {
- context = context || document;
- return $.slice.call(classSelectorRE.test(selector) ? context.getElementsByClassName(RegExp.$1) : tagSelectorRE.test(selector) ? context.getElementsByTagName(selector) : context.querySelectorAll(selector));
- };
- /**
- * ready(DOMContentLoaded)
- * @param {type} callback
- * @returns {_L6.$}
- */
- $.ready = function(callback) {
- if (readyRE.test(document.readyState)) {
- callback($);
- } else {
- document.addEventListener('DOMContentLoaded', function() {
- callback($);
- }, false);
- }
- return this;
- };
- /**
- * 将 fn 缓存一段时间后, 再被调用执行
- * 此方法为了避免在 ms 段时间内, 执行 fn 多次. 常用于 resize , scroll , mousemove 等连续性事件中;
- * 当 ms 设置为 -1, 表示立即执行 fn, 即和直接调用 fn 一样;
- * 调用返回函数的 stop 停止最后一次的 buffer 效果
- * @param {Object} fn
- * @param {Object} ms
- * @param {Object} context
- */
- $.buffer = function(fn, ms, context) {
- var timer;
- var lastStart = 0;
- var lastEnd = 0;
- var ms = ms || 150;
- function run() {
- if (timer) {
- timer.cancel();
- timer = 0;
- }
- lastStart = $.now();
- fn.apply(context || this, arguments);
- lastEnd = $.now();
- }
- return $.extend(function() {
- if (
- (!lastStart) || // 从未运行过
- (lastEnd >= lastStart && $.now() - lastEnd > ms) || // 上次运行成功后已经超过ms毫秒
- (lastEnd < lastStart && $.now() - lastStart > ms * 8) // 上次运行或未完成,后8*ms毫秒
- ) {
- run.apply(this, arguments);
- } else {
- if (timer) {
- timer.cancel();
- }
- timer = $.later(run, ms, null, $.slice.call(arguments));
- }
- }, {
- stop: function() {
- if (timer) {
- timer.cancel();
- timer = 0;
- }
- }
- });
- };
- /**
- * each
- * @param {type} elements
- * @param {type} callback
- * @returns {_L8.$}
- */
- $.each = function(elements, callback, hasOwnProperty) {
- if (!elements) {
- return this;
- }
- if (typeof elements.length === 'number') {
- [].every.call(elements, function(el, idx) {
- return callback.call(el, idx, el) !== false;
- });
- } else {
- for (var key in elements) {
- if (hasOwnProperty) {
- if (elements.hasOwnProperty(key)) {
- if (callback.call(elements[key], key, elements[key]) === false) return elements;
- }
- } else {
- if (callback.call(elements[key], key, elements[key]) === false) return elements;
- }
- }
- }
- return this;
- };
- $.focus = function(element) {
- if ($.os.ios) {
- setTimeout(function() {
- element.focus();
- }, 10);
- } else {
- element.focus();
- }
- };
- /**
- * trigger event
- * @param {type} element
- * @param {type} eventType
- * @param {type} eventData
- * @returns {_L8.$}
- */
- $.trigger = function(element, eventType, eventData) {
- element.dispatchEvent(new CustomEvent(eventType, {
- detail: eventData,
- bubbles: true,
- cancelable: true
- }));
- return this;
- };
- /**
- * getStyles
- * @param {type} element
- * @param {type} property
- * @returns {styles}
- */
- $.getStyles = function(element, property) {
- var styles = element.ownerDocument.defaultView.getComputedStyle(element, null);
- if (property) {
- return styles.getPropertyValue(property) || styles[property];
- }
- return styles;
- };
- /**
- * parseTranslate
- * @param {type} translateString
- * @param {type} position
- * @returns {Object}
- */
- $.parseTranslate = function(translateString, position) {
- var result = translateString.match(translateRE || '');
- if (!result || !result[1]) {
- result = ['', '0,0,0'];
- }
- result = result[1].split(",");
- result = {
- x: parseFloat(result[0]),
- y: parseFloat(result[1]),
- z: parseFloat(result[2])
- };
- if (position && result.hasOwnProperty(position)) {
- return result[position];
- }
- return result;
- };
- /**
- * parseTranslateMatrix
- * @param {type} translateString
- * @param {type} position
- * @returns {Object}
- */
- $.parseTranslateMatrix = function(translateString, position) {
- var matrix = translateString.match(translateMatrixRE);
- var is3D = matrix && matrix[1];
- if (matrix) {
- matrix = matrix[2].split(",");
- if (is3D === "3d")
- matrix = matrix.slice(12, 15);
- else {
- matrix.push(0);
- matrix = matrix.slice(4, 7);
- }
- } else {
- matrix = [0, 0, 0];
- }
- var result = {
- x: parseFloat(matrix[0]),
- y: parseFloat(matrix[1]),
- z: parseFloat(matrix[2])
- };
- if (position && result.hasOwnProperty(position)) {
- return result[position];
- }
- return result;
- };
- $.hooks = {};
- $.addAction = function(type, hook) {
- var hooks = $.hooks[type];
- if (!hooks) {
- hooks = [];
- }
- hook.index = hook.index || 1000;
- hooks.push(hook);
- hooks.sort(function(a, b) {
- return a.index - b.index;
- });
- $.hooks[type] = hooks;
- return $.hooks[type];
- };
- $.doAction = function(type, callback) {
- if ($.isFunction(callback)) { //指定了callback
- $.each($.hooks[type], callback);
- } else { //未指定callback,直接执行
- $.each($.hooks[type], function(index, hook) {
- return !hook.handle();
- });
- }
- };
- /**
- * setTimeout封装
- * @param {Object} fn
- * @param {Object} when
- * @param {Object} context
- * @param {Object} data
- */
- $.later = function(fn, when, context, data) {
- when = when || 0;
- var m = fn;
- var d = data;
- var f;
- var r;
- if (typeof fn === 'string') {
- m = context[fn];
- }
- f = function() {
- m.apply(context, $.isArray(d) ? d : [d]);
- };
- r = setTimeout(f, when);
- return {
- id: r,
- cancel: function() {
- clearTimeout(r);
- }
- };
- };
- $.now = Date.now || function() {
- return +new Date();
- };
- var class2type = {};
- $.each(['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'], function(i, name) {
- class2type["[object " + name + "]"] = name.toLowerCase();
- });
- if (window.JSON) {
- $.parseJSON = JSON.parse;
- }
- /**
- * $.fn
- */
- $.fn = {
- each: function(callback) {
- [].every.call(this, function(el, idx) {
- return callback.call(el, idx, el) !== false;
- });
- return this;
- }
- };
- /**
- * 兼容 AMD 模块
- **/
- if (typeof define === 'function' && define.amd) {
- define('mui', [], function() {
- return $;
- });
- }
- return $;
- })(document);
- //window.mui = mui;
- //'$' in window || (window.$ = mui);
- /**
- * $.os
- * @param {type} $
- * @returns {undefined}
- */
- (function($, window) {
- function detect(ua) {
- this.os = {};
- var funcs = [
- function() { //wechat
- var wechat = ua.match(/(MicroMessenger)\/([\d\.]+)/i);
- if (wechat) { //wechat
- this.os.wechat = {
- version: wechat[2].replace(/_/g, '.')
- };
- }
- return false;
- },
- function() { //android
- var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
- if (android) {
- this.os.android = true;
- this.os.version = android[2];
- this.os.isBadAndroid = !(/Chrome\/\d/.test(window.navigator.appVersion));
- }
- return this.os.android === true;
- },
- function() { //ios
- var iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/);
- if (iphone) { //iphone
- this.os.ios = this.os.iphone = true;
- this.os.version = iphone[2].replace(/_/g, '.');
- } else {
- var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
- if (ipad) { //ipad
- this.os.ios = this.os.ipad = true;
- this.os.version = ipad[2].replace(/_/g, '.');
- }
- }
- return this.os.ios === true;
- }
- ];
- [].every.call(funcs, function(func) {
- return !func.call($);
- });
- }
- detect.call($, navigator.userAgent);
- })(mui, window);
- /**
- * $.os.plus
- * @param {type} $
- * @returns {undefined}
- */
- (function($, document) {
- function detect(ua) {
- this.os = this.os || {};
- var plus = ua.match(/Html5Plus/i); //TODO 5\+Browser?
- if (plus) {
- this.os.plus = true;
- $(function() {
- document.body.classList.add('mui-plus');
- });
- if (ua.match(/StreamApp/i)) { //TODO 最好有流应用自己的标识
- this.os.stream = true;
- $(function() {
- document.body.classList.add('mui-plus-stream');
- });
- }
- }
- }
- detect.call($, navigator.userAgent);
- })(mui, document);
- /**
- * 仅提供简单的on,off(仅支持事件委托,不支持当前元素绑定,当前元素绑定请直接使用addEventListener,removeEventListener)
- * @param {Object} $
- */
- (function($) {
- if ('ontouchstart' in window) {
- $.isTouchable = true;
- $.EVENT_START = 'touchstart';
- $.EVENT_MOVE = 'touchmove';
- $.EVENT_END = 'touchend';
- } else {
- $.isTouchable = false;
- $.EVENT_START = 'mousedown';
- $.EVENT_MOVE = 'mousemove';
- $.EVENT_END = 'mouseup';
- }
- $.EVENT_CANCEL = 'touchcancel';
- $.EVENT_CLICK = 'click';
- var _mid = 1;
- var delegates = {};
- //需要wrap的函数
- var eventMethods = {
- preventDefault: 'isDefaultPrevented',
- stopImmediatePropagation: 'isImmediatePropagationStopped',
- stopPropagation: 'isPropagationStopped'
- };
- //默认true返回函数
- var returnTrue = function() {
- return true
- };
- //默认false返回函数
- var returnFalse = function() {
- return false
- };
- //wrap浏览器事件
- var compatible = function(event, target) {
- if (!event.detail) {
- event.detail = {
- currentTarget: target
- };
- } else {
- event.detail.currentTarget = target;
- }
- $.each(eventMethods, function(name, predicate) {
- var sourceMethod = event[name];
- event[name] = function() {
- this[predicate] = returnTrue;
- return sourceMethod && sourceMethod.apply(event, arguments)
- }
- event[predicate] = returnFalse;
- }, true);
- return event;
- };
- //简单的wrap对象_mid
- var mid = function(obj) {
- return obj && (obj._mid || (obj._mid = _mid++));
- };
- //事件委托对象绑定的事件回调列表
- var delegateFns = {};
- //返回事件委托的wrap事件回调
- var delegateFn = function(element, event, selector, callback) {
- return function(e) {
- //same event
- var callbackObjs = delegates[element._mid][event];
- var handlerQueue = [];
- var target = e.target;
- var selectorAlls = {};
- for (; target && target !== document; target = target.parentNode) {
- if (target === element) {
- break;
- }
- if (~['click', 'tap', 'doubletap', 'longtap', 'hold'].indexOf(event) && (target.disabled || target.classList.contains('mui-disabled'))) {
- break;
- }
- var matches = {};
- $.each(callbackObjs, function(selector, callbacks) { //same selector
- selectorAlls[selector] || (selectorAlls[selector] = $.qsa(selector, element));
- if (selectorAlls[selector] && ~(selectorAlls[selector]).indexOf(target)) {
- if (!matches[selector]) {
- matches[selector] = callbacks;
- }
- }
- }, true);
- if (!$.isEmptyObject(matches)) {
- handlerQueue.push({
- element: target,
- handlers: matches
- });
- }
- }
- selectorAlls = null;
- e = compatible(e); //compatible event
- $.each(handlerQueue, function(index, handler) {
- target = handler.element;
- var tagName = target.tagName;
- if (event === 'tap' && (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && tagName !== 'SELECT')) {
- e.preventDefault();
- e.detail && e.detail.gesture && e.detail.gesture.preventDefault();
- }
- $.each(handler.handlers, function(index, handler) {
- $.each(handler, function(index, callback) {
- if (callback.call(target, e) === false) {
- e.preventDefault();
- e.stopPropagation();
- }
- }, true);
- }, true)
- if (e.isPropagationStopped()) {
- return false;
- }
- }, true);
- };
- };
- var findDelegateFn = function(element, event) {
- var delegateCallbacks = delegateFns[mid(element)];
- var result = [];
- if (delegateCallbacks) {
- result = [];
- if (event) {
- var filterFn = function(fn) {
- return fn.type === event;
- }
- return delegateCallbacks.filter(filterFn);
- } else {
- result = delegateCallbacks;
- }
- }
- return result;
- };
- var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
- /**
- * mui delegate events
- * @param {type} event
- * @param {type} selector
- * @param {type} callback
- * @returns {undefined}
- */
- $.fn.on = function(event, selector, callback) { //仅支持简单的事件委托,主要是tap事件使用,类似mouse,focus之类暂不封装支持
- return this.each(function() {
- var element = this;
- mid(element);
- mid(callback);
- var isAddEventListener = false;
- var delegateEvents = delegates[element._mid] || (delegates[element._mid] = {});
- var delegateCallbackObjs = delegateEvents[event] || ((delegateEvents[event] = {}));
- if ($.isEmptyObject(delegateCallbackObjs)) {
- isAddEventListener = true;
- }
- var delegateCallbacks = delegateCallbackObjs[selector] || (delegateCallbackObjs[selector] = []);
- delegateCallbacks.push(callback);
- if (isAddEventListener) {
- var delegateFnArray = delegateFns[mid(element)];
- if (!delegateFnArray) {
- delegateFnArray = [];
- }
- var delegateCallback = delegateFn(element, event, selector, callback);
- delegateFnArray.push(delegateCallback);
- delegateCallback.i = delegateFnArray.length - 1;
- delegateCallback.type = event;
- delegateFns[mid(element)] = delegateFnArray;
- element.addEventListener(event, delegateCallback);
- if (event === 'tap') { //TODO 需要找个更好的解决方案
- element.addEventListener('click', function(e) {
- if (e.target) {
- var tagName = e.target.tagName;
- if (!preventDefaultException.test(tagName)) {
- if (tagName === 'A') {
- var href = e.target.href;
- if (!(href && ~href.indexOf('tel:'))) {
- e.preventDefault();
- }
- } else {
- e.preventDefault();
- }
- }
- }
- });
- }
- }
- });
- };
- $.fn.off = function(event, selector, callback) {
- return this.each(function() {
- var _mid = mid(this);
- if (!event) { //mui(selector).off();
- delegates[_mid] && delete delegates[_mid];
- } else if (!selector) { //mui(selector).off(event);
- delegates[_mid] && delete delegates[_mid][event];
- } else if (!callback) { //mui(selector).off(event,selector);
- delegates[_mid] && delegates[_mid][event] && delete delegates[_mid][event][selector];
- } else { //mui(selector).off(event,selector,callback);
- var delegateCallbacks = delegates[_mid] && delegates[_mid][event] && delegates[_mid][event][selector];
- $.each(delegateCallbacks, function(index, delegateCallback) {
- if (mid(delegateCallback) === mid(callback)) {
- delegateCallbacks.splice(index, 1);
- return false;
- }
- }, true);
- }
- if (delegates[_mid]) {
- //如果off掉了所有当前element的指定的event事件,则remove掉当前element的delegate回调
- if ((!delegates[_mid][event] || $.isEmptyObject(delegates[_mid][event]))) {
- findDelegateFn(this, event).forEach(function(fn) {
- this.removeEventListener(fn.type, fn);
- delete delegateFns[_mid][fn.i];
- }.bind(this));
- }
- } else {
- //如果delegates[_mid]已不存在,删除所有
- findDelegateFn(this).forEach(function(fn) {
- this.removeEventListener(fn.type, fn);
- delete delegateFns[_mid][fn.i];
- }.bind(this));
- }
- });
- };
- })(mui);
- /**
- * mui target(action>popover>modal>tab>toggle)
- */
- (function($, window, document) {
- /**
- * targets
- */
- $.targets = {};
- /**
- * target handles
- */
- $.targetHandles = [];
- /**
- * register target
- * @param {type} target
- * @returns {$.targets}
- */
- $.registerTarget = function(target) {
- target.index = target.index || 1000;
- $.targetHandles.push(target);
- $.targetHandles.sort(function(a, b) {
- return a.index - b.index;
- });
- return $.targetHandles;
- };
- window.addEventListener($.EVENT_START, function(event) {
- var target = event.target;
- var founds = {};
- for (; target && target !== document; target = target.parentNode) {
- var isFound = false;
- $.each($.targetHandles, function(index, targetHandle) {
- var name = targetHandle.name;
- if (!isFound && !founds[name] && targetHandle.hasOwnProperty('handle')) {
- $.targets[name] = targetHandle.handle(event, target);
- if ($.targets[name]) {
- founds[name] = true;
- if (targetHandle.isContinue !== true) {
- isFound = true;
- }
- }
- } else {
- if (!founds[name]) {
- if (targetHandle.isReset !== false)
- $.targets[name] = false;
- }
- }
- });
- if (isFound) {
- break;
- }
- }
- });
- window.addEventListener('click', function(event) { //解决touch与click的target不一致的问题(比如链接边缘点击时,touch的target为html,而click的target为A)
- var target = event.target;
- var isFound = false;
- for (; target && target !== document; target = target.parentNode) {
- if (target.tagName === 'A') {
- $.each($.targetHandles, function(index, targetHandle) {
- var name = targetHandle.name;
- if (targetHandle.hasOwnProperty('handle')) {
- if (targetHandle.handle(event, target)) {
- isFound = true;
- event.preventDefault();
- return false;
- }
- }
- });
- if (isFound) {
- break;
- }
- }
- }
- });
- })(mui, window, document);
- /**
- * fixed trim
- * @param {type} undefined
- * @returns {undefined}
- */
- (function(undefined) {
- if (String.prototype.trim === undefined) { // fix for iOS 3.2
- String.prototype.trim = function() {
- return this.replace(/^\s+|\s+$/g, '');
- };
- }
- Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {
- obj['__proto__'] = proto;
- return obj;
- };
- })();
- /**
- * fixed CustomEvent
- */
- (function() {
- if (typeof window.CustomEvent === 'undefined') {
- function CustomEvent(event, params) {
- params = params || {
- bubbles: false,
- cancelable: false,
- detail: undefined
- };
- var evt = document.createEvent('Events');
- var bubbles = true;
- for (var name in params) {
- (name === 'bubbles') ? (bubbles = !!params[name]) : (evt[name] = params[name]);
- }
- evt.initEvent(event, bubbles, true);
- return evt;
- };
- CustomEvent.prototype = window.Event.prototype;
- window.CustomEvent = CustomEvent;
- }
- })();
- /*
- A shim for non ES5 supporting browsers.
- Adds function bind to Function prototype, so that you can do partial application.
- 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.
- */
- Function.prototype.bind = Function.prototype.bind || function(to) {
- // Make an array of our arguments, starting from second argument
- var partial = Array.prototype.splice.call(arguments, 1),
- // We'll need the original function.
- fn = this;
- var bound = function() {
- // Join the already applied arguments to the now called ones (after converting to an array again).
- var args = partial.concat(Array.prototype.splice.call(arguments, 0));
- // If not being called as a constructor
- if (!(this instanceof bound)) {
- // return the result of the function called bound to target and partially applied.
- return fn.apply(to, args);
- }
- // If being called as a constructor, apply the function bound to self.
- fn.apply(this, args);
- }
- // Attach the prototype of the function to our newly created function.
- bound.prototype = fn.prototype;
- return bound;
- };
- /**
- * mui fixed classList
- * @param {type} document
- * @returns {undefined}
- */
- (function(document) {
- if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {
- Object.defineProperty(HTMLElement.prototype, 'classList', {
- get: function() {
- var self = this;
- function update(fn) {
- return function(value) {
- var classes = self.className.split(/\s+/),
- index = classes.indexOf(value);
- fn(classes, index, value);
- self.className = classes.join(" ");
- };
- }
- var ret = {
- add: update(function(classes, index, value) {
- ~index || classes.push(value);
- }),
- remove: update(function(classes, index) {
- ~index && classes.splice(index, 1);
- }),
- toggle: update(function(classes, index, value) {
- ~index ? classes.splice(index, 1) : classes.push(value);
- }),
- contains: function(value) {
- return !!~self.className.split(/\s+/).indexOf(value);
- },
- item: function(i) {
- return self.className.split(/\s+/)[i] || null;
- }
- };
- Object.defineProperty(ret, 'length', {
- get: function() {
- return self.className.split(/\s+/).length;
- }
- });
- return ret;
- }
- });
- }
- })(document);
- /**
- * mui fixed requestAnimationFrame
- * @param {type} window
- * @returns {undefined}
- */
- (function(window) {
- if (!window.requestAnimationFrame) {
- var lastTime = 0;
- window.requestAnimationFrame = window.webkitRequestAnimationFrame || function(callback, element) {
- var currTime = new Date().getTime();
- var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
- var id = window.setTimeout(function() {
- callback(currTime + timeToCall);
- }, timeToCall);
- lastTime = currTime + timeToCall;
- return id;
- };
- window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || function(id) {
- clearTimeout(id);
- };
- };
- }(window));
- /**
- * fastclick(only for radio,checkbox)
- */
- (function($, window, name) {
- if (!$.os.android && !$.os.ios) { //目前仅识别android和ios
- return;
- }
- if (window.FastClick) {
- return;
- }
- var handle = function(event, target) {
- if (target.tagName === 'LABEL') {
- if (target.parentNode) {
- target = target.parentNode.querySelector('input');
- }
- }
- if (target && (target.type === 'radio' || target.type === 'checkbox')) {
- if (!target.disabled) { //disabled
- return target;
- }
- }
- return false;
- };
- $.registerTarget({
- name: name,
- index: 40,
- handle: handle,
- target: false
- });
- var dispatchEvent = function(event) {
- var targetElement = $.targets.click;
- if (targetElement) {
- var clickEvent, touch;
- // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect
- if (document.activeElement && document.activeElement !== targetElement) {
- document.activeElement.blur();
- }
- touch = event.detail.gesture.changedTouches[0];
- // Synthesise a click event, with an extra attribute so it can be tracked
- clickEvent = document.createEvent('MouseEvents');
- clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
- clickEvent.forwardedTouchEvent = true;
- targetElement.dispatchEvent(clickEvent);
- event.detail && event.detail.gesture.preventDefault();
- }
- };
- window.addEventListener('tap', dispatchEvent);
- window.addEventListener('doubletap', dispatchEvent);
- //捕获
- window.addEventListener('click', function(event) {
- if ($.targets.click) {
- if (!event.forwardedTouchEvent) { //stop click
- if (event.stopImmediatePropagation) {
- event.stopImmediatePropagation();
- } else {
- // Part of the hack for browsers that don't support Event#stopImmediatePropagation
- event.propagationStopped = true;
- }
- event.stopPropagation();
- event.preventDefault();
- return false;
- }
- }
- }, true);
- })(mui, window, 'click');
- (function($, document) {
- $(function() {
- if (!$.os.ios) {
- return;
- }
- var CLASS_FOCUSIN = 'mui-focusin';
- var CLASS_BAR_TAB = 'mui-bar-tab';
- var CLASS_BAR_FOOTER = 'mui-bar-footer';
- var CLASS_BAR_FOOTER_SECONDARY = 'mui-bar-footer-secondary';
- var CLASS_BAR_FOOTER_SECONDARY_TAB = 'mui-bar-footer-secondary-tab';
- // var content = document.querySelector('.' + CLASS_CONTENT);
- // if (content) {
- // document.body.insertBefore(content, document.body.firstElementChild);
- // }
- document.addEventListener('focusin', function(e) {
- if ($.os.plus) { //在父webview里边不fix
- if (window.plus) {
- if (plus.webview.currentWebview().children().length > 0) {
- return;
- }
- }
- }
- var target = e.target;
- //TODO 需考虑所有键盘弹起的情况
- if (target.tagName && (target.tagName === 'TEXTAREA' || (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'search' || target.type === 'number')))) {
- if (target.disabled || target.readOnly) {
- return;
- }
- document.body.classList.add(CLASS_FOCUSIN);
- var isFooter = false;
- for (; target && target !== document; target = target.parentNode) {
- var classList = target.classList;
- 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)) {
- isFooter = true;
- break;
- }
- }
- if (isFooter) {
- var scrollTop = document.body.scrollHeight;
- var scrollLeft = document.body.scrollLeft;
- setTimeout(function() {
- window.scrollTo(scrollLeft, scrollTop);
- }, 20);
- }
- }
- });
- document.addEventListener('focusout', function(e) {
- var classList = document.body.classList;
- if (classList.contains(CLASS_FOCUSIN)) {
- classList.remove(CLASS_FOCUSIN);
- setTimeout(function() {
- window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
- }, 20);
- }
- });
- });
- })(mui, document);
- /**
- * mui namespace(optimization)
- * @param {type} $
- * @returns {undefined}
- */
- (function($) {
- $.namespace = 'mui';
- $.classNamePrefix = $.namespace + '-';
- $.classSelectorPrefix = '.' + $.classNamePrefix;
- /**
- * 返回正确的className
- * @param {type} className
- * @returns {String}
- */
- $.className = function(className) {
- return $.classNamePrefix + className;
- };
- /**
- * 返回正确的classSelector
- * @param {type} classSelector
- * @returns {String}
- */
- $.classSelector = function(classSelector) {
- return classSelector.replace(/\./g, $.classSelectorPrefix);
- };
- /**
- * 返回正确的eventName
- * @param {type} event
- * @param {type} module
- * @returns {String}
- */
- $.eventName = function(event, module) {
- return event + ($.namespace ? ('.' + $.namespace) : '') + ( module ? ('.' + module) : '');
- };
- })(mui);
- /**
- * mui gestures
- * @param {type} $
- * @param {type} window
- * @returns {undefined}
- */
- (function($, window) {
- $.gestures = {
- session: {}
- };
- /**
- * Gesture preventDefault
- * @param {type} e
- * @returns {undefined}
- */
- $.preventDefault = function(e) {
- e.preventDefault();
- };
- /**
- * Gesture stopPropagation
- * @param {type} e
- * @returns {undefined}
- */
- $.stopPropagation = function(e) {
- e.stopPropagation();
- };
- /**
- * register gesture
- * @param {type} gesture
- * @returns {$.gestures}
- */
- $.addGesture = function(gesture) {
- return $.addAction('gestures', gesture);
- };
- var round = Math.round;
- var abs = Math.abs;
- var sqrt = Math.sqrt;
- var atan = Math.atan;
- var atan2 = Math.atan2;
- /**
- * distance
- * @param {type} p1
- * @param {type} p2
- * @returns {Number}
- */
- var getDistance = function(p1, p2, props) {
- if(!props) {
- props = ['x', 'y'];
- }
- var x = p2[props[0]] - p1[props[0]];
- var y = p2[props[1]] - p1[props[1]];
- return sqrt((x * x) + (y * y));
- };
- /**
- * scale
- * @param {Object} starts
- * @param {Object} moves
- */
- var getScale = function(starts, moves) {
- if(starts.length >= 2 && moves.length >= 2) {
- var props = ['pageX', 'pageY'];
- return getDistance(moves[1], moves[0], props) / getDistance(starts[1], starts[0], props);
- }
- return 1;
- };
- /**
- * angle
- * @param {type} p1
- * @param {type} p2
- * @returns {Number}
- */
- var getAngle = function(p1, p2, props) {
- if(!props) {
- props = ['x', 'y'];
- }
- var x = p2[props[0]] - p1[props[0]];
- var y = p2[props[1]] - p1[props[1]];
- return atan2(y, x) * 180 / Math.PI;
- };
- /**
- * direction
- * @param {Object} x
- * @param {Object} y
- */
- var getDirection = function(x, y) {
- if(x === y) {
- return '';
- }
- if(abs(x) >= abs(y)) {
- return x > 0 ? 'left' : 'right';
- }
- return y > 0 ? 'up' : 'down';
- };
- /**
- * rotation
- * @param {Object} start
- * @param {Object} end
- */
- var getRotation = function(start, end) {
- var props = ['pageX', 'pageY'];
- return getAngle(end[1], end[0], props) - getAngle(start[1], start[0], props);
- };
- /**
- * px per ms
- * @param {Object} deltaTime
- * @param {Object} x
- * @param {Object} y
- */
- var getVelocity = function(deltaTime, x, y) {
- return {
- x: x / deltaTime || 0,
- y: y / deltaTime || 0
- };
- };
- /**
- * detect gestures
- * @param {type} event
- * @param {type} touch
- * @returns {undefined}
- */
- var detect = function(event, touch) {
- if($.gestures.stoped) {
- return;
- }
- $.doAction('gestures', function(index, gesture) {
- if(!$.gestures.stoped) {
- if($.options.gestureConfig[gesture.name] !== false) {
- gesture.handle(event, touch);
- }
- }
- });
- };
- /**
- * 暂时无用
- * @param {Object} node
- * @param {Object} parent
- */
- var hasParent = function(node, parent) {
- while(node) {
- if(node == parent) {
- return true;
- }
- node = node.parentNode;
- }
- return false;
- };
- var uniqueArray = function(src, key, sort) {
- var results = [];
- var values = [];
- var i = 0;
- while(i < src.length) {
- var val = key ? src[i][key] : src[i];
- if(values.indexOf(val) < 0) {
- results.push(src[i]);
- }
- values[i] = val;
- i++;
- }
- if(sort) {
- if(!key) {
- results = results.sort();
- } else {
- results = results.sort(function sortUniqueArray(a, b) {
- return a[key] > b[key];
- });
- }
- }
- return results;
- };
- var getMultiCenter = function(touches) {
- var touchesLength = touches.length;
- if(touchesLength === 1) {
- return {
- x: round(touches[0].pageX),
- y: round(touches[0].pageY)
- };
- }
- var x = 0;
- var y = 0;
- var i = 0;
- while(i < touchesLength) {
- x += touches[i].pageX;
- y += touches[i].pageY;
- i++;
- }
- return {
- x: round(x / touchesLength),
- y: round(y / touchesLength)
- };
- };
- var multiTouch = function() {
- return $.options.gestureConfig.pinch;
- };
- var copySimpleTouchData = function(touch) {
- var touches = [];
- var i = 0;
- while(i < touch.touches.length) {
- touches[i] = {
- pageX: round(touch.touches[i].pageX),
- pageY: round(touch.touches[i].pageY)
- };
- i++;
- }
- return {
- timestamp: $.now(),
- gesture: touch.gesture,
- touches: touches,
- center: getMultiCenter(touch.touches),
- deltaX: touch.deltaX,
- deltaY: touch.deltaY
- };
- };
- var calDelta = function(touch) {
- var session = $.gestures.session;
- var center = touch.center;
- var offset = session.offsetDelta || {};
- var prevDelta = session.prevDelta || {};
- var prevTouch = session.prevTouch || {};
- if(touch.gesture.type === $.EVENT_START || touch.gesture.type === $.EVENT_END) {
- prevDelta = session.prevDelta = {
- x: prevTouch.deltaX || 0,
- y: prevTouch.deltaY || 0
- };
- offset = session.offsetDelta = {
- x: center.x,
- y: center.y
- };
- }
- touch.deltaX = prevDelta.x + (center.x - offset.x);
- touch.deltaY = prevDelta.y + (center.y - offset.y);
- };
- var calTouchData = function(touch) {
- var session = $.gestures.session;
- var touches = touch.touches;
- var touchesLength = touches.length;
- if(!session.firstTouch) {
- session.firstTouch = copySimpleTouchData(touch);
- }
- if(multiTouch() && touchesLength > 1 && !session.firstMultiTouch) {
- session.firstMultiTouch = copySimpleTouchData(touch);
- } else if(touchesLength === 1) {
- session.firstMultiTouch = false;
- }
- var firstTouch = session.firstTouch;
- var firstMultiTouch = session.firstMultiTouch;
- var offsetCenter = firstMultiTouch ? firstMultiTouch.center : firstTouch.center;
- var center = touch.center = getMultiCenter(touches);
- touch.timestamp = $.now();
- touch.deltaTime = touch.timestamp - firstTouch.timestamp;
- touch.angle = getAngle(offsetCenter, center);
- touch.distance = getDistance(offsetCenter, center);
- calDelta(touch);
- touch.offsetDirection = getDirection(touch.deltaX, touch.deltaY);
- touch.scale = firstMultiTouch ? getScale(firstMultiTouch.touches, touches) : 1;
- touch.rotation = firstMultiTouch ? getRotation(firstMultiTouch.touches, touches) : 0;
- calIntervalTouchData(touch);
- };
- var CAL_INTERVAL = 25;
- var calIntervalTouchData = function(touch) {
- var session = $.gestures.session;
- var last = session.lastInterval || touch;
- var deltaTime = touch.timestamp - last.timestamp;
- var velocity;
- var velocityX;
- var velocityY;
- var direction;
- if(touch.gesture.type != $.EVENT_CANCEL && (deltaTime > CAL_INTERVAL || last.velocity === undefined)) {
- var deltaX = last.deltaX - touch.deltaX;
- var deltaY = last.deltaY - touch.deltaY;
- var v = getVelocity(deltaTime, deltaX, deltaY);
- velocityX = v.x;
- velocityY = v.y;
- velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
- direction = getDirection(deltaX, deltaY) || last.direction;
- session.lastInterval = touch;
- } else {
- velocity = last.velocity;
- velocityX = last.velocityX;
- velocityY = last.velocityY;
- direction = last.direction;
- }
- touch.velocity = velocity;
- touch.velocityX = velocityX;
- touch.velocityY = velocityY;
- touch.direction = direction;
- };
- var targetIds = {};
- var convertTouches = function(touches) {
- for(var i = 0; i < touches.length; i++) {
- !touches['identifier'] && (touches['identifier'] = 0);
- }
- return touches;
- };
- var getTouches = function(event, touch) {
- var allTouches = convertTouches($.slice.call(event.touches || [event]));
- var type = event.type;
- var targetTouches = [];
- var changedTargetTouches = [];
- //当touchstart或touchmove且touches长度为1,直接获得all和changed
- if((type === $.EVENT_START || type === $.EVENT_MOVE) && allTouches.length === 1) {
- targetIds[allTouches[0].identifier] = true;
- targetTouches = allTouches;
- changedTargetTouches = allTouches;
- touch.target = event.target;
- } else {
- var i = 0;
- var targetTouches = [];
- var changedTargetTouches = [];
- var changedTouches = convertTouches($.slice.call(event.changedTouches || [event]));
- touch.target = event.target;
- var sessionTarget = $.gestures.session.target || event.target;
- targetTouches = allTouches.filter(function(touch) {
- return hasParent(touch.target, sessionTarget);
- });
- if(type === $.EVENT_START) {
- i = 0;
- while(i < targetTouches.length) {
- targetIds[targetTouches[i].identifier] = true;
- i++;
- }
- }
- i = 0;
- while(i < changedTouches.length) {
- if(targetIds[changedTouches[i].identifier]) {
- changedTargetTouches.push(changedTouches[i]);
- }
- if(type === $.EVENT_END || type === $.EVENT_CANCEL) {
- delete targetIds[changedTouches[i].identifier];
- }
- i++;
- }
- if(!changedTargetTouches.length) {
- return false;
- }
- }
- targetTouches = uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true);
- var touchesLength = targetTouches.length;
- var changedTouchesLength = changedTargetTouches.length;
- if(type === $.EVENT_START && touchesLength - changedTouchesLength === 0) { //first
- touch.isFirst = true;
- $.gestures.touch = $.gestures.session = {
- target: event.target
- };
- }
- touch.isFinal = ((type === $.EVENT_END || type === $.EVENT_CANCEL) && (touchesLength - changedTouchesLength === 0));
- touch.touches = targetTouches;
- touch.changedTouches = changedTargetTouches;
- return true;
- };
- var handleTouchEvent = function(event) {
- var touch = {
- gesture: event
- };
- var touches = getTouches(event, touch);
- if(!touches) {
- return;
- }
- calTouchData(touch);
- detect(event, touch);
- $.gestures.session.prevTouch = touch;
- if(event.type === $.EVENT_END && !$.isTouchable) {
- $.gestures.touch = $.gestures.session = {};
- }
- };
- var supportsPassive = (function checkPassiveListener() {
- var supportsPassive = false;
- try {
- var opts = Object.defineProperty({}, 'passive', {
- get: function get() {
- supportsPassive = true;
- },
- });
- window.addEventListener('testPassiveListener', null, opts);
- } catch(e) {
- // No support
- }
- return supportsPassive;
- }())
- window.addEventListener($.EVENT_START, handleTouchEvent);
- window.addEventListener($.EVENT_MOVE, handleTouchEvent, supportsPassive ? {
- passive: false,
- capture: false
- } : false);
- window.addEventListener($.EVENT_END, handleTouchEvent);
- window.addEventListener($.EVENT_CANCEL, handleTouchEvent);
- //fixed hashchange(android)
- window.addEventListener($.EVENT_CLICK, function(e) {
- //TODO 应该判断当前target是不是在targets.popover内部,而不是非要相等
- if(($.os.android || $.os.ios) && (($.targets.popover && e.target === $.targets.popover) || ($.targets.tab) || $.targets.offcanvas || $.targets.modal)) {
- e.preventDefault();
- }
- }, true);
- //增加原生滚动识别
- $.isScrolling = false;
- var scrollingTimeout = null;
- window.addEventListener('scroll', function() {
- $.isScrolling = true;
- scrollingTimeout && clearTimeout(scrollingTimeout);
- scrollingTimeout = setTimeout(function() {
- $.isScrolling = false;
- }, 250);
- });
- })(mui, window);
- /**
- * mui gesture flick[left|right|up|down]
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var flickStartTime = 0;
- var handle = function(event, touch) {
- var session = $.gestures.session;
- var options = this.options;
- var now = $.now();
- switch (event.type) {
- case $.EVENT_MOVE:
- if (now - flickStartTime > 300) {
- flickStartTime = now;
- session.flickStart = touch.center;
- }
- break;
- case $.EVENT_END:
- case $.EVENT_CANCEL:
- touch.flick = false;
- if (session.flickStart && options.flickMaxTime > (now - flickStartTime) && touch.distance > options.flickMinDistince) {
- touch.flick = true;
- touch.flickTime = now - flickStartTime;
- touch.flickDistanceX = touch.center.x - session.flickStart.x;
- touch.flickDistanceY = touch.center.y - session.flickStart.y;
- $.trigger(session.target, name, touch);
- $.trigger(session.target, name + touch.direction, touch);
- }
- break;
- }
- };
- /**
- * mui gesture flick
- */
- $.addGesture({
- name: name,
- index: 5,
- handle: handle,
- options: {
- flickMaxTime: 200,
- flickMinDistince: 10
- }
- });
- })(mui, 'flick');
- /**
- * mui gesture swipe[left|right|up|down]
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var handle = function(event, touch) {
- var session = $.gestures.session;
- if (event.type === $.EVENT_END || event.type === $.EVENT_CANCEL) {
- var options = this.options;
- touch.swipe = false;
- //TODO 后续根据velocity计算
- if (touch.direction && options.swipeMaxTime > touch.deltaTime && touch.distance > options.swipeMinDistince) {
- touch.swipe = true;
- $.trigger(session.target, name, touch);
- $.trigger(session.target, name + touch.direction, touch);
- }
- }
- };
- /**
- * mui gesture swipe
- */
- $.addGesture({
- name: name,
- index: 10,
- handle: handle,
- options: {
- swipeMaxTime: 300,
- swipeMinDistince: 18
- }
- });
- })(mui, 'swipe');
- /**
- * mui gesture drag[start|left|right|up|down|end]
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var handle = function(event, touch) {
- var session = $.gestures.session;
- switch (event.type) {
- case $.EVENT_START:
- break;
- case $.EVENT_MOVE:
- if (!touch.direction || !session.target) {
- return;
- }
- //修正direction,可在session期间自行锁定拖拽方向,方便开发scroll类不同方向拖拽插件嵌套
- if (session.lockDirection && session.startDirection) {
- if (session.startDirection && session.startDirection !== touch.direction) {
- if (session.startDirection === 'up' || session.startDirection === 'down') {
- touch.direction = touch.deltaY < 0 ? 'up' : 'down';
- } else {
- touch.direction = touch.deltaX < 0 ? 'left' : 'right';
- }
- }
- }
- if (!session.drag) {
- session.drag = true;
- $.trigger(session.target, name + 'start', touch);
- }
- $.trigger(session.target, name, touch);
- $.trigger(session.target, name + touch.direction, touch);
- break;
- case $.EVENT_END:
- case $.EVENT_CANCEL:
- if (session.drag && touch.isFinal) {
- $.trigger(session.target, name + 'end', touch);
- }
- break;
- }
- };
- /**
- * mui gesture drag
- */
- $.addGesture({
- name: name,
- index: 20,
- handle: handle,
- options: {
- fingers: 1
- }
- });
- })(mui, 'drag');
- /**
- * mui gesture tap and doubleTap
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var lastTarget;
- var lastTapTime;
- var handle = function(event, touch) {
- var session = $.gestures.session;
- var options = this.options;
- switch (event.type) {
- case $.EVENT_END:
- if (!touch.isFinal) {
- return;
- }
- var target = session.target;
- if (!target || (target.disabled || (target.classList && target.classList.contains('mui-disabled')))) {
- return;
- }
- if (touch.distance < options.tapMaxDistance && touch.deltaTime < options.tapMaxTime) {
- if ($.options.gestureConfig.doubletap && lastTarget && (lastTarget === target)) { //same target
- if (lastTapTime && (touch.timestamp - lastTapTime) < options.tapMaxInterval) {
- $.trigger(target, 'doubletap', touch);
- lastTapTime = $.now();
- lastTarget = target;
- return;
- }
- }
- $.trigger(target, name, touch);
- lastTapTime = $.now();
- lastTarget = target;
- }
- break;
- }
- };
- /**
- * mui gesture tap
- */
- $.addGesture({
- name: name,
- index: 30,
- handle: handle,
- options: {
- fingers: 1,
- tapMaxInterval: 300,
- tapMaxDistance: 5,
- tapMaxTime: 250
- }
- });
- })(mui, 'tap');
- /**
- * mui gesture longtap
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var timer;
- var handle = function(event, touch) {
- var session = $.gestures.session;
- var options = this.options;
- switch (event.type) {
- case $.EVENT_START:
- clearTimeout(timer);
- timer = setTimeout(function() {
- $.trigger(session.target, name, touch);
- }, options.holdTimeout);
- break;
- case $.EVENT_MOVE:
- if (touch.distance > options.holdThreshold) {
- clearTimeout(timer);
- }
- break;
- case $.EVENT_END:
- case $.EVENT_CANCEL:
- clearTimeout(timer);
- break;
- }
- };
- /**
- * mui gesture longtap
- */
- $.addGesture({
- name: name,
- index: 10,
- handle: handle,
- options: {
- fingers: 1,
- holdTimeout: 500,
- holdThreshold: 2
- }
- });
- })(mui, 'longtap');
- /**
- * mui gesture hold
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var timer;
- var handle = function(event, touch) {
- var session = $.gestures.session;
- var options = this.options;
- switch (event.type) {
- case $.EVENT_START:
- if ($.options.gestureConfig.hold) {
- timer && clearTimeout(timer);
- timer = setTimeout(function() {
- touch.hold = true;
- $.trigger(session.target, name, touch);
- }, options.holdTimeout);
- }
- break;
- case $.EVENT_MOVE:
- break;
- case $.EVENT_END:
- case $.EVENT_CANCEL:
- if (timer) {
- clearTimeout(timer) && (timer = null);
- $.trigger(session.target, 'release', touch);
- }
- break;
- }
- };
- /**
- * mui gesture hold
- */
- $.addGesture({
- name: name,
- index: 10,
- handle: handle,
- options: {
- fingers: 1,
- holdTimeout: 0
- }
- });
- })(mui, 'hold');
- /**
- * mui gesture pinch
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var handle = function(event, touch) {
- var options = this.options;
- var session = $.gestures.session;
- switch (event.type) {
- case $.EVENT_START:
- break;
- case $.EVENT_MOVE:
- if ($.options.gestureConfig.pinch) {
- if (touch.touches.length < 2) {
- return;
- }
- if (!session.pinch) { //start
- session.pinch = true;
- $.trigger(session.target, name + 'start', touch);
- }
- $.trigger(session.target, name, touch);
- var scale = touch.scale;
- var rotation = touch.rotation;
- var lastScale = typeof touch.lastScale === 'undefined' ? 1 : touch.lastScale;
- var scaleDiff = 0.000000000001; //防止scale与lastScale相等,不触发事件的情况。
- if (scale > lastScale) { //out
- lastScale = scale - scaleDiff;
- $.trigger(session.target, name + 'out', touch);
- } //in
- else if (scale < lastScale) {
- lastScale = scale + scaleDiff;
- $.trigger(session.target, name + 'in', touch);
- }
- if (Math.abs(rotation) > options.minRotationAngle) {
- $.trigger(session.target, 'rotate', touch);
- }
- }
- break;
- case $.EVENT_END:
- case $.EVENT_CANCEL:
- if ($.options.gestureConfig.pinch && session.pinch && touch.touches.length === 2) {
- session.pinch = false;
- $.trigger(session.target, name + 'end', touch);
- }
- break;
- }
- };
- /**
- * mui gesture pinch
- */
- $.addGesture({
- name: name,
- index: 10,
- handle: handle,
- options: {
- minRotationAngle: 0
- }
- });
- })(mui, 'pinch');
- /**
- * mui.init
- * @param {type} $
- * @returns {undefined}
- */
- (function($) {
- $.global = $.options = {
- gestureConfig: {
- tap: true,
- doubletap: false,
- longtap: false,
- hold: false,
- flick: true,
- swipe: true,
- drag: true,
- pinch: false
- }
- };
- /**
- *
- * @param {type} options
- * @returns {undefined}
- */
- $.initGlobal = function(options) {
- $.options = $.extend(true, $.global, options);
- return this;
- };
- var inits = {};
- /**
- * 单页配置 初始化
- * @param {object} options
- */
- $.init = function(options) {
- $.options = $.extend(true, $.global, options || {});
- $.ready(function() {
- $.doAction('inits', function(index, init) {
- var isInit = !!(!inits[init.name] || init.repeat);
- if (isInit) {
- init.handle.call($);
- inits[init.name] = true;
- }
- });
- });
- return this;
- };
- /**
- * 增加初始化执行流程
- * @param {function} init
- */
- $.addInit = function(init) {
- return $.addAction('inits', init);
- };
- /**
- * 处理html5版本subpages
- */
- $.addInit({
- name: 'iframe',
- index: 100,
- handle: function() {
- var options = $.options;
- var subpages = options.subpages || [];
- if (!$.os.plus && subpages.length) {
- //暂时只处理单个subpage。后续可以考虑支持多个subpage
- createIframe(subpages[0]);
- }
- }
- });
- var createIframe = function(options) {
- var wrapper = document.createElement('div');
- wrapper.className = 'mui-iframe-wrapper';
- var styles = options.styles || {};
- if (typeof styles.top !== 'string') {
- styles.top = '0px';
- }
- if (typeof styles.bottom !== 'string') {
- styles.bottom = '0px';
- }
- wrapper.style.top = styles.top;
- wrapper.style.bottom = styles.bottom;
- var iframe = document.createElement('iframe');
- iframe.src = options.url;
- iframe.id = options.id || options.url;
- iframe.name = iframe.id;
- wrapper.appendChild(iframe);
- document.body.appendChild(wrapper);
- //目前仅处理微信
- $.os.wechat && handleScroll(wrapper, iframe);
- };
- function handleScroll(wrapper, iframe) {
- var key = 'MUI_SCROLL_POSITION_' + document.location.href + '_' + iframe.src;
- var scrollTop = (parseFloat(localStorage.getItem(key)) || 0);
- if (scrollTop) {
- (function(y) {
- iframe.onload = function() {
- window.scrollTo(0, y);
- };
- })(scrollTop);
- }
- setInterval(function() {
- var _scrollTop = window.scrollY;
- if (scrollTop !== _scrollTop) {
- localStorage.setItem(key, _scrollTop + '');
- scrollTop = _scrollTop;
- }
- }, 100);
- };
- $(function() {
- var classList = document.body.classList;
- var os = [];
- if ($.os.ios) {
- os.push({
- os: 'ios',
- version: $.os.version
- });
- classList.add('mui-ios');
- } else if ($.os.android) {
- os.push({
- os: 'android',
- version: $.os.version
- });
- classList.add('mui-android');
- }
- if ($.os.wechat) {
- os.push({
- os: 'wechat',
- version: $.os.wechat.version
- });
- classList.add('mui-wechat');
- }
- if (os.length) {
- $.each(os, function(index, osObj) {
- var version = '';
- var classArray = [];
- if (osObj.version) {
- $.each(osObj.version.split('.'), function(i, v) {
- version = version + (version ? '-' : '') + v;
- classList.add($.className(osObj.os + '-' + version));
- });
- }
- });
- }
- });
- })(mui);
- /**
- * mui.init 5+
- * @param {type} $
- * @returns {undefined}
- */
- (function($) {
- var defaultOptions = {
- swipeBack: false,
- preloadPages: [], //5+ lazyLoad webview
- preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出)
- keyEventBind: {
- backbutton: true,
- menubutton: true
- },
- titleConfig: {
- height: "44px",
- backgroundColor: "#f7f7f7", //导航栏背景色
- bottomBorderColor: "#cccccc", //底部边线颜色
- title: { //标题配置
- text: "", //标题文字
- position: {
- top: 0,
- left: 0,
- width: "100%",
- height: "100%"
- },
- styles: {
- color: "#000000",
- align: "center",
- family: "'Helvetica Neue',Helvetica,sans-serif",
- size: "17px",
- style: "normal",
- weight: "normal",
- fontSrc: ""
- }
- },
- back: {
- image: {
- base64Data: '',
- imgSrc: '',
- sprite: {
- top: '0px',
- left: '0px',
- width: '100%',
- height: '100%'
- },
- position: {
- top: "10px",
- left: "10px",
- width: "24px",
- height: "24px"
- }
- }
- }
- }
- };
- //默认页面动画
- var defaultShow = {
- event:"titleUpdate",
- autoShow: true,
- duration: 300,
- aniShow: 'slide-in-right',
- extras:{}
- };
- //若执行了显示动画初始化操作,则要覆盖默认配置
- if($.options.show) {
- defaultShow = $.extend(true, defaultShow, $.options.show);
- }
- $.currentWebview = null;
- $.extend(true, $.global, defaultOptions);
- $.extend(true, $.options, defaultOptions);
- /**
- * 等待动画配置
- * @param {type} options
- * @returns {Object}
- */
- $.waitingOptions = function(options) {
- return $.extend(true, {}, {
- autoShow: true,
- title: '',
- modal: false
- }, options);
- };
- /**
- * 窗口显示配置
- * @param {type} options
- * @returns {Object}
- */
- $.showOptions = function(options) {
- return $.extend(true, {}, defaultShow, options);
- };
- /**
- * 窗口默认配置
- * @param {type} options
- * @returns {Object}
- */
- $.windowOptions = function(options) {
- return $.extend({
- scalable: false,
- bounce: "" //vertical
- }, options);
- };
- /**
- * plusReady
- * @param {type} callback
- * @returns {_L6.$}
- */
- $.plusReady = function(callback) {
- if(window.plus) {
- setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)
- callback();
- }, 0);
- } else {
- document.addEventListener("plusready", function() {
- callback();
- }, false);
- }
- return this;
- };
- /**
- * 5+ event(5+没提供之前我自己实现)
- * @param {type} webview
- * @param {type} eventType
- * @param {type} data
- * @returns {undefined}
- */
- $.fire = function(webview, eventType, data) {
- if(webview) {
- if(typeof data === 'undefined') {
- data = '';
- } else if(typeof data === 'boolean' || typeof data === 'number') {
- webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")");
- return;
- } else if($.isPlainObject(data) || $.isArray(data)) {
- data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c");
- }
- webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')");
- }
- };
- /**
- * 5+ event(5+没提供之前我自己实现)
- * @param {type} eventType
- * @param {type} data
- * @returns {undefined}
- */
- $.receive = function(eventType, data) {
- if(eventType) {
- try {
- if(data && typeof data === 'string') {
- data = JSON.parse(data);
- }
- } catch(e) {}
- $.trigger(document, eventType, data);
- }
- };
- var triggerPreload = function(webview) {
- if(!webview.preloaded) { //保证仅触发一次
- $.fire(webview, 'preload');
- var list = webview.children();
- for(var i = 0; i < list.length; i++) {
- $.fire(list[i], 'preload');
- }
- webview.preloaded = true;
- }
- };
- var trigger = function(webview, eventType, timeChecked) {
- if(timeChecked) {
- if(!webview[eventType + 'ed']) {
- $.fire(webview, eventType);
- var list = webview.children();
- for(var i = 0; i < list.length; i++) {
- $.fire(list[i], eventType);
- }
- webview[eventType + 'ed'] = true;
- }
- } else {
- $.fire(webview, eventType);
- var list = webview.children();
- for(var i = 0; i < list.length; i++) {
- $.fire(list[i], eventType);
- }
- }
- };
- /**
- * 打开新窗口
- * @param {string} url 要打开的页面地址
- * @param {string} id 指定页面ID
- * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}}
- */
- $.openWindow = function(url, id, options) {
- if(typeof url === 'object') {
- options = url;
- url = options.url;
- id = options.id || url;
- } else {
- if(typeof id === 'object') {
- options = id;
- id = options.id || url;
- } else {
- id = id || url;
- }
- }
- if(!$.os.plus) {
- //TODO 先临时这么处理:手机上顶层跳,PC上parent跳
- if($.os.ios || $.os.android) {
- window.top.location.href = url;
- } else {
- window.parent.location.href = url;
- }
- return;
- }
- if(!window.plus) {
- return;
- }
- options = options || {};
- var params = options.params || {};
- var webview = null,
- webviewCache = null,
- nShow, nWaiting;
- if($.webviews[id]) {
- webviewCache = $.webviews[id];
- //webview真实存在,才能获取
- if(plus.webview.getWebviewById(id)) {
- webview = webviewCache.webview;
- }
- } else if(options.createNew !== true) {
- webview = plus.webview.getWebviewById(id);
- }
- if(webview) { //已缓存
- //每次show都需要传递动画参数;
- //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
- nShow = webviewCache ? webviewCache.show : defaultShow;
- nShow = options.show ? $.extend(nShow, options.show) : nShow;
- nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
- triggerPreload(webview);
- trigger(webview, 'pagebeforeshow', false);
- });
- if(webviewCache) {
- webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
- }
- return webview;
- } else { //新窗口
- if(!url) {
- throw new Error('webview[' + id + '] does not exist');
- }
- //显示waiting
- var waitingConfig = $.waitingOptions(options.waiting);
- if(waitingConfig.autoShow) {
- nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
- }
- //创建页面
- options = $.extend(options, {
- id: id,
- url: url
- });
- webview = $.createWindow(options);
- //显示
- nShow = $.showOptions(options.show);
- if(nShow.autoShow) {
- var showWebview = function() {
- //关闭等待框
- if(nWaiting) {
- nWaiting.close();
- }
- //显示页面
- webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
- options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
- };
- //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
- webview.addEventListener(nShow.event, showWebview, false);
- //loaded事件发生后,触发预加载和pagebeforeshow事件
- webview.addEventListener("loaded", function() {
- triggerPreload(webview);
- trigger(webview, 'pagebeforeshow', false);
- }, false);
- }
- }
- return webview;
- };
- $.openWindowWithTitle = function(options, titleConfig) {
- options = options || {};
- var url = options.url;
- var id = options.id || url;
- if(!$.os.plus) {
- //TODO 先临时这么处理:手机上顶层跳,PC上parent跳
- if($.os.ios || $.os.android) {
- window.top.location.href = url;
- } else {
- window.parent.location.href = url;
- }
- return;
- }
- if(!window.plus) {
- return;
- }
- var params = options.params || {};
- var webview = null,
- webviewCache = null,
- nShow, nWaiting;
- if($.webviews[id]) {
- webviewCache = $.webviews[id];
- //webview真实存在,才能获取
- if(plus.webview.getWebviewById(id)) {
- webview = webviewCache.webview;
- }
- } else if(options.createNew !== true) {
- webview = plus.webview.getWebviewById(id);
- }
- if(webview) { //已缓存
- //每次show都需要传递动画参数;
- //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
- nShow = webviewCache ? webviewCache.show : defaultShow;
- nShow = options.show ? $.extend(nShow, options.show) : nShow;
- nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
- triggerPreload(webview);
- trigger(webview, 'pagebeforeshow', false);
- });
- if(webviewCache) {
- webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
- }
- return webview;
- } else { //新窗口
- if(!url) {
- throw new Error('webview[' + id + '] does not exist');
- }
- //显示waiting
- var waitingConfig = $.waitingOptions(options.waiting);
- if(waitingConfig.autoShow) {
- nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
- }
- //创建页面
- options = $.extend(options, {
- id: id,
- url: url
- });
- webview = $.createWindow(options);
- if(titleConfig) { //处理原生头
- $.extend(true, $.options.titleConfig, titleConfig);
- var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title";
- var view = new plus.nativeObj.View(tid, {
- top: 0,
- height: $.options.titleConfig.height,
- width: "100%",
- dock: "top",
- position: "dock"
- });
- view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色
- var _b = parseInt($.options.titleConfig.height) - 1;
- view.drawRect($.options.titleConfig.bottomBorderColor, {
- top: _b + "px",
- left: "0px"
- }); //绘制底部边线
- //绘制文字
- if($.options.titleConfig.title.text){
- var _title = $.options.titleConfig.title;
- view.drawText(_title.text,_title.position , _title.styles);
- }
-
- //返回图标绘制
- var _back = $.options.titleConfig.back;
- var backClick = null;
- //优先字体
- //其次是图片
- var _backImage = _back.image;
- if(_backImage.base64Data || _backImage.imgSrc) {
- //TODO 此处需要处理百分比的情况
- backClick = {
- left:parseInt(_backImage.position.left),
- right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width)
- };
- var bitmap = new plus.nativeObj.Bitmap(id + "_back");
- if(_backImage.base64Data) { //优先base64编码字符串
- bitmap.loadBase64Data(_backImage.base64Data);
- } else { //其次加载图片文件
- bitmap.load(_backImage.imgSrc);
- }
- view.drawBitmap(bitmap,_backImage.sprite , _backImage.position);
- }
- //处理点击事件
- view.setTouchEventRect({
- top: "0px",
- left: "0px",
- width: "100%",
- height: "100%"
- });
- view.interceptTouchEvent(true);
- view.addEventListener("click", function(e) {
- var x = e.clientX;
-
- //返回按钮点击
- if(backClick&& x > backClick.left && x < backClick.right){
- if( _back.click && $.isFunction(_back.click)){
- _back.click();
- }else{
- webview.evalJS("window.mui&&mui.back();");
- }
- }
- }, false);
- webview.append(view);
- }
- //显示
- nShow = $.showOptions(options.show);
- if(nShow.autoShow) {
- //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
- webview.addEventListener(nShow.event, function () {
- //关闭等待框
- if(nWaiting) {
- nWaiting.close();
- }
- //显示页面
- webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
- }, false);
- }
- }
- return webview;
- };
- /**
- * 根据配置信息创建一个webview
- * @param {type} options
- * @param {type} isCreate
- * @returns {webview}
- */
- $.createWindow = function(options, isCreate) {
- if(!window.plus) {
- return;
- }
- var id = options.id || options.url;
- var webview;
- if(options.preload) {
- if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache
- webview = $.webviews[id].webview;
- } else { //新增预加载窗口
- //判断是否携带createNew参数,默认为false
- if(options.createNew !== true) {
- webview = plus.webview.getWebviewById(id);
- }
- //之前没有,那就新创建
- if(!webview) {
- webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({
- preload: true
- }, options.extras));
- if(options.subpages) {
- $.each(options.subpages, function(index, subpage) {
- var subpageId = subpage.id || subpage.url;
- if(subpageId) { //过滤空对象
- var subWebview = plus.webview.getWebviewById(subpageId);
- if(!subWebview) { //如果该webview不存在,则创建
- subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({
- preload: true
- }, subpage.extras));
- }
- webview.append(subWebview);
- }
- });
- }
- }
- }
- //TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题;
- $.webviews[id] = {
- webview: webview, //目前仅preload的缓存webview
- preload: true,
- show: $.showOptions(options.show),
- afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯
- };
- //索引该预加载窗口
- var preloads = $.data.preloads;
- var index = preloads.indexOf(id);
- if(~index) { //删除已存在的(变相调整插入位置)
- preloads.splice(index, 1);
- }
- preloads.push(id);
- if(preloads.length > $.options.preloadLimit) {
- //先进先出
- var first = $.data.preloads.shift();
- var webviewCache = $.webviews[first];
- if(webviewCache && webviewCache.webview) {
- //需要将自己打开的所有页面,全部close;
- //关闭该预加载webview
- $.closeAll(webviewCache.webview);
- }
- //删除缓存
- delete $.webviews[first];
- }
- } else {
- if(isCreate !== false) { //直接创建非预加载窗口
- webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras);
- if(options.subpages) {
- $.each(options.subpages, function(index, subpage) {
- var subpageId = subpage.id || subpage.url;
- var subWebview = plus.webview.getWebviewById(subpageId);
- if(!subWebview) {
- subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras);
- }
- webview.append(subWebview);
- });
- }
- }
- }
- return webview;
- };
- /**
- * 预加载
- */
- $.preload = function(options) {
- //调用预加载函数,不管是否传递preload参数,强制变为true
- if(!options.preload) {
- options.preload = true;
- }
- return $.createWindow(options);
- };
- /**
- *关闭当前webview打开的所有webview;
- */
- $.closeOpened = function(webview) {
- var opened = webview.opened();
- if(opened) {
- for(var i = 0, len = opened.length; i < len; i++) {
- var openedWebview = opened[i];
- var open_open = openedWebview.opened();
- if(open_open && open_open.length > 0) {
- //关闭打开的webview
- $.closeOpened(openedWebview);
- //关闭自己
- openedWebview.close("none");
- } else {
- //如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子;
- if(openedWebview.parent() !== webview) {
- openedWebview.close('none');
- }
- }
- }
- }
- };
- $.closeAll = function(webview, aniShow) {
- $.closeOpened(webview);
- if(aniShow) {
- webview.close(aniShow);
- } else {
- webview.close();
- }
- };
- /**
- * 批量创建webview
- * @param {type} options
- * @returns {undefined}
- */
- $.createWindows = function(options) {
- $.each(options, function(index, option) {
- //初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建)
- $.createWindow(option, false);
- });
- };
- /**
- * 创建当前页面的子webview
- * @param {type} options
- * @returns {webview}
- */
- $.appendWebview = function(options) {
- if(!window.plus) {
- return;
- }
- var id = options.id || options.url;
- var webview;
- if(!$.webviews[id]) { //保证执行一遍
- //TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话;
- if(!plus.webview.getWebviewById(id)) {
- webview = plus.webview.create(options.url, id, options.styles, options.extras);
- }
- //之前的实现方案:子窗口loaded之后再append到父窗口中;
- //问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败;
- // 比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发;
- //修改方式:不再监控loaded事件,直接append
- //by chb@20150521
- // webview.addEventListener('loaded', function() {
- plus.webview.currentWebview().append(webview);
- // });
- $.webviews[id] = options;
- }
- return webview;
- };
- //全局webviews
- $.webviews = {};
- //预加载窗口索引
- $.data.preloads = [];
- //$.currentWebview
- $.plusReady(function() {
- $.currentWebview = plus.webview.currentWebview();
- });
- $.addInit({
- name: '5+',
- index: 100,
- handle: function() {
- var options = $.options;
- var subpages = options.subpages || [];
- if($.os.plus) {
- $.plusReady(function() {
- //TODO 这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法;
- //或者:在openwindow方法中,监听实现;
- $.each(subpages, function(index, subpage) {
- $.appendWebview(subpage);
- });
- //判断是否首页
- if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) {
- //首页需要自己激活预加载;
- //timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题;
- setTimeout(function() {
- triggerPreload(plus.webview.currentWebview());
- }, 300);
- }
- //设置ios顶部状态栏颜色;
- if($.os.ios && $.options.statusBarBackground) {
- plus.navigator.setStatusBarBackground($.options.statusBarBackground);
- }
- if($.os.android && parseFloat($.os.version) < 4.4) {
- //解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题;
- if(plus.webview.currentWebview().parent() == null) {
- document.addEventListener("resume", function() {
- var body = document.body;
- body.style.display = 'none';
- setTimeout(function() {
- body.style.display = '';
- }, 10);
- });
- }
- }
- });
- } else {
- //已支持iframe嵌入
- // if (subpages.length > 0) {
- // var err = document.createElement('div');
- // err.className = 'mui-error';
- // //文字描述
- // var span = document.createElement('span');
- // span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考';
- // err.appendChild(span);
- // var a = document.createElement('a');
- // a.innerHTML = '"mui框架适用场景"';
- // a.href = 'http://ask.dcloud.net.cn/article/113';
- // err.appendChild(a);
- // document.body.appendChild(err);
- // console.log('在该浏览器下,不支持创建子页面');
- // }
- }
- }
- });
- window.addEventListener('preload', function() {
- //处理预加载部分
- var webviews = $.options.preloadPages || [];
- $.plusReady(function() {
- $.each(webviews, function(index, webview) {
- $.createWindow($.extend(webview, {
- preload: true
- }));
- });
- });
- });
- $.supportStatusbarOffset = function() {
- return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7;
- };
- $.ready(function() {
- //标识当前环境支持statusbar
- if($.supportStatusbarOffset()) {
- document.body.classList.add('mui-statusbar');
- }
- });
- })(mui);
- /**
- * mui back
- * @param {type} $
- * @param {type} window
- * @returns {undefined}
- */
- (function($, window) {
- /**
- * register back
- * @param {type} back
- * @returns {$.gestures}
- */
- $.addBack = function(back) {
- return $.addAction('backs', back);
- };
- /**
- * default
- */
- $.addBack({
- name: 'browser',
- index: 100,
- handle: function() {
- if (window.history.length > 1) {
- window.history.back();
- return true;
- }
- return false;
- }
- });
- /**
- * 后退
- */
- $.back = function() {
- if (typeof $.options.beforeback === 'function') {
- if ($.options.beforeback() === false) {
- return;
- }
- }
- $.doAction('backs');
- };
- window.addEventListener('tap', function(e) {
- var action = $.targets.action;
- if (action && action.classList.contains('mui-action-back')) {
- $.back();
- $.targets.action = false;
- }
- });
- window.addEventListener('swiperight', function(e) {
- var detail = e.detail;
- if ($.options.swipeBack === true && Math.abs(detail.angle) < 3) {
- $.back();
- }
- });
- })(mui, window);
- /**
- * mui back 5+
- * @param {type} $
- * @param {type} window
- * @returns {undefined}
- */
- (function($, window) {
- if ($.os.plus && $.os.android) {
- $.addBack({
- name: 'mui',
- index: 5,
- handle: function() {
- //后续重新设计此处,将back放到各个空间内部实现
- //popover
- if ($.targets._popover && $.targets._popover.classList.contains('mui-active')) {
- $($.targets._popover).popover('hide');
- return true;
- }
- //offcanvas
- var offCanvas = document.querySelector('.mui-off-canvas-wrap.mui-active');
- if (offCanvas) {
- $(offCanvas).offCanvas('close');
- return true;
- }
- var previewImage = $.isFunction($.getPreviewImage) && $.getPreviewImage();
- if (previewImage && previewImage.isShown()) {
- previewImage.close();
- return true;
- }
- //popup
- return $.closePopup();
- }
- });
- }
- //首次按下back按键的时间
- $.__back__first = null;
- /**
- * 5+ back
- */
- $.addBack({
- name: '5+',
- index: 10,
- handle: function() {
- if (!window.plus) {
- return false;
- }
- var wobj = plus.webview.currentWebview();
- var parent = wobj.parent();
- if (parent) {
- parent.evalJS('mui&&mui.back();');
- } else {
- wobj.canBack(function(e) {
- //by chb 暂时注释,在碰到类似popover之类的锚点的时候,需多次点击才能返回;
- if (e.canBack) { //webview history back
- window.history.back();
- } else { //webview close or hide
- //fixed by fxy 此处不应该用opener判断,因为用户有可能自己close掉当前窗口的opener。这样的话。opener就为空了,导致不能执行close
- if (wobj.id === plus.runtime.appid) { //首页
- //首页不存在opener的情况下,后退实际上应该是退出应用;
- //首次按键,提示‘再按一次退出应用’
- if (!$.__back__first) {
- $.__back__first = new Date().getTime();
- mui.toast('再按一次退出应用');
- setTimeout(function() {
- $.__back__first = null;
- }, 2000);
- } else {
- if (new Date().getTime() - $.__back__first < 2000) {
- plus.runtime.quit();
- }
- }
- } else { //其他页面,
- if (wobj.preload) {
- wobj.hide("auto");
- } else {
- //关闭页面时,需要将其打开的所有子页面全部关闭;
- $.closeAll(wobj);
- }
- }
- }
- });
- }
- return true;
- }
- });
- $.menu = function() {
- var menu = document.querySelector('.mui-action-menu');
- if (menu) {
- $.trigger(menu, $.EVENT_START); //临时处理menu无touchstart的话,找不到当前targets的问题
- $.trigger(menu, 'tap');
- } else { //执行父窗口的menu
- if (window.plus) {
- var wobj = $.currentWebview;
- var parent = wobj.parent();
- if (parent) { //又得evalJS
- parent.evalJS('mui&&mui.menu();');
- }
- }
- }
- };
- var __back = function() {
- $.back();
- };
- var __menu = function() {
- $.menu();
- };
- //默认监听
- $.plusReady(function() {
- if ($.options.keyEventBind.backbutton) {
- plus.key.addEventListener('backbutton', __back, false);
- }
- if ($.options.keyEventBind.menubutton) {
- plus.key.addEventListener('menubutton', __menu, false);
- }
- });
- //处理按键监听事件
- $.addInit({
- name: 'keyEventBind',
- index: 1000,
- handle: function() {
- $.plusReady(function() {
- //如果不为true,则移除默认监听
- if (!$.options.keyEventBind.backbutton) {
- plus.key.removeEventListener('backbutton', __back);
- }
- if (!$.options.keyEventBind.menubutton) {
- plus.key.removeEventListener('menubutton', __menu);
- }
- });
- }
- });
- })(mui, window);
- /**
- * mui.init pulldownRefresh
- * @param {type} $
- * @returns {undefined}
- */
- (function($) {
- $.addInit({
- name: 'pullrefresh',
- index: 1000,
- handle: function() {
- var options = $.options;
- var pullRefreshOptions = options.pullRefresh || {};
- var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback');
- var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback');
- if(hasPulldown || hasPullup) {
- var container = pullRefreshOptions.container;
- if(container) {
- var $container = $(container);
- if($container.length === 1) {
- if($.os.plus) { //5+环境
- if(hasPulldown && pullRefreshOptions.down.style == "circle") { //原生转圈
- $.plusReady(function() {
- //这里改写$.fn.pullRefresh
- $.fn.pullRefresh = $.fn.pullRefresh_native;
- $container.pullRefresh(pullRefreshOptions);
- });
- } else if($.os.android) { //非原生转圈,但是Android环境
- $.plusReady(function() {
- //这里改写$.fn.pullRefresh
- $.fn.pullRefresh = $.fn.pullRefresh_native
- var webview = plus.webview.currentWebview();
- if(window.__NWin_Enable__ === false) { //不支持多webview
- $container.pullRefresh(pullRefreshOptions);
- } else {
- if(hasPullup) {
- //当前页面初始化pullup
- var upOptions = {};
- upOptions.up = pullRefreshOptions.up;
- upOptions.webviewId = webview.id || webview.getURL();
- $container.pullRefresh(upOptions);
- }
- if(hasPulldown) {
- var parent = webview.parent();
- var id = webview.id || webview.getURL();
- if(parent) {
- if(!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法
- $container.pullRefresh({
- webviewId: id
- });
- }
- var downOptions = {
- webviewId: id//子页面id
- };
- downOptions.down = $.extend({}, pullRefreshOptions.down);
- downOptions.down.callback = '_CALLBACK';
- //改写父页面的$.fn.pullRefresh
- parent.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native");
- //父页面初始化pulldown
- parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')");
- }
- }
- }
- });
- } else { //非原生转圈,iOS环境
- $container.pullRefresh(pullRefreshOptions);
- }
- } else {
- $container.pullRefresh(pullRefreshOptions);
- }
- }
- }
- }
- }
- });
- })(mui);
- /**
- * mui ajax
- * @param {type} $
- * @returns {undefined}
- */
- (function($, window, undefined) {
- var jsonType = 'application/json';
- var htmlType = 'text/html';
- var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
- var scriptTypeRE = /^(?:text|application)\/javascript/i;
- var xmlTypeRE = /^(?:text|application)\/xml/i;
- var blankRE = /^\s*$/;
- $.ajaxSettings = {
- type: 'GET',
- beforeSend: $.noop,
- success: $.noop,
- error: $.noop,
- complete: $.noop,
- context: null,
- xhr: function(protocol) {
- return new window.XMLHttpRequest();
- },
- accepts: {
- script: 'text/javascript, application/javascript, application/x-javascript',
- json: jsonType,
- xml: 'application/xml, text/xml',
- html: htmlType,
- text: 'text/plain'
- },
- timeout: 0,
- processData: true,
- cache: true
- };
- var ajaxBeforeSend = function(xhr, settings) {
- var context = settings.context
- if(settings.beforeSend.call(context, xhr, settings) === false) {
- return false;
- }
- };
- var ajaxSuccess = function(data, xhr, settings) {
- settings.success.call(settings.context, data, 'success', xhr);
- ajaxComplete('success', xhr, settings);
- };
- // type: "timeout", "error", "abort", "parsererror"
- var ajaxError = function(error, type, xhr, settings) {
- settings.error.call(settings.context, xhr, type, error);
- ajaxComplete(type, xhr, settings);
- };
- // status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
- var ajaxComplete = function(status, xhr, settings) {
- settings.complete.call(settings.context, xhr, status);
- };
- var serialize = function(params, obj, traditional, scope) {
- var type, array = $.isArray(obj),
- hash = $.isPlainObject(obj);
- $.each(obj, function(key, value) {
- type = $.type(value);
- if(scope) {
- key = traditional ? scope :
- scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']';
- }
- // handle data in serializeArray() format
- if(!scope && array) {
- params.add(value.name, value.value);
- }
- // recurse into nested objects
- else if(type === "array" || (!traditional && type === "object")) {
- serialize(params, value, traditional, key);
- } else {
- params.add(key, value);
- }
- });
- };
- var serializeData = function(options) {
- if(options.processData && options.data && typeof options.data !== "string") {
- var contentType = options.contentType;
- if(!contentType && options.headers) {
- contentType = options.headers['Content-Type'];
- }
- if(contentType && ~contentType.indexOf(jsonType)) { //application/json
- options.data = JSON.stringify(options.data);
- } else {
- options.data = $.param(options.data, options.traditional);
- }
- }
- if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
- options.url = appendQuery(options.url, options.data);
- options.data = undefined;
- }
- };
- var appendQuery = function(url, query) {
- if(query === '') {
- return url;
- }
- return(url + '&' + query).replace(/[&?]{1,2}/, '?');
- };
- var mimeToDataType = function(mime) {
- if(mime) {
- mime = mime.split(';', 2)[0];
- }
- return mime && (mime === htmlType ? 'html' :
- mime === jsonType ? 'json' :
- scriptTypeRE.test(mime) ? 'script' :
- xmlTypeRE.test(mime) && 'xml') || 'text';
- };
- var parseArguments = function(url, data, success, dataType) {
- if($.isFunction(data)) {
- dataType = success, success = data, data = undefined;
- }
- if(!$.isFunction(success)) {
- dataType = success, success = undefined;
- }
- return {
- url: url,
- data: data,
- success: success,
- dataType: dataType
- };
- };
- $.ajax = function(url, options) {
- if(typeof url === "object") {
- options = url;
- url = undefined;
- }
- var settings = options || {};
- settings.url = url || settings.url;
- for(var key in $.ajaxSettings) {
- if(settings[key] === undefined) {
- settings[key] = $.ajaxSettings[key];
- }
- }
- serializeData(settings);
- var dataType = settings.dataType;
- if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) {
- settings.url = appendQuery(settings.url, '_=' + $.now());
- }
- var mime = settings.accepts[dataType && dataType.toLowerCase()];
- var headers = {};
- var setHeader = function(name, value) {
- headers[name.toLowerCase()] = [name, value];
- };
- var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;
- var xhr = settings.xhr(settings);
- var nativeSetHeader = xhr.setRequestHeader;
- var abortTimeout;
- setHeader('X-Requested-With', 'XMLHttpRequest');
- setHeader('Accept', mime || '*/*');
- if(!!(mime = settings.mimeType || mime)) {
- if(mime.indexOf(',') > -1) {
- mime = mime.split(',', 2)[0];
- }
- xhr.overrideMimeType && xhr.overrideMimeType(mime);
- }
- if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) {
- setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
- }
- if(settings.headers) {
- for(var name in settings.headers)
- setHeader(name, settings.headers[name]);
- }
- xhr.setRequestHeader = setHeader;
- xhr.onreadystatechange = function() {
- if(xhr.readyState === 4) {
- xhr.onreadystatechange = $.noop;
- clearTimeout(abortTimeout);
- var result, error = false;
- var isLocal = protocol === 'file:';
- if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) {
- dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'));
- result = xhr.responseText;
- try {
- // http://perfectionkills.com/global-eval-what-are-the-options/
- if(dataType === 'script') {
- (1, eval)(result);
- } else if(dataType === 'xml') {
- result = xhr.responseXML;
- } else if(dataType === 'json') {
- result = blankRE.test(result) ? null : $.parseJSON(result);
- }
- } catch(e) {
- error = e;
- }
- if(error) {
- ajaxError(error, 'parsererror', xhr, settings);
- } else {
- ajaxSuccess(result, xhr, settings);
- }
- } else {
- var status = xhr.status ? 'error' : 'abort';
- var statusText = xhr.statusText || null;
- if(isLocal) {
- status = 'error';
- statusText = '404';
- }
- ajaxError(statusText, status, xhr, settings);
- }
- }
- };
- if(ajaxBeforeSend(xhr, settings) === false) {
- xhr.abort();
- ajaxError(null, 'abort', xhr, settings);
- return xhr;
- }
- if(settings.xhrFields) {
- for(var name in settings.xhrFields) {
- xhr[name] = settings.xhrFields[name];
- }
- }
- var async = 'async' in settings ? settings.async : true;
- xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password);
- for(var name in headers) {
- if(headers.hasOwnProperty(name)) {
- nativeSetHeader.apply(xhr, headers[name]);
- }
- }
- if(settings.timeout > 0) {
- abortTimeout = setTimeout(function() {
- xhr.onreadystatechange = $.noop;
- xhr.abort();
- ajaxError(null, 'timeout', xhr, settings);
- }, settings.timeout);
- }
- xhr.send(settings.data ? settings.data : null);
- return xhr;
- };
- $.param = function(obj, traditional) {
- var params = [];
- params.add = function(k, v) {
- this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
- };
- serialize(params, obj, traditional);
- return params.join('&').replace(/%20/g, '+');
- };
- $.get = function( /* url, data, success, dataType */ ) {
- return $.ajax(parseArguments.apply(null, arguments));
- };
- $.post = function( /* url, data, success, dataType */ ) {
- var options = parseArguments.apply(null, arguments);
- options.type = 'POST';
- return $.ajax(options);
- };
- $.getJSON = function( /* url, data, success */ ) {
- var options = parseArguments.apply(null, arguments);
- options.dataType = 'json';
- return $.ajax(options);
- };
- $.fn.load = function(url, data, success) {
- if(!this.length)
- return this;
- var self = this,
- parts = url.split(/\s/),
- selector,
- options = parseArguments(url, data, success),
- callback = options.success;
- if(parts.length > 1)
- options.url = parts[0], selector = parts[1];
- options.success = function(response) {
- if(selector) {
- var div = document.createElement('div');
- div.innerHTML = response.replace(rscript, "");
- var selectorDiv = document.createElement('div');
- var childs = div.querySelectorAll(selector);
- if(childs && childs.length > 0) {
- for(var i = 0, len = childs.length; i < len; i++) {
- selectorDiv.appendChild(childs[i]);
- }
- }
- self[0].innerHTML = selectorDiv.innerHTML;
- } else {
- self[0].innerHTML = response;
- }
- callback && callback.apply(self, arguments);
- };
- $.ajax(options);
- return this;
- };
- })(mui, window);
- /**
- * 5+ ajax
- */
- (function($) {
- var originAnchor = document.createElement('a');
- originAnchor.href = window.location.href;
- $.plusReady(function() {
- $.ajaxSettings = $.extend($.ajaxSettings, {
- xhr: function(settings) {
- if (settings.crossDomain) { //强制使用plus跨域
- return new plus.net.XMLHttpRequest();
- }
- //仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest
- if (originAnchor.protocol !== 'file:') {
- var urlAnchor = document.createElement('a');
- urlAnchor.href = settings.url;
- urlAnchor.href = urlAnchor.href;
- settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host);
- if (settings.crossDomain) {
- return new plus.net.XMLHttpRequest();
- }
- }
- if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr
- return new plus.net.XMLHttpRequest();
- }
- return new window.XMLHttpRequest();
- }
- });
- });
- })(mui);
- /**
- * mui layout(offset[,position,width,height...])
- * @param {type} $
- * @param {type} window
- * @param {type} undefined
- * @returns {undefined}
- */
- (function($, window, undefined) {
- $.offset = function(element) {
- var box = {
- top : 0,
- left : 0
- };
- if ( typeof element.getBoundingClientRect !== undefined) {
- box = element.getBoundingClientRect();
- }
- return {
- top : box.top + window.pageYOffset - element.clientTop,
- left : box.left + window.pageXOffset - element.clientLeft
- };
- };
- })(mui, window);
- /**
- * mui animation
- */
- (function($, window) {
- /**
- * scrollTo
- */
- $.scrollTo = function(scrollTop, duration, callback) {
- duration = duration || 1000;
- var scroll = function(duration) {
- if (duration <= 0) {
- window.scrollTo(0, scrollTop);
- callback && callback();
- return;
- }
- var distaince = scrollTop - window.scrollY;
- setTimeout(function() {
- window.scrollTo(0, window.scrollY + distaince / duration * 10);
- scroll(duration - 10);
- }, 16.7);
- };
- scroll(duration);
- };
- $.animationFrame = function(cb) {
- var args, isQueued, context;
- return function() {
- args = arguments;
- context = this;
- if (!isQueued) {
- isQueued = true;
- requestAnimationFrame(function() {
- cb.apply(context, args);
- isQueued = false;
- });
- }
- };
- };
- })(mui, window);
- (function($) {
- var initializing = false,
- fnTest = /xyz/.test(function() {
- xyz;
- }) ? /\b_super\b/ : /.*/;
- var Class = function() {};
- Class.extend = function(prop) {
- var _super = this.prototype;
- initializing = true;
- var prototype = new this();
- initializing = false;
- for (var name in prop) {
- prototype[name] = typeof prop[name] == "function" &&
- typeof _super[name] == "function" && fnTest.test(prop[name]) ?
- (function(name, fn) {
- return function() {
- var tmp = this._super;
- this._super = _super[name];
- var ret = fn.apply(this, arguments);
- this._super = tmp;
- return ret;
- };
- })(name, prop[name]) :
- prop[name];
- }
- function Class() {
- if (!initializing && this.init)
- this.init.apply(this, arguments);
- }
- Class.prototype = prototype;
- Class.prototype.constructor = Class;
- Class.extend = arguments.callee;
- return Class;
- };
- $.Class = Class;
- })(mui);
- (function($, document, undefined) {
- var CLASS_PULL_TOP_POCKET = 'mui-pull-top-pocket';
- var CLASS_PULL_BOTTOM_POCKET = 'mui-pull-bottom-pocket';
- var CLASS_PULL = 'mui-pull';
- var CLASS_PULL_LOADING = 'mui-pull-loading';
- var CLASS_PULL_CAPTION = 'mui-pull-caption';
- var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
- var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
- var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
- var CLASS_ICON = 'mui-icon';
- var CLASS_SPINNER = 'mui-spinner';
- var CLASS_ICON_PULLDOWN = 'mui-icon-pulldown';
- var CLASS_BLOCK = 'mui-block';
- var CLASS_HIDDEN = 'mui-hidden';
- var CLASS_VISIBILITY = 'mui-visibility';
- var CLASS_LOADING_UP = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
- var CLASS_LOADING_DOWN = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
- var CLASS_LOADING = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_SPINNER;
- var pocketHtml = ['<div class="' + CLASS_PULL + '">', '<div class="{icon}"></div>', '<div class="' + CLASS_PULL_CAPTION + '">{contentrefresh}</div>', '</div>'].join('');
- var PullRefresh = {
- init: function(element, options) {
- this._super(element, $.extend(true, {
- scrollY: true,
- scrollX: false,
- indicators: true,
- deceleration: 0.003,
- down: {
- height: 50,
- contentinit: '下拉可以刷新',
- contentdown: '下拉可以刷新',
- contentover: '释放立即刷新',
- contentrefresh: '正在刷新...'
- },
- up: {
- height: 50,
- auto: false,
- contentinit: '上拉显示更多',
- contentdown: '上拉显示更多',
- contentrefresh: '正在加载...',
- contentnomore: '没有更多数据了',
- duration: 300
- }
- }, options));
- },
- _init: function() {
- this._super();
- this._initPocket();
- },
- _initPulldownRefresh: function() {
- this.pulldown = true;
- if (this.topPocket) {
- this.pullPocket = this.topPocket;
- this.pullPocket.classList.add(CLASS_BLOCK);
- this.pullPocket.classList.add(CLASS_VISIBILITY);
- this.pullCaption = this.topCaption;
- this.pullLoading = this.topLoading;
- }
- },
- _initPullupRefresh: function() {
- this.pulldown = false;
- if (this.bottomPocket) {
- this.pullPocket = this.bottomPocket;
- this.pullPocket.classList.add(CLASS_BLOCK);
- this.pullPocket.classList.add(CLASS_VISIBILITY);
- this.pullCaption = this.bottomCaption;
- this.pullLoading = this.bottomLoading;
- }
- },
- _initPocket: function() {
- var options = this.options;
- if (options.down && options.down.hasOwnProperty('callback')) {
- this.topPocket = this.scroller.querySelector('.' + CLASS_PULL_TOP_POCKET);
- if (!this.topPocket) {
- this.topPocket = this._createPocket(CLASS_PULL_TOP_POCKET, options.down, CLASS_LOADING_DOWN);
- this.wrapper.insertBefore(this.topPocket, this.wrapper.firstChild);
- }
- this.topLoading = this.topPocket.querySelector('.' + CLASS_PULL_LOADING);
- this.topCaption = this.topPocket.querySelector('.' + CLASS_PULL_CAPTION);
- }
- if (options.up && options.up.hasOwnProperty('callback')) {
- this.bottomPocket = this.scroller.querySelector('.' + CLASS_PULL_BOTTOM_POCKET);
- if (!this.bottomPocket) {
- this.bottomPocket = this._createPocket(CLASS_PULL_BOTTOM_POCKET, options.up, CLASS_LOADING);
- this.scroller.appendChild(this.bottomPocket);
- }
- this.bottomLoading = this.bottomPocket.querySelector('.' + CLASS_PULL_LOADING);
- this.bottomCaption = this.bottomPocket.querySelector('.' + CLASS_PULL_CAPTION);
- //TODO only for h5
- this.wrapper.addEventListener('scrollbottom', this);
- }
- },
- _createPocket: function(clazz, options, iconClass) {
- var pocket = document.createElement('div');
- pocket.className = clazz;
- pocket.innerHTML = pocketHtml.replace('{contentrefresh}', options.contentinit).replace('{icon}', iconClass);
- return pocket;
- },
- _resetPullDownLoading: function() {
- var loading = this.pullLoading;
- if (loading) {
- this.pullCaption.innerHTML = this.options.down.contentdown;
- loading.style.webkitTransition = "";
- loading.style.webkitTransform = "";
- loading.style.webkitAnimation = "";
- loading.className = CLASS_LOADING_DOWN;
- }
- },
- _setCaptionClass: function(isPulldown, caption, title) {
- if (!isPulldown) {
- switch (title) {
- case this.options.up.contentdown:
- caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
- break;
- case this.options.up.contentrefresh:
- caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH
- break;
- case this.options.up.contentnomore:
- caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
- break;
- }
- }
- },
- _setCaption: function(title, reset) {
- if (this.loading) {
- return;
- }
- var options = this.options;
- var pocket = this.pullPocket;
- var caption = this.pullCaption;
- var loading = this.pullLoading;
- var isPulldown = this.pulldown;
- var self = this;
- if (pocket) {
- if (reset) {
- setTimeout(function() {
- caption.innerHTML = self.lastTitle = title;
- if (isPulldown) {
- loading.className = CLASS_LOADING_DOWN;
- } else {
- self._setCaptionClass(false, caption, title);
- loading.className = CLASS_LOADING;
- }
- loading.style.webkitAnimation = "";
- loading.style.webkitTransition = "";
- loading.style.webkitTransform = "";
- }, 100);
- } else {
- if (title !== this.lastTitle) {
- caption.innerHTML = title;
- if (isPulldown) {
- if (title === options.down.contentrefresh) {
- loading.className = CLASS_LOADING;
- loading.style.webkitAnimation = "spinner-spin 1s step-end infinite";
- } else if (title === options.down.contentover) {
- loading.className = CLASS_LOADING_UP;
- loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
- loading.style.webkitTransform = "rotate(180deg)";
- } else if (title === options.down.contentdown) {
- loading.className = CLASS_LOADING_DOWN;
- loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
- loading.style.webkitTransform = "rotate(0deg)";
- }
- } else {
- if (title === options.up.contentrefresh) {
- loading.className = CLASS_LOADING + ' ' + CLASS_VISIBILITY;
- } else {
- loading.className = CLASS_LOADING + ' ' + CLASS_HIDDEN;
- }
- self._setCaptionClass(false, caption, title);
- }
- this.lastTitle = title;
- }
- }
- }
- }
- };
- $.PullRefresh = PullRefresh;
- })(mui, document);
- (function($, window, document, undefined) {
- var CLASS_SCROLL = 'mui-scroll';
- var CLASS_SCROLLBAR = 'mui-scrollbar';
- var CLASS_INDICATOR = 'mui-scrollbar-indicator';
- var CLASS_SCROLLBAR_VERTICAL = CLASS_SCROLLBAR + '-vertical';
- var CLASS_SCROLLBAR_HORIZONTAL = CLASS_SCROLLBAR + '-horizontal';
- var CLASS_ACTIVE = 'mui-active';
- var ease = {
- quadratic: {
- style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
- fn: function(k) {
- return k * (2 - k);
- }
- },
- circular: {
- style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',
- fn: function(k) {
- return Math.sqrt(1 - (--k * k));
- }
- },
- outCirc: {
- style: 'cubic-bezier(0.075, 0.82, 0.165, 1)'
- },
- outCubic: {
- style: 'cubic-bezier(0.165, 0.84, 0.44, 1)'
- }
- }
- var Scroll = $.Class.extend({
- init: function(element, options) {
- this.wrapper = this.element = element;
- this.scroller = this.wrapper.children[0];
- this.scrollerStyle = this.scroller && this.scroller.style;
- this.stopped = false;
- this.options = $.extend(true, {
- scrollY: true, //是否竖向滚动
- scrollX: false, //是否横向滚动
- startX: 0, //初始化时滚动至x
- startY: 0, //初始化时滚动至y
- indicators: true, //是否显示滚动条
- stopPropagation: false,
- hardwareAccelerated: true,
- fixedBadAndorid: false,
- preventDefaultException: {
- tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
- },
- momentum: true,
- snapX: 0.5, //横向切换距离(以当前容器宽度为基准)
- snap: false, //图片轮播,拖拽式选项卡
- bounce: true, //是否启用回弹
- bounceTime: 500, //回弹动画时间
- bounceEasing: ease.outCirc, //回弹动画曲线
- scrollTime: 500,
- scrollEasing: ease.outCubic, //轮播动画曲线
- directionLockThreshold: 5,
- parallaxElement: false, //视差元素
- parallaxRatio: 0.5
- }, options);
- this.x = 0;
- this.y = 0;
- this.translateZ = this.options.hardwareAccelerated ? ' translateZ(0)' : '';
- this._init();
- if (this.scroller) {
- this.refresh();
- // if (this.options.startX !== 0 || this.options.startY !== 0) { //需要判断吗?后续根据实际情况再看看
- this.scrollTo(this.options.startX, this.options.startY);
- // }
- }
- },
- _init: function() {
- this._initParallax();
- this._initIndicators();
- this._initEvent();
- },
- _initParallax: function() {
- if (this.options.parallaxElement) {
- this.parallaxElement = document.querySelector(this.options.parallaxElement);
- this.parallaxStyle = this.parallaxElement.style;
- this.parallaxHeight = this.parallaxElement.offsetHeight;
- this.parallaxImgStyle = this.parallaxElement.querySelector('img').style;
- }
- },
- _initIndicators: function() {
- var self = this;
- self.indicators = [];
- if (!this.options.indicators) {
- return;
- }
- var indicators = [],
- indicator;
- // Vertical scrollbar
- if (self.options.scrollY) {
- indicator = {
- el: this._createScrollBar(CLASS_SCROLLBAR_VERTICAL),
- listenX: false
- };
- this.wrapper.appendChild(indicator.el);
- indicators.push(indicator);
- }
- // Horizontal scrollbar
- if (this.options.scrollX) {
- indicator = {
- el: this._createScrollBar(CLASS_SCROLLBAR_HORIZONTAL),
- listenY: false
- };
- this.wrapper.appendChild(indicator.el);
- indicators.push(indicator);
- }
- for (var i = indicators.length; i--;) {
- this.indicators.push(new Indicator(this, indicators[i]));
- }
- },
- _initSnap: function() {
- this.currentPage = {};
- this.pages = [];
- var snaps = this.snaps;
- var length = snaps.length;
- var m = 0;
- var n = -1;
- var x = 0;
- var leftX = 0;
- var rightX = 0;
- var snapX = 0;
- for (var i = 0; i < length; i++) {
- var snap = snaps[i];
- var offsetLeft = snap.offsetLeft;
- var offsetWidth = snap.offsetWidth;
- if (i === 0 || offsetLeft <= snaps[i - 1].offsetLeft) {
- m = 0;
- n++;
- }
- if (!this.pages[m]) {
- this.pages[m] = [];
- }
- x = this._getSnapX(offsetLeft);
- snapX = Math.round((offsetWidth) * this.options.snapX);
- leftX = x - snapX;
- rightX = x - offsetWidth + snapX;
- this.pages[m][n] = {
- x: x,
- leftX: leftX,
- rightX: rightX,
- pageX: m,
- element: snap
- }
- if (snap.classList.contains(CLASS_ACTIVE)) {
- this.currentPage = this.pages[m][0];
- }
- if (x >= this.maxScrollX) {
- m++;
- }
- }
- this.options.startX = this.currentPage.x || 0;
- },
- _getSnapX: function(offsetLeft) {
- return Math.max(Math.min(0, -offsetLeft + (this.wrapperWidth / 2)), this.maxScrollX);
- },
- _gotoPage: function(index) {
- this.currentPage = this.pages[Math.min(index, this.pages.length - 1)][0];
- for (var i = 0, len = this.snaps.length; i < len; i++) {
- if (i === index) {
- this.snaps[i].classList.add(CLASS_ACTIVE);
- } else {
- this.snaps[i].classList.remove(CLASS_ACTIVE);
- }
- }
- this.scrollTo(this.currentPage.x, 0, this.options.scrollTime);
- },
- _nearestSnap: function(x) {
- if (!this.pages.length) {
- return {
- x: 0,
- pageX: 0
- };
- }
- var i = 0;
- var length = this.pages.length;
- if (x > 0) {
- x = 0;
- } else if (x < this.maxScrollX) {
- x = this.maxScrollX;
- }
- for (; i < length; i++) {
- var nearestX = this.direction === 'left' ? this.pages[i][0].leftX : this.pages[i][0].rightX;
- if (x >= nearestX) {
- return this.pages[i][0];
- }
- }
- return {
- x: 0,
- pageX: 0
- };
- },
- _initEvent: function(detach) {
- var action = detach ? 'removeEventListener' : 'addEventListener';
- window[action]('orientationchange', this);
- window[action]('resize', this);
- this.scroller[action]('webkitTransitionEnd', this);
- this.wrapper[action]($.EVENT_START, this);
- this.wrapper[action]($.EVENT_CANCEL, this);
- this.wrapper[action]($.EVENT_END, this);
- this.wrapper[action]('drag', this);
- this.wrapper[action]('dragend', this);
- this.wrapper[action]('flick', this);
- this.wrapper[action]('scrollend', this);
- if (this.options.scrollX) {
- this.wrapper[action]('swiperight', this);
- }
- var segmentedControl = this.wrapper.querySelector('.mui-segmented-control');
- if (segmentedControl) { //靠,这个bug排查了一下午,阻止hash跳转,一旦hash跳转会导致可拖拽选项卡的tab不见
- mui(segmentedControl)[detach ? 'off' : 'on']('click', 'a', $.preventDefault);
- }
- this.wrapper[action]('scrollstart', this);
- this.wrapper[action]('refresh', this);
- },
- _handleIndicatorScrollend: function() {
- this.indicators.map(function(indicator) {
- indicator.fade();
- });
- },
- _handleIndicatorScrollstart: function() {
- this.indicators.map(function(indicator) {
- indicator.fade(1);
- });
- },
- _handleIndicatorRefresh: function() {
- this.indicators.map(function(indicator) {
- indicator.refresh();
- });
- },
- handleEvent: function(e) {
- if (this.stopped) {
- this.resetPosition();
- return;
- }
- switch (e.type) {
- case $.EVENT_START:
- this._start(e);
- break;
- case 'drag':
- this.options.stopPropagation && e.stopPropagation();
- this._drag(e);
- break;
- case 'dragend':
- case 'flick':
- this.options.stopPropagation && e.stopPropagation();
- this._flick(e);
- break;
- case $.EVENT_CANCEL:
- case $.EVENT_END:
- this._end(e);
- break;
- case 'webkitTransitionEnd':
- this.transitionTimer && this.transitionTimer.cancel();
- this._transitionEnd(e);
- break;
- case 'scrollstart':
- this._handleIndicatorScrollstart(e);
- break;
- case 'scrollend':
- this._handleIndicatorScrollend(e);
- this._scrollend(e);
- e.stopPropagation();
- break;
- case 'orientationchange':
- case 'resize':
- this._resize();
- break;
- case 'swiperight':
- e.stopPropagation();
- break;
- case 'refresh':
- this._handleIndicatorRefresh(e);
- break;
- }
- },
- _start: function(e) {
- this.moved = this.needReset = false;
- this._transitionTime();
- if (this.isInTransition) {
- this.needReset = true;
- this.isInTransition = false;
- var pos = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
- this.setTranslate(Math.round(pos.x), Math.round(pos.y));
- // this.resetPosition(); //reset
- $.trigger(this.scroller, 'scrollend', this);
- // e.stopPropagation();
- e.preventDefault();
- }
- this.reLayout();
- $.trigger(this.scroller, 'beforescrollstart', this);
- },
- _getDirectionByAngle: function(angle) {
- if (angle < -80 && angle > -100) {
- return 'up';
- } else if (angle >= 80 && angle < 100) {
- return 'down';
- } else if (angle >= 170 || angle <= -170) {
- return 'left';
- } else if (angle >= -35 && angle <= 10) {
- return 'right';
- }
- return null;
- },
- _drag: function(e) {
- // if (this.needReset) {
- // e.stopPropagation(); //disable parent drag(nested scroller)
- // return;
- // }
- var detail = e.detail;
- if (this.options.scrollY || detail.direction === 'up' || detail.direction === 'down') { //如果是竖向滚动或手势方向是上或下
- //ios8 hack
- if ($.os.ios && parseFloat($.os.version) >= 8) { //多webview时,离开当前webview会导致后续touch事件不触发
- var clientY = detail.gesture.touches[0].clientY;
- //下拉刷新 or 上拉加载
- if ((clientY + 10) > window.innerHeight || clientY < 10) {
- this.resetPosition(this.options.bounceTime);
- return;
- }
- }
- }
- var isPreventDefault = isReturn = false;
- var direction = this._getDirectionByAngle(detail.angle);
- if (detail.direction === 'left' || detail.direction === 'right') {
- if (this.options.scrollX) {
- isPreventDefault = true;
- if (!this.moved) { //识别角度(该角度导致轮播不灵敏)
- // if (direction !== 'left' && direction !== 'right') {
- // isReturn = true;
- // } else {
- $.gestures.session.lockDirection = true; //锁定方向
- $.gestures.session.startDirection = detail.direction;
- // }
- }
- } else if (this.options.scrollY && !this.moved) {
- isReturn = true;
- }
- } else if (detail.direction === 'up' || detail.direction === 'down') {
- if (this.options.scrollY) {
- isPreventDefault = true;
- // if (!this.moved) { //识别角度,竖向滚动似乎没必要进行小角度验证
- // if (direction !== 'up' && direction !== 'down') {
- // isReturn = true;
- // }
- // }
- if (!this.moved) {
- $.gestures.session.lockDirection = true; //锁定方向
- $.gestures.session.startDirection = detail.direction;
- }
- } else if (this.options.scrollX && !this.moved) {
- isReturn = true;
- }
- } else {
- isReturn = true;
- }
- if (this.moved || isPreventDefault) {
- e.stopPropagation(); //阻止冒泡(scroll类嵌套)
- detail.gesture && detail.gesture.preventDefault();
- }
- if (isReturn) { //禁止非法方向滚动
- return;
- }
- if (!this.moved) {
- $.trigger(this.scroller, 'scrollstart', this);
- } else {
- e.stopPropagation(); //move期间阻止冒泡(scroll嵌套)
- }
- var deltaX = 0;
- var deltaY = 0;
- if (!this.moved) { //start
- deltaX = detail.deltaX;
- deltaY = detail.deltaY;
- } else { //move
- deltaX = detail.deltaX - $.gestures.session.prevTouch.deltaX;
- deltaY = detail.deltaY - $.gestures.session.prevTouch.deltaY;
- }
- var absDeltaX = Math.abs(detail.deltaX);
- var absDeltaY = Math.abs(detail.deltaY);
- if (absDeltaX > absDeltaY + this.options.directionLockThreshold) {
- deltaY = 0;
- } else if (absDeltaY >= absDeltaX + this.options.directionLockThreshold) {
- deltaX = 0;
- }
- deltaX = this.hasHorizontalScroll ? deltaX : 0;
- deltaY = this.hasVerticalScroll ? deltaY : 0;
- var newX = this.x + deltaX;
- var newY = this.y + deltaY;
- // Slow down if outside of the boundaries
- if (newX > 0 || newX < this.maxScrollX) {
- newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
- }
- if (newY > 0 || newY < this.maxScrollY) {
- newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
- }
- if (!this.requestAnimationFrame) {
- this._updateTranslate();
- }
- this.direction = detail.deltaX > 0 ? 'right' : 'left';
- this.moved = true;
- this.x = newX;
- this.y = newY;
- $.trigger(this.scroller, 'scroll', this);
- },
- _flick: function(e) {
- // if (!this.moved || this.needReset) {
- // return;
- // }
- if (!this.moved) {
- return;
- }
- e.stopPropagation();
- var detail = e.detail;
- this._clearRequestAnimationFrame();
- if (e.type === 'dragend' && detail.flick) { //dragend
- return;
- }
- var newX = Math.round(this.x);
- var newY = Math.round(this.y);
- this.isInTransition = false;
- // reset if we are outside of the boundaries
- if (this.resetPosition(this.options.bounceTime)) {
- return;
- }
- this.scrollTo(newX, newY); // ensures that the last position is rounded
- if (e.type === 'dragend') { //dragend
- $.trigger(this.scroller, 'scrollend', this);
- return;
- }
- var time = 0;
- var easing = '';
- // start momentum animation if needed
- if (this.options.momentum && detail.flickTime < 300) {
- momentumX = this.hasHorizontalScroll ? this._momentum(this.x, detail.flickDistanceX, detail.flickTime, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : {
- destination: newX,
- duration: 0
- };
- momentumY = this.hasVerticalScroll ? this._momentum(this.y, detail.flickDistanceY, detail.flickTime, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : {
- destination: newY,
- duration: 0
- };
- newX = momentumX.destination;
- newY = momentumY.destination;
- time = Math.max(momentumX.duration, momentumY.duration);
- this.isInTransition = true;
- }
- if (newX != this.x || newY != this.y) {
- if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) {
- easing = ease.quadratic;
- }
- this.scrollTo(newX, newY, time, easing);
- return;
- }
- $.trigger(this.scroller, 'scrollend', this);
- // e.stopPropagation();
- },
- _end: function(e) {
- this.needReset = false;
- if ((!this.moved && this.needReset) || e.type === $.EVENT_CANCEL) {
- this.resetPosition();
- }
- },
- _transitionEnd: function(e) {
- if (e.target != this.scroller || !this.isInTransition) {
- return;
- }
- this._transitionTime();
- if (!this.resetPosition(this.options.bounceTime)) {
- this.isInTransition = false;
- $.trigger(this.scroller, 'scrollend', this);
- }
- },
- _scrollend: function(e) {
- if ((this.y === 0 && this.maxScrollY === 0) || (Math.abs(this.y) > 0 && this.y <= this.maxScrollY)) {
- $.trigger(this.scroller, 'scrollbottom', this);
- }
- },
- _resize: function() {
- var that = this;
- clearTimeout(that.resizeTimeout);
- that.resizeTimeout = setTimeout(function() {
- that.refresh();
- }, that.options.resizePolling);
- },
- _transitionTime: function(time) {
- time = time || 0;
- this.scrollerStyle['webkitTransitionDuration'] = time + 'ms';
- if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
- this.parallaxStyle['webkitTransitionDuration'] = time + 'ms';
- }
- if (this.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
- this.scrollerStyle['webkitTransitionDuration'] = '0.001s';
- if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
- this.parallaxStyle['webkitTransitionDuration'] = '0.001s';
- }
- }
- if (this.indicators) {
- for (var i = this.indicators.length; i--;) {
- this.indicators[i].transitionTime(time);
- }
- }
- if (time) { //自定义timer,保证webkitTransitionEnd始终触发
- this.transitionTimer && this.transitionTimer.cancel();
- this.transitionTimer = $.later(function() {
- $.trigger(this.scroller, 'webkitTransitionEnd');
- }, time + 100, this);
- }
- },
- _transitionTimingFunction: function(easing) {
- this.scrollerStyle['webkitTransitionTimingFunction'] = easing;
- if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
- this.parallaxStyle['webkitTransitionDuration'] = easing;
- }
- if (this.indicators) {
- for (var i = this.indicators.length; i--;) {
- this.indicators[i].transitionTimingFunction(easing);
- }
- }
- },
- _translate: function(x, y) {
- this.x = x;
- this.y = y;
- },
- _clearRequestAnimationFrame: function() {
- if (this.requestAnimationFrame) {
- cancelAnimationFrame(this.requestAnimationFrame);
- this.requestAnimationFrame = null;
- }
- },
- _updateTranslate: function() {
- var self = this;
- if (self.x !== self.lastX || self.y !== self.lastY) {
- self.setTranslate(self.x, self.y);
- }
- self.requestAnimationFrame = requestAnimationFrame(function() {
- self._updateTranslate();
- });
- },
- _createScrollBar: function(clazz) {
- var scrollbar = document.createElement('div');
- var indicator = document.createElement('div');
- scrollbar.className = CLASS_SCROLLBAR + ' ' + clazz;
- indicator.className = CLASS_INDICATOR;
- scrollbar.appendChild(indicator);
- if (clazz === CLASS_SCROLLBAR_VERTICAL) {
- this.scrollbarY = scrollbar;
- this.scrollbarIndicatorY = indicator;
- } else if (clazz === CLASS_SCROLLBAR_HORIZONTAL) {
- this.scrollbarX = scrollbar;
- this.scrollbarIndicatorX = indicator;
- }
- this.wrapper.appendChild(scrollbar);
- return scrollbar;
- },
- _preventDefaultException: function(el, exceptions) {
- for (var i in exceptions) {
- if (exceptions[i].test(el[i])) {
- return true;
- }
- }
- return false;
- },
- _reLayout: function() {
- if (!this.hasHorizontalScroll) {
- this.maxScrollX = 0;
- this.scrollerWidth = this.wrapperWidth;
- }
- if (!this.hasVerticalScroll) {
- this.maxScrollY = 0;
- this.scrollerHeight = this.wrapperHeight;
- }
- this.indicators.map(function(indicator) {
- indicator.refresh();
- });
- //以防slider类嵌套使用
- if (this.options.snap && typeof this.options.snap === 'string') {
- var items = this.scroller.querySelectorAll(this.options.snap);
- this.itemLength = 0;
- this.snaps = [];
- for (var i = 0, len = items.length; i < len; i++) {
- var item = items[i];
- if (item.parentNode === this.scroller) {
- this.itemLength++;
- this.snaps.push(item);
- }
- }
- this._initSnap(); //需要每次都_initSnap么。其实init的时候执行一次,后续resize的时候执行一次就行了吧.先这么做吧,如果影响性能,再调整
- }
- },
- _momentum: function(current, distance, time, lowerMargin, wrapperSize, deceleration) {
- var speed = parseFloat(Math.abs(distance) / time),
- destination,
- duration;
- deceleration = deceleration === undefined ? 0.0006 : deceleration;
- destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1);
- duration = speed / deceleration;
- if (destination < lowerMargin) {
- destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin;
- distance = Math.abs(destination - current);
- duration = distance / speed;
- } else if (destination > 0) {
- destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0;
- distance = Math.abs(current) + destination;
- duration = distance / speed;
- }
- return {
- destination: Math.round(destination),
- duration: duration
- };
- },
- _getTranslateStr: function(x, y) {
- if (this.options.hardwareAccelerated) {
- return 'translate3d(' + x + 'px,' + y + 'px,0px) ' + this.translateZ;
- }
- return 'translate(' + x + 'px,' + y + 'px) ';
- },
- //API
- setStopped: function(stopped) {
- // this.stopped = !!stopped;
- // fixed ios双webview模式下拉刷新
- if(stopped) {
- this.disablePullupToRefresh();
- this.disablePulldownToRefresh();
- } else {
- this.enablePullupToRefresh();
- this.enablePulldownToRefresh();
- }
- },
- setTranslate: function(x, y) {
- this.x = x;
- this.y = y;
- this.scrollerStyle['webkitTransform'] = this._getTranslateStr(x, y);
- if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
- var parallaxY = y * this.options.parallaxRatio;
- var scale = 1 + parallaxY / ((this.parallaxHeight - parallaxY) / 2);
- if (scale > 1) {
- this.parallaxImgStyle['opacity'] = 1 - parallaxY / 100 * this.options.parallaxRatio;
- this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -parallaxY) + ' scale(' + scale + ',' + scale + ')';
- } else {
- this.parallaxImgStyle['opacity'] = 1;
- this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -1) + ' scale(1,1)';
- }
- }
- if (this.indicators) {
- for (var i = this.indicators.length; i--;) {
- this.indicators[i].updatePosition();
- }
- }
- this.lastX = this.x;
- this.lastY = this.y;
- $.trigger(this.scroller, 'scroll', this);
- },
- reLayout: function() {
- this.wrapper.offsetHeight;
- var paddingLeft = parseFloat($.getStyles(this.wrapper, 'padding-left')) || 0;
- var paddingRight = parseFloat($.getStyles(this.wrapper, 'padding-right')) || 0;
- var paddingTop = parseFloat($.getStyles(this.wrapper, 'padding-top')) || 0;
- var paddingBottom = parseFloat($.getStyles(this.wrapper, 'padding-bottom')) || 0;
- var clientWidth = this.wrapper.clientWidth;
- var clientHeight = this.wrapper.clientHeight;
- this.scrollerWidth = this.scroller.offsetWidth;
- this.scrollerHeight = this.scroller.offsetHeight;
- this.wrapperWidth = clientWidth - paddingLeft - paddingRight;
- this.wrapperHeight = clientHeight - paddingTop - paddingBottom;
- this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
- this.maxScrollY = Math.min(this.wrapperHeight - this.scrollerHeight, 0);
- this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
- this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
- this._reLayout();
- },
- resetPosition: function(time) {
- var x = this.x,
- y = this.y;
- time = time || 0;
- if (!this.hasHorizontalScroll || this.x > 0) {
- x = 0;
- } else if (this.x < this.maxScrollX) {
- x = this.maxScrollX;
- }
- if (!this.hasVerticalScroll || this.y > 0) {
- y = 0;
- } else if (this.y < this.maxScrollY) {
- y = this.maxScrollY;
- }
- if (x == this.x && y == this.y) {
- return false;
- }
- this.scrollTo(x, y, time, this.options.scrollEasing);
- return true;
- },
- _reInit: function() {
- var groups = this.wrapper.querySelectorAll('.' + CLASS_SCROLL);
- for (var i = 0, len = groups.length; i < len; i++) {
- if (groups[i].parentNode === this.wrapper) {
- this.scroller = groups[i];
- break;
- }
- }
- this.scrollerStyle = this.scroller && this.scroller.style;
- },
- refresh: function() {
- this._reInit();
- this.reLayout();
- $.trigger(this.scroller, 'refresh', this);
- this.resetPosition();
- },
- scrollTo: function(x, y, time, easing) {
- var easing = easing || ease.circular;
- // this.isInTransition = time > 0 && (this.lastX != x || this.lastY != y);
- //暂不严格判断x,y,否则会导致部分版本上不正常触发轮播
- this.isInTransition = time > 0;
- if (this.isInTransition) {
- this._clearRequestAnimationFrame();
- this._transitionTimingFunction(easing.style);
- this._transitionTime(time);
- this.setTranslate(x, y);
- } else {
- this.setTranslate(x, y);
- }
- },
- scrollToBottom: function(time, easing) {
- time = time || this.options.scrollTime;
- this.scrollTo(0, this.maxScrollY, time, easing);
- },
- gotoPage: function(index) {
- this._gotoPage(index);
- },
- destroy: function() {
- this._initEvent(true); //detach
- delete $.data[this.wrapper.getAttribute('data-scroll')];
- this.wrapper.setAttribute('data-scroll', '');
- }
- });
- //Indicator
- var Indicator = function(scroller, options) {
- this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
- this.wrapperStyle = this.wrapper.style;
- this.indicator = this.wrapper.children[0];
- this.indicatorStyle = this.indicator.style;
- this.scroller = scroller;
- this.options = $.extend({
- listenX: true,
- listenY: true,
- fade: false,
- speedRatioX: 0,
- speedRatioY: 0
- }, options);
- this.sizeRatioX = 1;
- this.sizeRatioY = 1;
- this.maxPosX = 0;
- this.maxPosY = 0;
- if (this.options.fade) {
- this.wrapperStyle['webkitTransform'] = this.scroller.translateZ;
- this.wrapperStyle['webkitTransitionDuration'] = this.options.fixedBadAndorid && $.os.isBadAndroid ? '0.001s' : '0ms';
- this.wrapperStyle.opacity = '0';
- }
- }
- Indicator.prototype = {
- handleEvent: function(e) {
- },
- transitionTime: function(time) {
- time = time || 0;
- this.indicatorStyle['webkitTransitionDuration'] = time + 'ms';
- if (this.scroller.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
- this.indicatorStyle['webkitTransitionDuration'] = '0.001s';
- }
- },
- transitionTimingFunction: function(easing) {
- this.indicatorStyle['webkitTransitionTimingFunction'] = easing;
- },
- refresh: function() {
- this.transitionTime();
- if (this.options.listenX && !this.options.listenY) {
- this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
- } else if (this.options.listenY && !this.options.listenX) {
- this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
- } else {
- this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
- }
- this.wrapper.offsetHeight; // force refresh
- if (this.options.listenX) {
- this.wrapperWidth = this.wrapper.clientWidth;
- this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
- this.indicatorStyle.width = this.indicatorWidth + 'px';
- this.maxPosX = this.wrapperWidth - this.indicatorWidth;
- this.minBoundaryX = 0;
- this.maxBoundaryX = this.maxPosX;
- this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
- }
- if (this.options.listenY) {
- this.wrapperHeight = this.wrapper.clientHeight;
- this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
- this.indicatorStyle.height = this.indicatorHeight + 'px';
- this.maxPosY = this.wrapperHeight - this.indicatorHeight;
- this.minBoundaryY = 0;
- this.maxBoundaryY = this.maxPosY;
- this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
- }
- this.updatePosition();
- },
- updatePosition: function() {
- var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
- y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
- if (x < this.minBoundaryX) {
- this.width = Math.max(this.indicatorWidth + x, 8);
- this.indicatorStyle.width = this.width + 'px';
- x = this.minBoundaryX;
- } else if (x > this.maxBoundaryX) {
- this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
- this.indicatorStyle.width = this.width + 'px';
- x = this.maxPosX + this.indicatorWidth - this.width;
- } else if (this.width != this.indicatorWidth) {
- this.width = this.indicatorWidth;
- this.indicatorStyle.width = this.width + 'px';
- }
- if (y < this.minBoundaryY) {
- this.height = Math.max(this.indicatorHeight + y * 3, 8);
- this.indicatorStyle.height = this.height + 'px';
- y = this.minBoundaryY;
- } else if (y > this.maxBoundaryY) {
- this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
- this.indicatorStyle.height = this.height + 'px';
- y = this.maxPosY + this.indicatorHeight - this.height;
- } else if (this.height != this.indicatorHeight) {
- this.height = this.indicatorHeight;
- this.indicatorStyle.height = this.height + 'px';
- }
- this.x = x;
- this.y = y;
- this.indicatorStyle['webkitTransform'] = this.scroller._getTranslateStr(x, y);
- },
- fade: function(val, hold) {
- if (hold && !this.visible) {
- return;
- }
- clearTimeout(this.fadeTimeout);
- this.fadeTimeout = null;
- var time = val ? 250 : 500,
- delay = val ? 0 : 300;
- val = val ? '1' : '0';
- this.wrapperStyle['webkitTransitionDuration'] = time + 'ms';
- this.fadeTimeout = setTimeout((function(val) {
- this.wrapperStyle.opacity = val;
- this.visible = +val;
- }).bind(this, val), delay);
- }
- };
- $.Scroll = Scroll;
- $.fn.scroll = function(options) {
- var scrollApis = [];
- this.each(function() {
- var scrollApi = null;
- var self = this;
- var id = self.getAttribute('data-scroll');
- if (!id) {
- id = ++$.uuid;
- var _options = $.extend({}, options);
- if (self.classList.contains('mui-segmented-control')) {
- _options = $.extend(_options, {
- scrollY: false,
- scrollX: true,
- indicators: false,
- snap: '.mui-control-item'
- });
- }
- $.data[id] = scrollApi = new Scroll(self, _options);
- self.setAttribute('data-scroll', id);
- } else {
- scrollApi = $.data[id];
- }
- scrollApis.push(scrollApi);
- });
- return scrollApis.length === 1 ? scrollApis[0] : scrollApis;
- };
- })(mui, window, document);
- (function($, window, document, undefined) {
- var CLASS_VISIBILITY = 'mui-visibility';
- var CLASS_HIDDEN = 'mui-hidden';
- var PullRefresh = $.Scroll.extend($.extend({
- handleEvent: function(e) {
- this._super(e);
- if (e.type === 'scrollbottom') {
- if (e.target === this.scroller) {
- this._scrollbottom();
- }
- }
- },
- _scrollbottom: function() {
- if (!this.pulldown && !this.loading) {
- this.pulldown = false;
- this._initPullupRefresh();
- this.pullupLoading();
- }
- },
- _start: function(e) {
- //仅下拉刷新在start阻止默认事件
- if (e.touches && e.touches.length && e.touches[0].clientX > 30) {
- e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
- }
- if (!this.loading) {
- this.pulldown = this.pullPocket = this.pullCaption = this.pullLoading = false
- }
- this._super(e);
- },
- _drag: function(e) {
- if (this.y >= 0 && this.disablePulldown && e.detail.direction === 'down') { //禁用下拉刷新
- return;
- }
- this._super(e);
- if (!this.pulldown && !this.loading && this.topPocket && e.detail.direction === 'down' && this.y >= 0) {
- this._initPulldownRefresh();
- }
- if (this.pulldown) {
- this._setCaption(this.y > this.options.down.height ? this.options.down.contentover : this.options.down.contentdown);
- }
- },
- _reLayout: function() {
- this.hasVerticalScroll = true;
- this._super();
- },
- //API
- resetPosition: function(time) {
- if (this.pulldown && !this.disablePulldown) {
- if (this.y >= this.options.down.height) {
- this.pulldownLoading(undefined, time || 0);
- return true;
- } else {
- !this.loading && this.topPocket.classList.remove(CLASS_VISIBILITY);
- }
- }
- return this._super(time);
- },
- pulldownLoading: function(y, time) {
- typeof y === 'undefined' && (y = this.options.down.height); //默认高度
- this.scrollTo(0, y, time, this.options.bounceEasing);
- if (this.loading) {
- return;
- }
- // if (!this.pulldown) {
- this._initPulldownRefresh();
- // }
- this._setCaption(this.options.down.contentrefresh);
- this.loading = true;
- this.indicators.map(function(indicator) {
- indicator.fade(0);
- });
- var callback = this.options.down.callback;
- callback && callback.call(this);
- },
- endPulldownToRefresh: function() {
- var self = this;
- if (self.topPocket && self.loading && this.pulldown) {
- self.scrollTo(0, 0, self.options.bounceTime, self.options.bounceEasing);
- self.loading = false;
- self._setCaption(self.options.down.contentdown, true);
- setTimeout(function() {
- self.loading || self.topPocket.classList.remove(CLASS_VISIBILITY);
- }, 350);
- }
- },
- pullupLoading: function(callback, x, time) {
- x = x || 0;
- this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing);
- if (this.loading) {
- return;
- }
- this._initPullupRefresh();
- this._setCaption(this.options.up.contentrefresh);
- this.indicators.map(function(indicator) {
- indicator.fade(0);
- });
- this.loading = true;
- callback = callback || this.options.up.callback;
- callback && callback.call(this);
- },
- endPullupToRefresh: function(finished) {
- var self = this;
- if (self.bottomPocket) { // && self.loading && !this.pulldown
- self.loading = false;
- if (finished) {
- this.finished = true;
- self._setCaption(self.options.up.contentnomore);
- // self.bottomPocket.classList.remove(CLASS_VISIBILITY);
- // self.bottomPocket.classList.add(CLASS_HIDDEN);
- self.wrapper.removeEventListener('scrollbottom', self);
- } else {
- self._setCaption(self.options.up.contentdown);
- // setTimeout(function() {
- self.loading || self.bottomPocket.classList.remove(CLASS_VISIBILITY);
- // }, 300);
- }
- }
- },
- disablePullupToRefresh: function() {
- this._initPullupRefresh();
- this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
- this.wrapper.removeEventListener('scrollbottom', this);
- },
- disablePulldownToRefresh: function() {
- this._initPulldownRefresh();
- this.topPocket.className = 'mui-pull-top-pocket' + ' ' + CLASS_HIDDEN;
- this.disablePulldown = true;
- },
- enablePulldownToRefresh: function() {
- this._initPulldownRefresh();
- this.topPocket.classList.remove(CLASS_HIDDEN);
- this._setCaption(this.options.down.contentdown);
- this.disablePulldown = false;
- },
- enablePullupToRefresh: function() {
- this._initPullupRefresh();
- this.bottomPocket.classList.remove(CLASS_HIDDEN);
- this._setCaption(this.options.up.contentdown);
- this.wrapper.addEventListener('scrollbottom', this);
- },
- refresh: function(isReset) {
- if (isReset && this.finished) {
- this.enablePullupToRefresh();
- this.finished = false;
- }
- this._super();
- },
- }, $.PullRefresh));
- $.fn.pullRefresh = function(options) {
- if (this.length === 1) {
- var self = this[0];
- var pullRefreshApi = null;
- var id = self.getAttribute('data-pullrefresh');
- if (!id && typeof options === 'undefined') {
- return false;
- }
- options = options || {};
- if (!id) {
- id = ++$.uuid;
- $.data[id] = pullRefreshApi = new PullRefresh(self, options);
- self.setAttribute('data-pullrefresh', id);
- } else {
- pullRefreshApi = $.data[id];
- }
- if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
- pullRefreshApi.pulldownLoading(options.down.autoY);
- } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
- pullRefreshApi.pullupLoading();
- }
- //暂不提供这种调用方式吧
- // if (typeof options === 'string') {
- // var methodValue = pullRefreshApi[options].apply(pullRefreshApi, $.slice.call(arguments, 1));
- // if (methodValue !== undefined) {
- // return methodValue;
- // }
- // }
- return pullRefreshApi;
- }
- };
- })(mui, window, document);
- /**
- * snap 重构
- * @param {Object} $
- * @param {Object} window
- */
- (function($, window) {
- var CLASS_SLIDER = 'mui-slider';
- var CLASS_SLIDER_GROUP = 'mui-slider-group';
- var CLASS_SLIDER_LOOP = 'mui-slider-loop';
- var CLASS_SLIDER_INDICATOR = 'mui-slider-indicator';
- var CLASS_ACTION_PREVIOUS = 'mui-action-previous';
- var CLASS_ACTION_NEXT = 'mui-action-next';
- var CLASS_SLIDER_ITEM = 'mui-slider-item';
- var CLASS_ACTIVE = 'mui-active';
- var SELECTOR_SLIDER_ITEM = '.' + CLASS_SLIDER_ITEM;
- var SELECTOR_SLIDER_INDICATOR = '.' + CLASS_SLIDER_INDICATOR;
- var SELECTOR_SLIDER_PROGRESS_BAR = '.mui-slider-progress-bar';
- var Slider = $.Slider = $.Scroll.extend({
- init: function(element, options) {
- this._super(element, $.extend(true, {
- fingers: 1,
- interval: 0, //设置为0,则不定时轮播
- scrollY: false,
- scrollX: true,
- indicators: false,
- scrollTime: 1000,
- startX: false,
- slideTime: 0, //滑动动画时间
- snap: SELECTOR_SLIDER_ITEM
- }, options));
- if (this.options.startX) {
- // $.trigger(this.wrapper, 'scrollend', this);
- }
- },
- _init: function() {
- this._reInit();
- if (this.scroller) {
- this.scrollerStyle = this.scroller.style;
- this.progressBar = this.wrapper.querySelector(SELECTOR_SLIDER_PROGRESS_BAR);
- if (this.progressBar) {
- this.progressBarWidth = this.progressBar.offsetWidth;
- this.progressBarStyle = this.progressBar.style;
- }
- //忘记这个代码是干什么的了?
- // this.x = this._getScroll();
- // if (this.options.startX === false) {
- // this.options.startX = this.x;
- // }
- //根据active修正startX
- this._super();
- this._initTimer();
- }
- },
- _triggerSlide: function() {
- var self = this;
- self.isInTransition = false;
- var page = self.currentPage;
- self.slideNumber = self._fixedSlideNumber();
- if (self.loop) {
- if (self.slideNumber === 0) {
- self.setTranslate(self.pages[1][0].x, 0);
- } else if (self.slideNumber === self.itemLength - 3) {
- self.setTranslate(self.pages[self.itemLength - 2][0].x, 0);
- }
- }
- if (self.lastSlideNumber != self.slideNumber) {
- self.lastSlideNumber = self.slideNumber;
- self.lastPage = self.currentPage;
- $.trigger(self.wrapper, 'slide', {
- slideNumber: self.slideNumber
- });
- }
- self._initTimer();
- },
- _handleSlide: function(e) {
- var self = this;
- if (e.target !== self.wrapper) {
- return;
- }
- var detail = e.detail;
- detail.slideNumber = detail.slideNumber || 0;
- var temps = self.scroller.querySelectorAll(SELECTOR_SLIDER_ITEM);
- var items = [];
- for (var i = 0, len = temps.length; i < len; i++) {
- var item = temps[i];
- if (item.parentNode === self.scroller) {
- items.push(item);
- }
- }
- var _slideNumber = detail.slideNumber;
- if (self.loop) {
- _slideNumber += 1;
- }
- if (!self.wrapper.classList.contains('mui-segmented-control')) {
- for (var i = 0, len = items.length; i < len; i++) {
- var item = items[i];
- if (item.parentNode === self.scroller) {
- if (i === _slideNumber) {
- item.classList.add(CLASS_ACTIVE);
- } else {
- item.classList.remove(CLASS_ACTIVE);
- }
- }
- }
- }
- var indicatorWrap = self.wrapper.querySelector('.mui-slider-indicator');
- if (indicatorWrap) {
- if (indicatorWrap.getAttribute('data-scroll')) { //scroll
- $(indicatorWrap).scroll().gotoPage(detail.slideNumber);
- }
- var indicators = indicatorWrap.querySelectorAll('.mui-indicator');
- if (indicators.length > 0) { //图片轮播
- for (var i = 0, len = indicators.length; i < len; i++) {
- indicators[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
- }
- } else {
- var number = indicatorWrap.querySelector('.mui-number span');
- if (number) { //图文表格
- number.innerText = (detail.slideNumber + 1);
- } else { //segmented controls
- var controlItems = indicatorWrap.querySelectorAll('.mui-control-item');
- for (var i = 0, len = controlItems.length; i < len; i++) {
- controlItems[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
- }
- }
- }
- }
- e.stopPropagation();
- },
- _handleTabShow: function(e) {
- var self = this;
- self.gotoItem((e.detail.tabNumber || 0), self.options.slideTime);
- },
- _handleIndicatorTap: function(event) {
- var self = this;
- var target = event.target;
- if (target.classList.contains(CLASS_ACTION_PREVIOUS) || target.classList.contains(CLASS_ACTION_NEXT)) {
- self[target.classList.contains(CLASS_ACTION_PREVIOUS) ? 'prevItem' : 'nextItem']();
- event.stopPropagation();
- }
- },
- _initEvent: function(detach) {
- var self = this;
- self._super(detach);
- var action = detach ? 'removeEventListener' : 'addEventListener';
- self.wrapper[action]('slide', this);
- self.wrapper[action]($.eventName('shown', 'tab'), this);
- },
- handleEvent: function(e) {
- this._super(e);
- switch (e.type) {
- case 'slide':
- this._handleSlide(e);
- break;
- case $.eventName('shown', 'tab'):
- if (~this.snaps.indexOf(e.target)) { //避免嵌套监听错误的tab show
- this._handleTabShow(e);
- }
- break;
- }
- },
- _scrollend: function(e) {
- this._super(e);
- this._triggerSlide(e);
- },
- _drag: function(e) {
- this._super(e);
- var direction = e.detail.direction;
- if (direction === 'left' || direction === 'right') {
- //拖拽期间取消定时
- var slidershowTimer = this.wrapper.getAttribute('data-slidershowTimer');
- slidershowTimer && window.clearTimeout(slidershowTimer);
- e.stopPropagation();
- }
- },
- _initTimer: function() {
- var self = this;
- var slider = self.wrapper;
- var interval = self.options.interval;
- var slidershowTimer = slider.getAttribute('data-slidershowTimer');
- slidershowTimer && window.clearTimeout(slidershowTimer);
- if (interval) {
- slidershowTimer = window.setTimeout(function() {
- if (!slider) {
- return;
- }
- //仅slider显示状态进行自动轮播
- if (!!(slider.offsetWidth || slider.offsetHeight)) {
- self.nextItem(true);
- //下一个
- }
- self._initTimer();
- }, interval);
- slider.setAttribute('data-slidershowTimer', slidershowTimer);
- }
- },
- _fixedSlideNumber: function(page) {
- page = page || this.currentPage;
- var slideNumber = page.pageX;
- if (this.loop) {
- if (page.pageX === 0) {
- slideNumber = this.itemLength - 3;
- } else if (page.pageX === (this.itemLength - 1)) {
- slideNumber = 0;
- } else {
- slideNumber = page.pageX - 1;
- }
- }
- return slideNumber;
- },
- _reLayout: function() {
- this.hasHorizontalScroll = true;
- this.loop = this.scroller.classList.contains(CLASS_SLIDER_LOOP);
- this._super();
- },
- _getScroll: function() {
- var result = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
- return result ? result.x : 0;
- },
- _transitionEnd: function(e) {
- if (e.target !== this.scroller || !this.isInTransition) {
- return;
- }
- this._transitionTime();
- this.isInTransition = false;
- $.trigger(this.wrapper, 'scrollend', this);
- },
- _flick: function(e) {
- if (!this.moved) { //无moved
- return;
- }
- var detail = e.detail;
- var direction = detail.direction;
- this._clearRequestAnimationFrame();
- this.isInTransition = true;
- // if (direction === 'up' || direction === 'down') {
- // this.resetPosition(this.options.bounceTime);
- // return;
- // }
- if (e.type === 'flick') {
- if (detail.deltaTime < 200) { //flick,太容易触发,额外校验一下deltaTime
- this.x = this._getPage((this.slideNumber + (direction === 'right' ? -1 : 1)), true).x;
- }
- this.resetPosition(this.options.bounceTime);
- } else if (e.type === 'dragend' && !detail.flick) {
- this.resetPosition(this.options.bounceTime);
- }
- e.stopPropagation();
- },
- _initSnap: function() {
- this.scrollerWidth = this.itemLength * this.scrollerWidth;
- this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
- this._super();
- if (!this.currentPage.x) {
- //当slider处于隐藏状态时,导致snap计算是错误的,临时先这么判断一下,后续要考虑解决所有scroll在隐藏状态下初始化属性不正确的问题
- var currentPage = this.pages[this.loop ? 1 : 0];
- currentPage = currentPage || this.pages[0];
- if (!currentPage) {
- return;
- }
- this.currentPage = currentPage[0];
- this.slideNumber = 0;
- this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? 0 : this.lastSlideNumber;
- } else {
- this.slideNumber = this._fixedSlideNumber();
- this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? this.slideNumber : this.lastSlideNumber;
- }
- this.options.startX = this.currentPage.x || 0;
- },
- _getSnapX: function(offsetLeft) {
- return Math.max(-offsetLeft, this.maxScrollX);
- },
- _getPage: function(slideNumber, isFlick) {
- if (this.loop) {
- if (slideNumber > (this.itemLength - (isFlick ? 2 : 3))) {
- slideNumber = 1;
- time = 0;
- } else if (slideNumber < (isFlick ? -1 : 0)) {
- slideNumber = this.itemLength - 2;
- time = 0;
- } else {
- slideNumber += 1;
- }
- } else {
- if (!isFlick) {
- if (slideNumber > (this.itemLength - 1)) {
- slideNumber = 0;
- time = 0;
- } else if (slideNumber < 0) {
- slideNumber = this.itemLength - 1;
- time = 0;
- }
- }
- slideNumber = Math.min(Math.max(0, slideNumber), this.itemLength - 1);
- }
- return this.pages[slideNumber][0];
- },
- _gotoItem: function(slideNumber, time) {
- this.currentPage = this._getPage(slideNumber, true); //此处传true。可保证程序切换时,动画与人手操作一致(第一张,最后一张的切换动画)
- this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
- if (time === 0) {
- $.trigger(this.wrapper, 'scrollend', this);
- }
- },
- //API
- setTranslate: function(x, y) {
- this._super(x, y);
- var progressBar = this.progressBar;
- if (progressBar) {
- this.progressBarStyle.webkitTransform = this._getTranslateStr((-x * (this.progressBarWidth / this.wrapperWidth)), 0);
- }
- },
- resetPosition: function(time) {
- time = time || 0;
- if (this.x > 0) {
- this.x = 0;
- } else if (this.x < this.maxScrollX) {
- this.x = this.maxScrollX;
- }
- this.currentPage = this._nearestSnap(this.x);
- this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
- return true;
- },
- gotoItem: function(slideNumber, time) {
- this._gotoItem(slideNumber, typeof time === 'undefined' ? this.options.scrollTime : time);
- },
- nextItem: function() {
- this._gotoItem(this.slideNumber + 1, this.options.scrollTime);
- },
- prevItem: function() {
- this._gotoItem(this.slideNumber - 1, this.options.scrollTime);
- },
- getSlideNumber: function() {
- return this.slideNumber || 0;
- },
- _reInit: function() {
- var groups = this.wrapper.querySelectorAll('.' + CLASS_SLIDER_GROUP);
- for (var i = 0, len = groups.length; i < len; i++) {
- if (groups[i].parentNode === this.wrapper) {
- this.scroller = groups[i];
- break;
- }
- }
- this.scrollerStyle = this.scroller && this.scroller.style;
- if (this.progressBar) {
- this.progressBarWidth = this.progressBar.offsetWidth;
- this.progressBarStyle = this.progressBar.style;
- }
- },
- refresh: function(options) {
- if (options) {
- $.extend(this.options, options);
- this._super();
- this._initTimer();
- } else {
- this._super();
- }
- },
- destroy: function() {
- this._initEvent(true); //detach
- delete $.data[this.wrapper.getAttribute('data-slider')];
- this.wrapper.setAttribute('data-slider', '');
- }
- });
- $.fn.slider = function(options) {
- var slider = null;
- this.each(function() {
- var sliderElement = this;
- if (!this.classList.contains(CLASS_SLIDER)) {
- sliderElement = this.querySelector('.' + CLASS_SLIDER);
- }
- if (sliderElement && sliderElement.querySelector(SELECTOR_SLIDER_ITEM)) {
- var id = sliderElement.getAttribute('data-slider');
- if (!id) {
- id = ++$.uuid;
- $.data[id] = slider = new Slider(sliderElement, options);
- sliderElement.setAttribute('data-slider', id);
- } else {
- slider = $.data[id];
- if (slider && options) {
- slider.refresh(options);
- }
- }
- }
- });
- return slider;
- };
- $.ready(function() {
- // setTimeout(function() {
- $('.mui-slider').slider();
- $('.mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control').scroll({
- scrollY: false,
- scrollX: true,
- indicators: false,
- snap: '.mui-control-item'
- });
- // }, 500); //临时处理slider宽度计算不正确的问题(初步确认是scrollbar导致的)
- });
- })(mui, window);
- /**
- * pullRefresh 5+
- * @param {type} $
- * @returns {undefined}
- */
- (function($, document) {
- if (!($.os.plus)) { //仅在5+android支持多webview的使用
- return;
- }
- $.plusReady(function() {
- if (window.__NWin_Enable__ === false) { //不支持多webview,则不用5+下拉刷新
- return;
- }
- var CLASS_PLUS_PULLREFRESH = 'mui-plus-pullrefresh';
- var CLASS_VISIBILITY = 'mui-visibility';
- var CLASS_HIDDEN = 'mui-hidden';
- var CLASS_BLOCK = 'mui-block';
- var CLASS_PULL_CAPTION = 'mui-pull-caption';
- var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
- var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
- var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
- var PlusPullRefresh = $.Class.extend({
- init: function(element, options) {
- this.element = element;
- this.options = options;
- this.wrapper = this.scroller = element;
- this._init();
- this._initPulldownRefreshEvent();
- },
- _init: function() {
- var self = this;
- //document.addEventListener('plusscrollbottom', this);
- window.addEventListener('dragup', self);
- document.addEventListener("plusscrollbottom", self);
- self.scrollInterval = window.setInterval(function() {
- if (self.isScroll && !self.loading) {
- if (window.pageYOffset + window.innerHeight + 10 >= document.documentElement.scrollHeight) {
- self.isScroll = false; //放在这里是因为快速滚动的话,有可能检测时,还没到底,所以只要有滚动,没到底之前一直检测高度变化
- if (self.bottomPocket) {
- self.pullupLoading();
- }
- }
- }
- }, 100);
- },
- _initPulldownRefreshEvent: function() {
- var self = this;
- $.plusReady(function() {
- if (self.options.down.style == "circle") {
- //单webview、原生转圈
- self.options.webview = plus.webview.currentWebview();
- self.options.webview.setPullToRefresh({
- support: true,
- color: self.options.down.color || '#2BD009',
- height: self.options.down.height || '50px',
- range: self.options.down.range || '100px',
- style: 'circle',
- offset: self.options.down.offset || '0px'
- }, function() {
- self.options.down.callback();
- });
- } else if (self.topPocket && self.options.webviewId) {
- var webview = plus.webview.getWebviewById(self.options.webviewId); //子窗口
- if (!webview) {
- return;
- }
- self.options.webview = webview;
- var downOptions = self.options.down;
- var height = downOptions.height;
- webview.addEventListener('close', function() {
- var attrWebviewId = self.options.webviewId && self.options.webviewId.replace(/\//g, "_"); //替换所有"/"
- self.element.removeAttribute('data-pullrefresh-plus-' + attrWebviewId);
- });
- webview.addEventListener("dragBounce", function(e) {
- if (!self.pulldown) {
- self._initPulldownRefresh();
- } else {
- self.pullPocket.classList.add(CLASS_BLOCK);
- }
- switch (e.status) {
- case "beforeChangeOffset": //下拉可刷新状态
- self._setCaption(downOptions.contentdown);
- break;
- case "afterChangeOffset": //松开可刷新状态
- self._setCaption(downOptions.contentover);
- break;
- case "dragEndAfterChangeOffset": //正在刷新状态
- //执行下拉刷新所在webview的回调函数
- webview.evalJS("window.mui&&mui.options.pullRefresh.down.callback()");
- self._setCaption(downOptions.contentrefresh);
- break;
- default:
- break;
- }
- }, false);
- webview.setBounce({
- position: {
- top: height * 2 + 'px'
- },
- changeoffset: {
- top: height + 'px'
- }
- });
- }
- });
- },
- handleEvent: function(e) {
- var self = this;
- if (self.stopped) {
- return;
- }
- self.isScroll = false;
- if (e.type === 'dragup' || e.type === 'plusscrollbottom') {
- self.isScroll = true;
- setTimeout(function() {
- self.isScroll = false;
- }, 1000);
- }
- }
- }).extend($.extend({
- setStopped: function(stopped) { //该方法是子页面调用的
- this.stopped = !!stopped;
- // TODO 此处需要设置当前webview的bounce为none,目前5+有BUG
- if (this.stopped) {
- this.disablePullupToRefresh();
- this.disablePulldownToRefresh();
- } else {
- this.enablePullupToRefresh();
- this.enablePulldownToRefresh();
- }
- },
- beginPulldown: function() {
- var self = this;
- $.plusReady(function() {
- //这里延时的目的是为了保证下拉刷新组件初始化完成,后续应该做成有状态的
- setTimeout(function() {
- if (self.options.down.style == "circle") { //单webview下拉刷新
- plus.webview.currentWebview().beginPullToRefresh();
- } else { //双webview模式
- var webview = self.options.webview;
- if (webview) {
- webview.setBounce({
- offset: {
- top: self.options.down.height + "px"
- }
- });
- }
- }
- }, 15);
- }.bind(this));
- },
- pulldownLoading: function() { //该方法是子页面调用的,兼容老的历史API
- this.beginPulldown();
- },
- _pulldownLoading: function() { //该方法是父页面调用的
- var self = this;
- $.plusReady(function() {
- var childWebview = plus.webview.getWebviewById(self.options.webviewId);
- childWebview && childWebview.setBounce({
- offset: {
- top: self.options.down.height + "px"
- }
- });
- });
- },
- endPulldown: function() {
- var _wv = plus.webview.currentWebview();
- //双webview的下拉刷新,需要修改父窗口提示信息
- if (_wv.parent() && this.options.down.style !== "circle") {
- _wv.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify({
- webviewId: _wv.id
- }) + "')._endPulldownToRefresh()");
- } else {
- _wv.endPullToRefresh();
- }
- },
- endPulldownToRefresh: function() { //该方法是子页面调用的,兼容老的历史API
- this.endPulldown();
- },
- _endPulldownToRefresh: function() { //该方法是父页面调用的
- var self = this;
- if (self.topPocket && self.options.webview) {
- self.options.webview.endPullToRefresh(); //下拉刷新所在webview回弹
- self.loading = false;
- self._setCaption(self.options.down.contentdown, true);
- setTimeout(function() {
- self.loading || self.topPocket.classList.remove(CLASS_BLOCK);
- }, 350);
- }
- },
- beginPullup: function(callback) { //开始上拉加载
- var self = this;
- if (self.isLoading) return;
- self.isLoading = true;
- if (self.pulldown !== false) {
- self._initPullupRefresh();
- } else {
- this.pullPocket.classList.add(CLASS_BLOCK);
- }
- setTimeout(function() {
- self.pullLoading.classList.add(CLASS_VISIBILITY);
- self.pullLoading.classList.remove(CLASS_HIDDEN);
- self.pullCaption.innerHTML = ''; //修正5+里边第一次加载时,文字显示的bug(还会显示出来个“多”,猜测应该是渲染问题导致的)
- self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH;
- self.pullCaption.innerHTML = self.options.up.contentrefresh;
- callback = callback || self.options.up.callback;
- callback && callback.call(self);
- }, 300);
- },
- pullupLoading: function(callback) { //兼容老的API
- this.beginPullup(callback);
- },
- endPullup: function(finished) { //上拉加载结束
- var self = this;
- if (self.pullLoading) {
- self.pullLoading.classList.remove(CLASS_VISIBILITY);
- self.pullLoading.classList.add(CLASS_HIDDEN);
- self.isLoading = false;
- if (finished) {
- self.finished = true;
- self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
- self.pullCaption.innerHTML = self.options.up.contentnomore;
- //取消5+的plusscrollbottom事件
- document.removeEventListener('plusscrollbottom', self);
- window.removeEventListener('dragup', self);
- } else { //初始化时隐藏,后续不再隐藏
- self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
- self.pullCaption.innerHTML = self.options.up.contentdown;
- }
- }
- },
- endPullupToRefresh: function(finished) { //上拉加载结束,兼容老的API
- this.endPullup(finished);
- },
- disablePulldownToRefresh: function() {
- var webview = plus.webview.currentWebview();
- if (this.options.down.style && this.options.down.style == 'circle') { // 单webview模式禁止原生下拉刷新
- this.options.webview.setPullToRefresh({
- support: false,
- style: 'circle'
- });
- } else { // 双webview模式禁止下拉刷新
- webview.setStyle({
- bounce: 'none'
- });
- webview.setBounce({
- position: {
- top: 'none'
- }
- });
- }
- },
- enablePulldownToRefresh: function() {
- var self = this,
- webview = plus.webview.currentWebview(),
- height = this.options.down.height;
- // 单webview模式禁止原生下拉刷新
- if (this.options.down.style && this.options.down.style == 'circle') {
- webview.setPullToRefresh({
- support: true,
- height: height || '50px',
- range: self.options.down.range || '100px',
- style: 'circle',
- offset: self.options.down.offset || '0px'
- });
- } else { // 重新初始化双webview模式下拉刷新
- webview.setStyle({
- bounce: 'vertical'
- });
- webview.setBounce({
- position: {
- top: height * 2 + 'px'
- },
- changeoffset: {
- top: height + 'px'
- }
- });
- }
- },
- disablePullupToRefresh: function() {
- this._initPullupRefresh();
- this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
- window.removeEventListener('dragup', this);
- },
- enablePullupToRefresh: function() {
- this._initPullupRefresh();
- this.bottomPocket.classList.remove(CLASS_HIDDEN);
- this.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
- this.pullCaption.innerHTML = this.options.up.contentdown;
- document.addEventListener("plusscrollbottom", this);
- window.addEventListener('dragup', this);
- },
- scrollTo: function(x, y, time) {
- $.scrollTo(y, time);
- },
- scrollToBottom: function(time) {
- $.scrollTo(document.documentElement.scrollHeight, time);
- },
- refresh: function(isReset) {
- if (isReset && this.finished) {
- this.enablePullupToRefresh();
- this.finished = false;
- }
- }
- }, $.PullRefresh));
- //override h5 pullRefresh
- $.fn.pullRefresh_native = function(options) {
- var self;
- if (this.length === 0) {
- self = document.createElement('div');
- self.className = 'mui-content';
- document.body.appendChild(self);
- } else {
- self = this[0];
- }
- var args = options;
- //一个父需要支持多个子下拉刷新
- options = options || {}
- if (typeof options === 'string') {
- options = $.parseJSON(options);
- };
- !options.webviewId && (options.webviewId = (plus.webview.currentWebview().id || plus.webview.currentWebview().getURL()));
- var pullRefreshApi = null;
- var attrWebviewId = options.webviewId && options.webviewId.replace(/\//g, "_"); //替换所有"/"
- var id = self.getAttribute('data-pullrefresh-plus-' + attrWebviewId);
- if (!id && typeof args === 'undefined') {
- return false;
- }
- if (!id) { //避免重复初始化5+ pullrefresh
- id = ++$.uuid;
- self.setAttribute('data-pullrefresh-plus-' + attrWebviewId, id);
- document.body.classList.add(CLASS_PLUS_PULLREFRESH);
- $.data[id] = pullRefreshApi = new PlusPullRefresh(self, options);
- } else {
- pullRefreshApi = $.data[id];
- }
- if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
- //pullRefreshApi._pulldownLoading(); //parent webview
- pullRefreshApi.beginPulldown();
- } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
- pullRefreshApi.beginPullup();
- }
- return pullRefreshApi;
- };
- });
- })(mui, document);
- /**
- * off-canvas
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @param {type} action
- * @returns {undefined}
- */
- (function($, window, document, name) {
- var CLASS_OFF_CANVAS_LEFT = 'mui-off-canvas-left';
- var CLASS_OFF_CANVAS_RIGHT = 'mui-off-canvas-right';
- var CLASS_ACTION_BACKDROP = 'mui-off-canvas-backdrop';
- var CLASS_OFF_CANVAS_WRAP = 'mui-off-canvas-wrap';
- var CLASS_SLIDE_IN = 'mui-slide-in';
- var CLASS_ACTIVE = 'mui-active';
- var CLASS_TRANSITIONING = 'mui-transitioning';
- var SELECTOR_INNER_WRAP = '.mui-inner-wrap';
- var OffCanvas = $.Class.extend({
- init: function(element, options) {
- this.wrapper = this.element = element;
- this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
- this.classList = this.wrapper.classList;
- if (this.scroller) {
- this.options = $.extend(true, {
- dragThresholdX: 10,
- scale: 0.8,
- opacity: 0.1,
- preventDefaultException: {
- tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
- },
- }, options);
- document.body.classList.add('mui-fullscreen'); //fullscreen
- this.refresh();
- this.initEvent();
- }
- },
- _preventDefaultException: function(el, exceptions) {
- for (var i in exceptions) {
- if (exceptions[i].test(el[i])) {
- return true;
- }
- }
- return false;
- },
- refresh: function(offCanvas) {
- // offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE);
- this.slideIn = this.classList.contains(CLASS_SLIDE_IN);
- this.scalable = this.classList.contains('mui-scalable') && !this.slideIn;
- this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
- // !offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING);
- // !offCanvas && this.scroller.setAttribute('style', '');
- this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT);
- this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT);
- if (offCanvas) {
- if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
- this.offCanvasLeft = offCanvas;
- } else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
- this.offCanvasRight = offCanvas;
- }
- } else {
- this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT);
- this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT);
- }
- this.offCanvasRightWidth = this.offCanvasLeftWidth = 0;
- this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false;
- if (this.offCanvasRight) {
- this.offCanvasRightWidth = this.offCanvasRight.offsetWidth;
- this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper);
- // this.offCanvasRight.classList.remove(CLASS_TRANSITIONING);
- // this.offCanvasRight.classList.remove(CLASS_ACTIVE);
- // this.offCanvasRight.setAttribute('style', '');
- }
- if (this.offCanvasLeft) {
- this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth;
- this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper);
- // this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING);
- // this.offCanvasLeft.classList.remove(CLASS_ACTIVE);
- // this.offCanvasLeft.setAttribute('style', '');
- }
- this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP);
- this.options.dragThresholdX = this.options.dragThresholdX || 10;
- this.visible = false;
- this.startX = null;
- this.lastX = null;
- this.offsetX = null;
- this.lastTranslateX = null;
- },
- handleEvent: function(e) {
- switch (e.type) {
- case $.EVENT_START:
- e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
- break;
- case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况
- if (e.target === this.scroller) {
- this._dispatchEvent();
- }
- break;
- case 'drag':
- var detail = e.detail;
- if (!this.startX) {
- this.startX = detail.center.x;
- this.lastX = this.startX;
- } else {
- this.lastX = detail.center.x;
- }
- if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) {
- if (this.slideIn) {
- this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
- if (this.classList.contains(CLASS_ACTIVE)) {
- if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) {
- this.offCanvas = this.offCanvasRight;
- this.offCanvasWidth = this.offCanvasRightWidth;
- } else {
- this.offCanvas = this.offCanvasLeft;
- this.offCanvasWidth = this.offCanvasLeftWidth;
- }
- } else {
- if (detail.direction === 'left' && this.offCanvasRight) {
- this.offCanvas = this.offCanvasRight;
- this.offCanvasWidth = this.offCanvasRightWidth;
- } else if (detail.direction === 'right' && this.offCanvasLeft) {
- this.offCanvas = this.offCanvasLeft;
- this.offCanvasWidth = this.offCanvasLeftWidth;
- } else {
- this.scroller = null;
- }
- }
- } else {
- if (this.classList.contains(CLASS_ACTIVE)) {
- if (detail.direction === 'left') {
- this.offCanvas = this.offCanvasLeft;
- this.offCanvasWidth = this.offCanvasLeftWidth;
- } else {
- this.offCanvas = this.offCanvasRight;
- this.offCanvasWidth = this.offCanvasRightWidth;
- }
- } else {
- if (detail.direction === 'right') {
- this.offCanvas = this.offCanvasLeft;
- this.offCanvasWidth = this.offCanvasLeftWidth;
- } else {
- this.offCanvas = this.offCanvasRight;
- this.offCanvasWidth = this.offCanvasRightWidth;
- }
- }
- }
- if (this.offCanvas && this.scroller) {
- this.startX = this.lastX;
- this.isDragging = true;
- $.gestures.session.lockDirection = true; //锁定方向
- $.gestures.session.startDirection = detail.direction;
- this.offCanvas.classList.remove(CLASS_TRANSITIONING);
- this.scroller.classList.remove(CLASS_TRANSITIONING);
- this.offsetX = this.getTranslateX();
- this._initOffCanvasVisible();
- }
- }
- if (this.isDragging) {
- this.updateTranslate(this.offsetX + (this.lastX - this.startX));
- detail.gesture.preventDefault();
- e.stopPropagation();
- }
- break;
- case 'dragend':
- if (this.isDragging) {
- var detail = e.detail;
- var direction = detail.direction;
- this.isDragging = false;
- this.offCanvas.classList.add(CLASS_TRANSITIONING);
- this.scroller.classList.add(CLASS_TRANSITIONING);
- var ratio = 0;
- var x = this.getTranslateX();
- if (!this.slideIn) {
- if (x >= 0) {
- ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
- } else {
- ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
- }
- if (ratio === 0) {
- this.openPercentage(0);
- this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch
- return;
- }
- if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开
- this.openPercentage(100);
- } else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭
- this.openPercentage(0);
- } else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭
- this.openPercentage(0);
- } else if (direction === 'right' && ratio < 0.5) { //右滑还原打开
- this.openPercentage(-100);
- } else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开
- this.openPercentage(-100);
- } else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭
- this.openPercentage(0);
- } else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭
- this.openPercentage(0);
- } else if (direction === 'left' && ratio > 0.5) { //左滑还原打开
- this.openPercentage(100);
- } else { //默认关闭
- this.openPercentage(0);
- }
- if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch
- this._dispatchEvent();
- }
- } else {
- if (x >= 0) {
- ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
- } else {
- ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
- }
- if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开
- this.openPercentage(100);
- } else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭
- this.openPercentage(0);
- } else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭
- this.openPercentage(0);
- } else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开
- this.openPercentage(-100);
- } else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开
- this.openPercentage(-100);
- } else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭
- this.openPercentage(0);
- } else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭
- this.openPercentage(0);
- } else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开
- this.openPercentage(100);
- } else {
- this.openPercentage(0);
- }
- if (ratio === 1 || ratio === -1 || ratio === 0) {
- this._dispatchEvent();
- return;
- }
- }
- }
- break;
- }
- },
- _dispatchEvent: function() {
- if (this.classList.contains(CLASS_ACTIVE)) {
- $.trigger(this.wrapper, 'shown', this);
- } else {
- $.trigger(this.wrapper, 'hidden', this);
- }
- },
- _initOffCanvasVisible: function() {
- if (!this.visible) {
- this.visible = true;
- if (this.offCanvasLeft) {
- this.offCanvasLeft.style.visibility = 'visible';
- }
- if (this.offCanvasRight) {
- this.offCanvasRight.style.visibility = 'visible';
- }
- }
- },
- initEvent: function() {
- var self = this;
- if (self.backdrop) {
- self.backdrop.addEventListener('tap', function(e) {
- self.close();
- e.detail.gesture.preventDefault();
- });
- }
- if (this.classList.contains('mui-draggable')) {
- this.wrapper.addEventListener($.EVENT_START, this); //临时处理
- this.wrapper.addEventListener('drag', this);
- this.wrapper.addEventListener('dragend', this);
- }
- this.wrapper.addEventListener('webkitTransitionEnd', this);
- },
- openPercentage: function(percentage) {
- var p = percentage / 100;
- if (!this.slideIn) {
- if (this.offCanvasLeft && percentage >= 0) {
- this.updateTranslate(this.offCanvasLeftWidth * p);
- this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
- } else if (this.offCanvasRight && percentage <= 0) {
- this.updateTranslate(this.offCanvasRightWidth * p);
- this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
- }
- this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
- } else {
- if (this.offCanvasLeft && percentage >= 0) {
- p = p === 0 ? -1 : 0;
- this.updateTranslate(this.offCanvasLeftWidth * p);
- this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
- } else if (this.offCanvasRight && percentage <= 0) {
- p = p === 0 ? 1 : 0;
- this.updateTranslate(this.offCanvasRightWidth * p);
- this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
- }
- this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
- }
- },
- updateTranslate: function(x) {
- if (x !== this.lastTranslateX) {
- if (!this.slideIn) {
- if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) {
- this.setTranslateX(0);
- return;
- }
- if (this.leftShowing && x > this.offCanvasLeftWidth) {
- this.setTranslateX(this.offCanvasLeftWidth);
- return;
- }
- if (this.rightShowing && x < -this.offCanvasRightWidth) {
- this.setTranslateX(-this.offCanvasRightWidth);
- return;
- }
- this.setTranslateX(x);
- if (x >= 0) {
- this.leftShowing = true;
- this.rightShowing = false;
- if (x > 0) {
- if (this.offCanvasLeft) {
- $.each(this.offCanvasLefts, function(index, offCanvas) {
- if (offCanvas === this.offCanvasLeft) {
- this.offCanvasLeft.style.zIndex = 0;
- } else {
- offCanvas.style.zIndex = -1;
- }
- }.bind(this));
- }
- if (this.offCanvasRight) {
- this.offCanvasRight.style.zIndex = -1;
- }
- }
- } else {
- this.rightShowing = true;
- this.leftShowing = false;
- if (this.offCanvasRight) {
- $.each(this.offCanvasRights, function(index, offCanvas) {
- if (offCanvas === this.offCanvasRight) {
- offCanvas.style.zIndex = 0;
- } else {
- offCanvas.style.zIndex = -1;
- }
- }.bind(this));
- }
- if (this.offCanvasLeft) {
- this.offCanvasLeft.style.zIndex = -1;
- }
- }
- } else {
- if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
- if (x < 0) {
- this.setTranslateX(0);
- return;
- }
- if (x > this.offCanvasRightWidth) {
- this.setTranslateX(this.offCanvasRightWidth);
- return;
- }
- } else {
- if (x > 0) {
- this.setTranslateX(0);
- return;
- }
- if (x < -this.offCanvasLeftWidth) {
- this.setTranslateX(-this.offCanvasLeftWidth);
- return;
- }
- }
- this.setTranslateX(x);
- }
- this.lastTranslateX = x;
- }
- },
- setTranslateX: $.animationFrame(function(x) {
- if (this.scroller) {
- if (this.scalable && this.offCanvas.parentNode === this.wrapper) {
- var percent = Math.abs(x) / this.offCanvasWidth;
- var zoomOutScale = 1 - (1 - this.options.scale) * percent;
- var zoomInScale = this.options.scale + (1 - this.options.scale) * percent;
- var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent;
- var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent;
- if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
- this.offCanvas.style.webkitTransformOrigin = '-100%';
- this.scroller.style.webkitTransformOrigin = 'left';
- } else {
- this.offCanvas.style.webkitTransformOrigin = '200%';
- this.scroller.style.webkitTransformOrigin = 'right';
- }
- this.offCanvas.style.opacity = zoomInOpacity;
- this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')';
- this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')';
- } else {
- if (this.slideIn) {
- this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
- } else {
- this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
- }
- }
- }
- }),
- getTranslateX: function() {
- if (this.offCanvas) {
- var scroller = this.slideIn ? this.offCanvas : this.scroller;
- var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform'));
- return (result && result.x) || 0;
- }
- return 0;
- },
- isShown: function(direction) {
- var shown = false;
- if (!this.slideIn) {
- var x = this.getTranslateX();
- if (direction === 'right') {
- shown = this.classList.contains(CLASS_ACTIVE) && x < 0;
- } else if (direction === 'left') {
- shown = this.classList.contains(CLASS_ACTIVE) && x > 0;
- } else {
- shown = this.classList.contains(CLASS_ACTIVE) && x !== 0;
- }
- } else {
- if (direction === 'left') {
- shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
- } else if (direction === 'right') {
- shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE);
- } else {
- shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE));
- }
- }
- return shown;
- },
- close: function() {
- this._initOffCanvasVisible();
- this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
- this.offCanvasWidth = this.offCanvas.offsetWidth;
- if (this.scroller) {
- this.offCanvas.offsetHeight;
- this.offCanvas.classList.add(CLASS_TRANSITIONING);
- this.scroller.classList.add(CLASS_TRANSITIONING);
- this.openPercentage(0);
- }
- },
- show: function(direction) {
- this._initOffCanvasVisible();
- if (this.isShown(direction)) {
- return false;
- }
- if (!direction) {
- direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left';
- }
- if (direction === 'right') {
- this.offCanvas = this.offCanvasRight;
- this.offCanvasWidth = this.offCanvasRightWidth;
- } else {
- this.offCanvas = this.offCanvasLeft;
- this.offCanvasWidth = this.offCanvasLeftWidth;
- }
- if (this.scroller) {
- this.offCanvas.offsetHeight;
- this.offCanvas.classList.add(CLASS_TRANSITIONING);
- this.scroller.classList.add(CLASS_TRANSITIONING);
- this.openPercentage(direction === 'left' ? 100 : -100);
- }
- return true;
- },
- toggle: function(directionOrOffCanvas) {
- var direction = directionOrOffCanvas;
- if (directionOrOffCanvas && directionOrOffCanvas.classList) {
- direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right';
- this.refresh(directionOrOffCanvas);
- }
- if (!this.show(direction)) {
- this.close();
- }
- }
- });
- //hash to offcanvas
- var findOffCanvasContainer = function(target) {
- parentNode = target.parentNode;
- if (parentNode) {
- if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
- return parentNode;
- } else {
- parentNode = parentNode.parentNode;
- if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
- return parentNode;
- }
- }
- }
- };
- var handle = function(event, target) {
- if (target.tagName === 'A' && target.hash) {
- var offcanvas = document.getElementById(target.hash.replace('#', ''));
- if (offcanvas) {
- var container = findOffCanvasContainer(offcanvas);
- if (container) {
- $.targets._container = container;
- return offcanvas;
- }
- }
- }
- return false;
- };
- $.registerTarget({
- name: name,
- index: 60,
- handle: handle,
- target: false,
- isReset: false,
- isContinue: true
- });
- window.addEventListener('tap', function(e) {
- if (!$.targets.offcanvas) {
- return;
- }
- //TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好
- var target = e.target;
- for (; target && target !== document; target = target.parentNode) {
- if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) {
- e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange
- $($.targets._container).offCanvas().toggle($.targets.offcanvas);
- $.targets.offcanvas = $.targets._container = null;
- break;
- }
- }
- });
- $.fn.offCanvas = function(options) {
- var offCanvasApis = [];
- this.each(function() {
- var offCanvasApi = null;
- var self = this;
- //hack old version
- if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
- self = findOffCanvasContainer(self);
- }
- var id = self.getAttribute('data-offCanvas');
- if (!id) {
- id = ++$.uuid;
- $.data[id] = offCanvasApi = new OffCanvas(self, options);
- self.setAttribute('data-offCanvas', id);
- } else {
- offCanvasApi = $.data[id];
- }
- if (options === 'show' || options === 'close' || options === 'toggle') {
- offCanvasApi.toggle();
- }
- offCanvasApis.push(offCanvasApi);
- });
- return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis;
- };
- $.ready(function() {
- $('.mui-off-canvas-wrap').offCanvas();
- });
- })(mui, window, document, 'offcanvas');
- /**
- * actions
- * @param {type} $
- * @param {type} name
- * @returns {undefined}
- */
- (function($, name) {
- var CLASS_ACTION = 'mui-action';
- var handle = function(event, target) {
- var className = target.className || '';
- if (typeof className !== 'string') { //svg className(SVGAnimatedString)
- className = '';
- }
- if (className && ~className.indexOf(CLASS_ACTION)) {
- if (target.classList.contains('mui-action-back')) {
- event.preventDefault();
- }
- return target;
- }
- return false;
- };
- $.registerTarget({
- name: name,
- index: 50,
- handle: handle,
- target: false,
- isContinue: true
- });
- })(mui, 'action');
- /**
- * Modals
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @param {type} name
- * @returns {undefined}
- */
- (function($, window, document, name) {
- var CLASS_MODAL = 'mui-modal';
- var handle = function(event, target) {
- if (target.tagName === 'A' && target.hash) {
- var modal = document.getElementById(target.hash.replace('#', ''));
- if (modal && modal.classList.contains(CLASS_MODAL)) {
- return modal;
- }
- }
- return false;
- };
- $.registerTarget({
- name: name,
- index: 50,
- handle: handle,
- target: false,
- isReset: false,
- isContinue: true
- });
- window.addEventListener('tap', function(event) {
- if ($.targets.modal) {
- event.detail.gesture.preventDefault(); //fixed hashchange
- $.targets.modal.classList.toggle('mui-active');
- }
- });
- })(mui, window, document, 'modal');
- /**
- * Popovers
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @param {type} name
- * @param {type} undefined
- * @returns {undefined}
- */
- (function($, window, document, name) {
- var CLASS_POPOVER = 'mui-popover';
- var CLASS_POPOVER_ARROW = 'mui-popover-arrow';
- var CLASS_ACTION_POPOVER = 'mui-popover-action';
- var CLASS_BACKDROP = 'mui-backdrop';
- var CLASS_BAR_POPOVER = 'mui-bar-popover';
- var CLASS_BAR_BACKDROP = 'mui-bar-backdrop';
- var CLASS_ACTION_BACKDROP = 'mui-backdrop-action';
- var CLASS_ACTIVE = 'mui-active';
- var CLASS_BOTTOM = 'mui-bottom';
- var handle = function(event, target) {
- if (target.tagName === 'A' && target.hash) {
- $.targets._popover = document.getElementById(target.hash.replace('#', ''));
- if ($.targets._popover && $.targets._popover.classList.contains(CLASS_POPOVER)) {
- return target;
- } else {
- $.targets._popover = null;
- }
- }
- return false;
- };
- $.registerTarget({
- name: name,
- index: 60,
- handle: handle,
- target: false,
- isReset: false,
- isContinue: true
- });
- var onPopoverShown = function(e) {
- this.removeEventListener('webkitTransitionEnd', onPopoverShown);
- this.addEventListener($.EVENT_MOVE, $.preventDefault);
- $.trigger(this, 'shown', this);
- }
- var onPopoverHidden = function(e) {
- setStyle(this, 'none');
- this.removeEventListener('webkitTransitionEnd', onPopoverHidden);
- this.removeEventListener($.EVENT_MOVE, $.preventDefault);
- $.trigger(this, 'hidden', this);
- };
- var backdrop = (function() {
- var element = document.createElement('div');
- element.classList.add(CLASS_BACKDROP);
- element.addEventListener($.EVENT_MOVE, $.preventDefault);
- element.addEventListener('tap', function(e) {
- var popover = $.targets._popover;
- if (popover) {
- popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
- popover.classList.remove(CLASS_ACTIVE);
- removeBackdrop(popover);
- }
- });
- return element;
- }());
- var removeBackdropTimer;
- var removeBackdrop = function(popover) {
- backdrop.setAttribute('style', 'opacity:0');
- $.targets.popover = $.targets._popover = null; //reset
- removeBackdropTimer = $.later(function() {
- if (!popover.classList.contains(CLASS_ACTIVE) && backdrop.parentNode && backdrop.parentNode === document.body) {
- document.body.removeChild(backdrop);
- }
- }, 350);
- };
- window.addEventListener('tap', function(e) {
- if (!$.targets.popover) {
- return;
- }
- var toggle = false;
- var target = e.target;
- for (; target && target !== document; target = target.parentNode) {
- if (target === $.targets.popover) {
- toggle = true;
- }
- }
- if (toggle) {
- e.detail.gesture.preventDefault(); //fixed hashchange
- togglePopover($.targets._popover, $.targets.popover);
- }
- });
- var togglePopover = function(popover, anchor, state) {
- if ((state === 'show' && popover.classList.contains(CLASS_ACTIVE)) || (state === 'hide' && !popover.classList.contains(CLASS_ACTIVE))) {
- return;
- }
- removeBackdropTimer && removeBackdropTimer.cancel(); //取消remove的timer
- //remove一遍,以免来回快速切换,导致webkitTransitionEnd不触发,无法remove
- popover.removeEventListener('webkitTransitionEnd', onPopoverShown);
- popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
- backdrop.classList.remove(CLASS_BAR_BACKDROP);
- backdrop.classList.remove(CLASS_ACTION_BACKDROP);
- var _popover = document.querySelector('.mui-popover.mui-active');
- if (_popover) {
- // _popover.setAttribute('style', '');
- _popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
- _popover.classList.remove(CLASS_ACTIVE);
- // _popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
- //同一个弹出则直接返回,解决同一个popover的toggle
- if (popover === _popover) {
- removeBackdrop(_popover);
- return;
- }
- }
- var isActionSheet = false;
- if (popover.classList.contains(CLASS_BAR_POPOVER) || popover.classList.contains(CLASS_ACTION_POPOVER)) { //navBar
- if (popover.classList.contains(CLASS_ACTION_POPOVER)) { //action sheet popover
- isActionSheet = true;
- backdrop.classList.add(CLASS_ACTION_BACKDROP);
- } else { //bar popover
- backdrop.classList.add(CLASS_BAR_BACKDROP);
- // if (anchor) {
- // if (anchor.parentNode) {
- // var offsetWidth = anchor.offsetWidth;
- // var offsetLeft = anchor.offsetLeft;
- // var innerWidth = window.innerWidth;
- // popover.style.left = (Math.min(Math.max(offsetLeft, defaultPadding), innerWidth - offsetWidth - defaultPadding)) + "px";
- // } else {
- // //TODO anchor is position:{left,top,bottom,right}
- // }
- // }
- }
- }
- setStyle(popover, 'block'); //actionsheet transform
- popover.offsetHeight;
- popover.classList.add(CLASS_ACTIVE);
- backdrop.setAttribute('style', '');
- document.body.appendChild(backdrop);
- calPosition(popover, anchor, isActionSheet); //position
- backdrop.classList.add(CLASS_ACTIVE);
- popover.addEventListener('webkitTransitionEnd', onPopoverShown);
- };
- var setStyle = function(popover, display, top, left) {
- var style = popover.style;
- if (typeof display !== 'undefined')
- style.display = display;
- if (typeof top !== 'undefined')
- style.top = top + 'px';
- if (typeof left !== 'undefined')
- style.left = left + 'px';
- };
- var calPosition = function(popover, anchor, isActionSheet) {
- if (!popover || !anchor) {
- return;
- }
- if (isActionSheet) { //actionsheet
- setStyle(popover, 'block')
- return;
- }
- var wWidth = window.innerWidth;
- var wHeight = window.innerHeight;
- var pWidth = popover.offsetWidth;
- var pHeight = popover.offsetHeight;
- var aWidth = anchor.offsetWidth;
- var aHeight = anchor.offsetHeight;
- var offset = $.offset(anchor);
- var arrow = popover.querySelector('.' + CLASS_POPOVER_ARROW);
- if (!arrow) {
- arrow = document.createElement('div');
- arrow.className = CLASS_POPOVER_ARROW;
- popover.appendChild(arrow);
- }
- var arrowSize = arrow && arrow.offsetWidth / 2 || 0;
- var pTop = 0;
- var pLeft = 0;
- var diff = 0;
- var arrowLeft = 0;
- var defaultPadding = popover.classList.contains(CLASS_ACTION_POPOVER) ? 0 : 5;
- var position = 'top';
- if ((pHeight + arrowSize) < (offset.top - window.pageYOffset)) { //top
- pTop = offset.top - pHeight - arrowSize;
- } else if ((pHeight + arrowSize) < (wHeight - (offset.top - window.pageYOffset) - aHeight)) { //bottom
- position = 'bottom';
- pTop = offset.top + aHeight + arrowSize;
- } else { //middle
- position = 'middle';
- pTop = Math.max((wHeight - pHeight) / 2 + window.pageYOffset, 0);
- pLeft = Math.max((wWidth - pWidth) / 2 + window.pageXOffset, 0);
- }
- if (position === 'top' || position === 'bottom') {
- pLeft = aWidth / 2 + offset.left - pWidth / 2;
- diff = pLeft;
- if (pLeft < defaultPadding) pLeft = defaultPadding;
- if (pLeft + pWidth > wWidth) pLeft = wWidth - pWidth - defaultPadding;
- if (arrow) {
- if (position === 'top') {
- arrow.classList.add(CLASS_BOTTOM);
- } else {
- arrow.classList.remove(CLASS_BOTTOM);
- }
- diff = diff - pLeft;
- arrowLeft = (pWidth / 2 - arrowSize / 2 + diff);
- arrowLeft = Math.max(Math.min(arrowLeft, pWidth - arrowSize * 2 - 6), 6);
- arrow.setAttribute('style', 'left:' + arrowLeft + 'px');
- }
- } else if (position === 'middle') {
- arrow.setAttribute('style', 'display:none');
- }
- setStyle(popover, 'block', pTop, pLeft);
- };
- $.createMask = function(callback) {
- var element = document.createElement('div');
- element.classList.add(CLASS_BACKDROP);
- element.addEventListener($.EVENT_MOVE, $.preventDefault);
- element.addEventListener('tap', function() {
- mask.close();
- });
- var mask = [element];
- mask._show = false;
- mask.show = function() {
- mask._show = true;
- element.setAttribute('style', 'opacity:1');
- document.body.appendChild(element);
- return mask;
- };
- mask._remove = function() {
- if (mask._show) {
- mask._show = false;
- element.setAttribute('style', 'opacity:0');
- $.later(function() {
- var body = document.body;
- element.parentNode === body && body.removeChild(element);
- }, 350);
- }
- return mask;
- };
- mask.close = function() {
- if (callback) {
- if (callback() !== false) {
- mask._remove();
- }
- } else {
- mask._remove();
- }
- };
- return mask;
- };
- $.fn.popover = function() {
- var args = arguments;
- this.each(function() {
- $.targets._popover = this;
- if (args[0] === 'show' || args[0] === 'hide' || args[0] === 'toggle') {
- togglePopover(this, args[1], args[0]);
- }
- });
- };
- })(mui, window, document, 'popover');
- /**
- * segmented-controllers
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @param {type} undefined
- * @returns {undefined}
- */
- (function($, window, document, name, undefined) {
- var CLASS_CONTROL_ITEM = 'mui-control-item';
- var CLASS_SEGMENTED_CONTROL = 'mui-segmented-control';
- var CLASS_SEGMENTED_CONTROL_VERTICAL = 'mui-segmented-control-vertical';
- var CLASS_CONTROL_CONTENT = 'mui-control-content';
- var CLASS_TAB_BAR = 'mui-bar-tab';
- var CLASS_TAB_ITEM = 'mui-tab-item';
- var CLASS_SLIDER_ITEM = 'mui-slider-item';
- var handle = function(event, target) {
- if (target.classList && (target.classList.contains(CLASS_CONTROL_ITEM) || target.classList.contains(CLASS_TAB_ITEM))) {
- if (target.parentNode && target.parentNode.classList && target.parentNode.classList.contains(CLASS_SEGMENTED_CONTROL_VERTICAL)) {
- //vertical 如果preventDefault会导致无法滚动
- } else {
- event.preventDefault();
- // if(target.tagName == 'A') {
- // // fixed 底部选项卡href 无法跳转 && stop hash change
- // var curr_href = location.hostname + location.pathname,
- // target_href = target.hostname + target.pathname;
-
- // if (curr_href == target_href && target.hash !== "") {
- // event.preventDefault();
- // return target;
- // }else{
- // return false
- // }
- // }
- }
- // if (target.hash) {
- return target;
- // }
- }
- return false;
- };
- $.registerTarget({
- name: name,
- index: 80,
- handle: handle,
- target: false
- });
- window.addEventListener('tap', function(e) {
- var targetTab = $.targets.tab;
- if (!targetTab) {
- return;
- }
- var activeTab;
- var activeBodies;
- var targetBody;
- var className = 'mui-active';
- var classSelector = '.' + className;
- var segmentedControl = targetTab.parentNode;
- for (; segmentedControl && segmentedControl !== document; segmentedControl = segmentedControl.parentNode) {
- if (segmentedControl.classList.contains(CLASS_SEGMENTED_CONTROL)) {
- activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_CONTROL_ITEM);
- break;
- } else if (segmentedControl.classList.contains(CLASS_TAB_BAR)) {
- activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_TAB_ITEM);
- }
- }
- if (activeTab) {
- activeTab.classList.remove(className);
- }
- var isLastActive = targetTab === activeTab;
- if (targetTab) {
- targetTab.classList.add(className);
- }
- if (!targetTab.hash) {
- return;
- }
- targetBody = document.getElementById(targetTab.hash.replace('#', ''));
- if (!targetBody) {
- return;
- }
- if (!targetBody.classList.contains(CLASS_CONTROL_CONTENT)) { //tab bar popover
- targetTab.classList[isLastActive ? 'remove' : 'add'](className);
- return;
- }
- if (isLastActive) { //same
- return;
- }
- var parentNode = targetBody.parentNode;
- activeBodies = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT + classSelector);
- for (var i = 0; i < activeBodies.length; i++) {
- var activeBody = activeBodies[i];
- activeBody.parentNode === parentNode && activeBody.classList.remove(className);
- }
- targetBody.classList.add(className);
- var contents = [];
- var _contents = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT);
- for (var i = 0; i < _contents.length; i++) { //查找直属子节点
- _contents[i].parentNode === parentNode && (contents.push(_contents[i]));
- }
- $.trigger(targetBody, $.eventName('shown', name), {
- tabNumber: Array.prototype.indexOf.call(contents, targetBody)
- });
- e.detail && e.detail.gesture.preventDefault(); //fixed hashchange
- });
- })(mui, window, document, 'tab');
- /**
- * Toggles switch
- * @param {type} $
- * @param {type} window
- * @param {type} name
- * @returns {undefined}
- */
- (function($, window, name) {
- var CLASS_SWITCH = 'mui-switch';
- var CLASS_SWITCH_HANDLE = 'mui-switch-handle';
- var CLASS_ACTIVE = 'mui-active';
- var CLASS_DRAGGING = 'mui-dragging';
- var CLASS_DISABLED = 'mui-disabled';
- var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE;
- var handle = function(event, target) {
- if (target.classList && target.classList.contains(CLASS_SWITCH)) {
- return target;
- }
- return false;
- };
- $.registerTarget({
- name: name,
- index: 100,
- handle: handle,
- target: false
- });
- var Toggle = function(element) {
- this.element = element;
- this.classList = this.element.classList;
- this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE);
- this.init();
- this.initEvent();
- };
- Toggle.prototype.init = function() {
- this.toggleWidth = this.element.offsetWidth;
- this.handleWidth = this.handle.offsetWidth;
- this.handleX = this.toggleWidth - this.handleWidth - 3;
- };
- Toggle.prototype.initEvent = function() {
- this.element.addEventListener($.EVENT_START, this);
- this.element.addEventListener('drag', this);
- this.element.addEventListener('swiperight', this);
- this.element.addEventListener($.EVENT_END, this);
- this.element.addEventListener($.EVENT_CANCEL, this);
- };
- Toggle.prototype.handleEvent = function(e) {
- if (this.classList.contains(CLASS_DISABLED)) {
- return;
- }
- switch (e.type) {
- case $.EVENT_START:
- this.start(e);
- break;
- case 'drag':
- this.drag(e);
- break;
- case 'swiperight':
- this.swiperight();
- break;
- case $.EVENT_END:
- case $.EVENT_CANCEL:
- this.end(e);
- break;
- }
- };
- Toggle.prototype.start = function(e) {
- this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
- this.classList.add(CLASS_DRAGGING);
- if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化
- this.init();
- }
- };
- Toggle.prototype.drag = function(e) {
- var detail = e.detail;
- if (!this.isDragging) {
- if (detail.direction === 'left' || detail.direction === 'right') {
- this.isDragging = true;
- this.lastChanged = undefined;
- this.initialState = this.classList.contains(CLASS_ACTIVE);
- }
- }
- if (this.isDragging) {
- this.setTranslateX(detail.deltaX);
- e.stopPropagation();
- detail.gesture.preventDefault();
- }
- };
- Toggle.prototype.swiperight = function(e) {
- if (this.isDragging) {
- e.stopPropagation();
- }
- };
- Toggle.prototype.end = function(e) {
- this.classList.remove(CLASS_DRAGGING);
- if (this.isDragging) {
- this.isDragging = false;
- e.stopPropagation();
- $.trigger(this.element, 'toggle', {
- isActive: this.classList.contains(CLASS_ACTIVE)
- });
- } else {
- this.toggle();
- }
- };
- Toggle.prototype.toggle = function(animate) {
- var classList = this.classList;
- if (animate === false) {
- this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s';
- } else {
- this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
- }
- if (classList.contains(CLASS_ACTIVE)) {
- classList.remove(CLASS_ACTIVE);
- this.handle.style.webkitTransform = 'translate(0,0)';
- } else {
- classList.add(CLASS_ACTIVE);
- this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)';
- }
- $.trigger(this.element, 'toggle', {
- isActive: this.classList.contains(CLASS_ACTIVE)
- });
- };
- Toggle.prototype.setTranslateX = $.animationFrame(function(x) {
- if (!this.isDragging) {
- return;
- }
- var isChanged = false;
- if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) {
- isChanged = true;
- }
- if (this.lastChanged !== isChanged) {
- if (isChanged) {
- this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)';
- this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE);
- } else {
- this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)';
- this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE);
- }
- this.lastChanged = isChanged;
- }
- });
- $.fn['switch'] = function(options) {
- var switchApis = [];
- this.each(function() {
- var switchApi = null;
- var id = this.getAttribute('data-switch');
- if (!id) {
- id = ++$.uuid;
- $.data[id] = new Toggle(this);
- this.setAttribute('data-switch', id);
- } else {
- switchApi = $.data[id];
- }
- switchApis.push(switchApi);
- });
- return switchApis.length > 1 ? switchApis : switchApis[0];
- };
- $.ready(function() {
- $('.' + CLASS_SWITCH)['switch']();
- });
- })(mui, window, 'toggle');
- /**
- * Tableviews
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @returns {undefined}
- */
- (function($, window, document) {
- var CLASS_ACTIVE = 'mui-active';
- var CLASS_SELECTED = 'mui-selected';
- var CLASS_GRID_VIEW = 'mui-grid-view';
- var CLASS_RADIO_VIEW = 'mui-table-view-radio';
- var CLASS_TABLE_VIEW_CELL = 'mui-table-view-cell';
- var CLASS_COLLAPSE_CONTENT = 'mui-collapse-content';
- var CLASS_DISABLED = 'mui-disabled';
- var CLASS_TOGGLE = 'mui-switch';
- var CLASS_BTN = 'mui-btn';
- var CLASS_SLIDER_HANDLE = 'mui-slider-handle';
- var CLASS_SLIDER_LEFT = 'mui-slider-left';
- var CLASS_SLIDER_RIGHT = 'mui-slider-right';
- var CLASS_TRANSITIONING = 'mui-transitioning';
- var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE;
- var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT;
- var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT;
- var SELECTOR_SELECTED = '.' + CLASS_SELECTED;
- var SELECTOR_BUTTON = '.' + CLASS_BTN;
- var overFactor = 0.8;
- var cell, a;
- var isMoved = isOpened = openedActions = progress = false;
- var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
- var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0;
- var toggleActive = function(isActive) {
- if (isActive) {
- if (a) {
- a.classList.add(CLASS_ACTIVE);
- } else if (cell) {
- cell.classList.add(CLASS_ACTIVE);
- }
- } else {
- timer && timer.cancel();
- if (a) {
- a.classList.remove(CLASS_ACTIVE);
- } else if (cell) {
- cell.classList.remove(CLASS_ACTIVE);
- }
- }
- };
- var updateTranslate = function() {
- if (translateX !== lastTranslateX) {
- if (buttonsRight && buttonsRight.length > 0) {
- progress = translateX / sliderActionRightWidth;
- if (translateX < -sliderActionRightWidth) {
- translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor);
- }
- for (var i = 0, len = buttonsRight.length; i < len; i++) {
- var buttonRight = buttonsRight[i];
- if (typeof buttonRight._buttonOffset === 'undefined') {
- buttonRight._buttonOffset = buttonRight.offsetLeft;
- }
- buttonOffset = buttonRight._buttonOffset;
- setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1))));
- }
- }
- if (buttonsLeft && buttonsLeft.length > 0) {
- progress = translateX / sliderActionLeftWidth;
- if (translateX > sliderActionLeftWidth) {
- translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor);
- }
- for (var i = 0, len = buttonsLeft.length; i < len; i++) {
- var buttonLeft = buttonsLeft[i];
- if (typeof buttonLeft._buttonOffset === 'undefined') {
- buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
- }
- buttonOffset = buttonLeft._buttonOffset;
- if (buttonsLeft.length > 1) {
- buttonLeft.style.zIndex = buttonsLeft.length - i;
- }
- setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1))));
- }
- }
- setTranslate(sliderHandle, translateX);
- lastTranslateX = translateX;
- }
- sliderRequestAnimationFrame = requestAnimationFrame(function() {
- updateTranslate();
- });
- };
- var setTranslate = function(element, x) {
- if (element) {
- element.style.webkitTransform = 'translate(' + x + 'px,0)';
- }
- };
- window.addEventListener($.EVENT_START, function(event) {
- if (cell) {
- toggleActive(false);
- }
- cell = a = false;
- isMoved = isOpened = openedActions = false;
- var target = event.target;
- var isDisabled = false;
- for (; target && target !== document; target = target.parentNode) {
- if (target.classList) {
- var classList = target.classList;
- 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)) {
- isDisabled = true;
- }
- if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content
- break;
- }
- if (classList.contains(CLASS_TABLE_VIEW_CELL)) {
- cell = target;
- //TODO swipe to delete close
- var selected = cell.parentNode.querySelector(SELECTOR_SELECTED);
- if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) {
- $.swipeoutClose(selected);
- cell = isDisabled = false;
- return;
- }
- if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) {
- var link = cell.querySelector('a');
- if (link && link.parentNode === cell) { //li>a
- a = link;
- }
- }
- var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
- if (handle) {
- toggleEvents(cell);
- event.stopPropagation();
- }
- if (!isDisabled) {
- if (handle) {
- if (timer) {
- timer.cancel();
- }
- timer = $.later(function() {
- toggleActive(true);
- }, 100);
- } else {
- toggleActive(true);
- }
- }
- break;
- }
- }
- }
- });
- window.addEventListener($.EVENT_MOVE, function(event) {
- toggleActive(false);
- });
- var handleEvent = {
- handleEvent: function(event) {
- switch (event.type) {
- case 'drag':
- this.drag(event);
- break;
- case 'dragend':
- this.dragend(event);
- break;
- case 'flick':
- this.flick(event);
- break;
- case 'swiperight':
- this.swiperight(event);
- break;
- case 'swipeleft':
- this.swipeleft(event);
- break;
- }
- },
- drag: function(event) {
- if (!cell) {
- return;
- }
- if (!isMoved) { //init
- sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
- sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
- if (sliderHandle) {
- sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT);
- sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT);
- if (sliderActionLeft) {
- sliderActionLeftWidth = sliderActionLeft.offsetWidth;
- buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON);
- }
- if (sliderActionRight) {
- sliderActionRightWidth = sliderActionRight.offsetWidth;
- buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON);
- }
- cell.classList.remove(CLASS_TRANSITIONING);
- isOpened = cell.classList.contains(CLASS_SELECTED);
- if (isOpened) {
- openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right';
- }
- }
- }
- var detail = event.detail;
- var direction = detail.direction;
- var angle = detail.angle;
- if (direction === 'left' && (angle > 150 || angle < -150)) {
- if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态
- isMoved = true;
- }
- } else if (direction === 'right' && (angle > -30 && angle < 30)) {
- if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态
- isMoved = true;
- }
- }
- if (isMoved) {
- event.stopPropagation();
- event.detail.gesture.preventDefault();
- var translate = event.detail.deltaX;
- if (isOpened) {
- if (openedActions === 'right') {
- translate = translate - sliderActionRightWidth;
- } else {
- translate = translate + sliderActionLeftWidth;
- }
- }
- if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) {
- if (!isOpened) {
- return;
- }
- translate = 0;
- }
- if (translate < 0) {
- sliderDirection = 'toLeft';
- } else if (translate > 0) {
- sliderDirection = 'toRight';
- } else {
- if (!sliderDirection) {
- sliderDirection = 'toLeft';
- }
- }
- if (!sliderRequestAnimationFrame) {
- updateTranslate();
- }
- translateX = translate;
- }
- },
- flick: function(event) {
- if (isMoved) {
- event.stopPropagation();
- }
- },
- swipeleft: function(event) {
- if (isMoved) {
- event.stopPropagation();
- }
- },
- swiperight: function(event) {
- if (isMoved) {
- event.stopPropagation();
- }
- },
- dragend: function(event) {
- if (!isMoved) {
- return;
- }
- event.stopPropagation();
- if (sliderRequestAnimationFrame) {
- cancelAnimationFrame(sliderRequestAnimationFrame);
- sliderRequestAnimationFrame = null;
- }
- var detail = event.detail;
- isMoved = false;
- var action = 'close';
- var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth;
- var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2);
- if (isToggle) {
- if (!isOpened) {
- action = 'open';
- } else if (detail.direction === 'left' && openedActions === 'right') {
- action = 'open';
- } else if (detail.direction === 'right' && openedActions === 'left') {
- action = 'open';
- }
- }
- cell.classList.add(CLASS_TRANSITIONING);
- var buttons;
- if (action === 'open') {
- var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth;
- setTranslate(sliderHandle, newTranslate);
- buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft;
- if (typeof buttons !== 'undefined') {
- var button = null;
- for (var i = 0; i < buttons.length; i++) {
- button = buttons[i];
- setTranslate(button, newTranslate);
- }
- button.parentNode.classList.add(CLASS_SELECTED);
- cell.classList.add(CLASS_SELECTED);
- if (!isOpened) {
- $.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright');
- }
- }
- } else {
- setTranslate(sliderHandle, 0);
- sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED);
- sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED);
- cell.classList.remove(CLASS_SELECTED);
- }
- var buttonOffset;
- if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {
- for (var i = 0, len = buttonsLeft.length; i < len; i++) {
- var buttonLeft = buttonsLeft[i];
- buttonOffset = buttonLeft._buttonOffset;
- if (typeof buttonOffset === 'undefined') {
- buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
- }
- setTranslate(buttonLeft, buttonOffset);
- }
- }
- if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {
- for (var i = 0, len = buttonsRight.length; i < len; i++) {
- var buttonRight = buttonsRight[i];
- buttonOffset = buttonRight._buttonOffset;
- if (typeof buttonOffset === 'undefined') {
- buttonRight._buttonOffset = buttonRight.offsetLeft;
- }
- setTranslate(buttonRight, -buttonOffset);
- }
- }
- }
- };
- function toggleEvents(element, isRemove) {
- var method = !!isRemove ? 'removeEventListener' : 'addEventListener';
- element[method]('drag', handleEvent);
- element[method]('dragend', handleEvent);
- element[method]('swiperight', handleEvent);
- element[method]('swipeleft', handleEvent);
- element[method]('flick', handleEvent);
- };
- /**
- * 打开滑动菜单
- * @param {Object} el
- * @param {Object} direction
- */
- $.swipeoutOpen = function(el, direction) {
- if (!el) return;
- var classList = el.classList;
- if (classList.contains(CLASS_SELECTED)) return;
- if (!direction) {
- if (el.querySelector(SELECTOR_SLIDER_RIGHT)) {
- direction = 'right';
- } else {
- direction = 'left';
- }
- }
- var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
- if (!swipeoutAction) return;
- swipeoutAction.classList.add(CLASS_SELECTED);
- classList.add(CLASS_SELECTED);
- classList.remove(CLASS_TRANSITIONING);
- var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
- var swipeoutWidth = swipeoutAction.offsetWidth;
- var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth;
- var length = buttons.length;
- var button;
- for (var i = 0; i < length; i++) {
- button = buttons[i];
- if (direction === 'right') {
- setTranslate(button, -button.offsetLeft);
- } else {
- setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
- }
- }
- classList.add(CLASS_TRANSITIONING);
- for (var i = 0; i < length; i++) {
- setTranslate(buttons[i], translate);
- }
- setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate);
- };
- /**
- * 关闭滑动菜单
- * @param {Object} el
- */
- $.swipeoutClose = function(el) {
- if (!el) return;
- var classList = el.classList;
- if (!classList.contains(CLASS_SELECTED)) return;
- var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left';
- var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
- if (!swipeoutAction) return;
- swipeoutAction.classList.remove(CLASS_SELECTED);
- classList.remove(CLASS_SELECTED);
- classList.add(CLASS_TRANSITIONING);
- var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
- var swipeoutWidth = swipeoutAction.offsetWidth;
- var length = buttons.length;
- var button;
- setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0);
- for (var i = 0; i < length; i++) {
- button = buttons[i];
- if (direction === 'right') {
- setTranslate(button, (-button.offsetLeft));
- } else {
- setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
- }
- }
- };
- window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
- if (!cell) {
- return;
- }
- toggleActive(false);
- sliderHandle && toggleEvents(cell, true);
- });
- window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
- if (!cell) {
- return;
- }
- toggleActive(false);
- sliderHandle && toggleEvents(cell, true);
- });
- var radioOrCheckboxClick = function(event) {
- var type = event.target && event.target.type || '';
- if (type === 'radio' || type === 'checkbox') {
- return;
- }
- var classList = cell.classList;
- if (classList.contains('mui-radio')) {
- var input = cell.querySelector('input[type=radio]');
- if (input) {
- // input.click();
- if (!input.disabled && !input.readOnly) {
- input.checked = !input.checked;
- $.trigger(input, 'change');
- }
- }
- } else if (classList.contains('mui-checkbox')) {
- var input = cell.querySelector('input[type=checkbox]');
- if (input) {
- // input.click();
- if (!input.disabled && !input.readOnly) {
- input.checked = !input.checked;
- $.trigger(input, 'change');
- }
- }
- }
- };
- //fixed hashchange(android)
- window.addEventListener($.EVENT_CLICK, function(e) {
- if (cell && cell.classList.contains('mui-collapse')) {
- e.preventDefault();
- }
- });
- window.addEventListener('doubletap', function(event) {
- if (cell) {
- radioOrCheckboxClick(event);
- }
- });
- var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
- window.addEventListener('tap', function(event) {
- if (!cell) {
- return;
- }
- var isExpand = false;
- var classList = cell.classList;
- var ul = cell.parentNode;
- if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) {
- if (classList.contains(CLASS_SELECTED)) {
- return;
- }
- var selected = ul.querySelector('li' + SELECTOR_SELECTED);
- if (selected) {
- selected.classList.remove(CLASS_SELECTED);
- }
- classList.add(CLASS_SELECTED);
- $.trigger(cell, 'selected', {
- el: cell
- });
- return;
- }
- if (classList.contains('mui-collapse') && !cell.parentNode.classList.contains('mui-unfold')) {
- if (!preventDefaultException.test(event.target.tagName)) {
- event.detail.gesture.preventDefault();
- }
- if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类
- var collapse = cell.parentNode.querySelector('.mui-collapse.mui-active');
- if (collapse) {
- collapse.classList.remove(CLASS_ACTIVE);
- }
- isExpand = true;
- }
- classList.toggle(CLASS_ACTIVE);
- if (isExpand) {
- //触发展开事件
- $.trigger(cell, 'expand');
- //scroll
- //暂不滚动
- // var offsetTop = $.offset(cell).top;
- // var scrollTop = document.body.scrollTop;
- // var height = window.innerHeight;
- // var offsetHeight = cell.offsetHeight;
- // var cellHeight = (offsetTop - scrollTop + offsetHeight);
- // if (offsetHeight > height) {
- // $.scrollTo(offsetTop, 300);
- // } else if (cellHeight > height) {
- // $.scrollTo(cellHeight - height + scrollTop, 300);
- // }
- }
- } else {
- radioOrCheckboxClick(event);
- }
- });
- })(mui, window, document);
- (function($, window) {
- /**
- * 警告消息框
- */
- $.alert = function(message, title, btnValue, callback) {
- if ($.os.plus) {
- if (typeof message === 'undefined') {
- return;
- } else {
- if (typeof title === 'function') {
- callback = title;
- title = null;
- btnValue = '确定';
- } else if (typeof btnValue === 'function') {
- callback = btnValue;
- btnValue = null;
- }
- $.plusReady(function() {
- plus.nativeUI.alert(message, callback, title, btnValue);
- });
- }
- } else {
- //TODO H5版本
- window.alert(message);
- }
- };
- })(mui, window);
- (function($, window) {
- /**
- * 确认消息框
- */
- $.confirm = function(message, title, btnArray, callback) {
- if ($.os.plus) {
- if (typeof message === 'undefined') {
- return;
- } else {
- if (typeof title === 'function') {
- callback = title;
- title = null;
- btnArray = null;
- } else if (typeof btnArray === 'function') {
- callback = btnArray;
- btnArray = null;
- }
- $.plusReady(function() {
- plus.nativeUI.confirm(message, callback, title, btnArray);
- });
- }
- } else {
- //H5版本,0为确认,1为取消
- if (window.confirm(message)) {
- callback({
- index: 0
- });
- } else {
- callback({
- index: 1
- });
- }
- }
- };
- })(mui, window);
- (function($, window) {
- /**
- * 输入对话框
- */
- $.prompt = function(text, defaultText, title, btnArray, callback) {
- if ($.os.plus) {
- if (typeof message === 'undefined') {
- return;
- } else {
- if (typeof defaultText === 'function') {
- callback = defaultText;
- defaultText = null;
- title = null;
- btnArray = null;
- } else if (typeof title === 'function') {
- callback = title;
- title = null;
- btnArray = null;
- } else if (typeof btnArray === 'function') {
- callback = btnArray;
- btnArray = null;
- }
- $.plusReady(function() {
- plus.nativeUI.prompt(text, callback, title, defaultText, btnArray);
- });
- }
- } else {
- //H5版本(确认index为0,取消index为1)
- var result = window.prompt(text);
- if (result) {
- callback({
- index: 0,
- value: result
- });
- } else {
- callback({
- index: 1,
- value: ''
- });
- }
- }
- };
- })(mui, window);
- (function($, window) {
- var CLASS_ACTIVE = 'mui-active';
- /**
- * 自动消失提示框
- */
- $.toast = function(message,options) {
- var durations = {
- 'long': 3500,
- 'short': 2000
- };
- //计算显示时间
- options = $.extend({
- duration: 'short'
- }, options || {});
- if ($.os.plus && options.type !== 'div') {
- //默认显示在底部;
- $.plusReady(function() {
- plus.nativeUI.toast(message, {
- verticalAlign: 'bottom',
- duration:options.duration
- });
- });
- } else {
- if (typeof options.duration === 'number') {
- duration = options.duration>0 ? options.duration:durations['short'];
- } else {
- duration = durations[options.duration];
- }
- if (!duration) {
- duration = durations['short'];
- }
- var toast = document.createElement('div');
- toast.classList.add('mui-toast-container');
- toast.innerHTML = '<div class="' + 'mui-toast-message' + '">' + message + '</div>';
- toast.addEventListener('webkitTransitionEnd', function() {
- if (!toast.classList.contains(CLASS_ACTIVE)) {
- toast.parentNode.removeChild(toast);
- toast = null;
- }
- });
- //点击则自动消失
- toast.addEventListener('click', function() {
- toast.parentNode.removeChild(toast);
- toast = null;
- });
- document.body.appendChild(toast);
- toast.offsetHeight;
- toast.classList.add(CLASS_ACTIVE);
- setTimeout(function() {
- toast && toast.classList.remove(CLASS_ACTIVE);
- }, duration);
-
- return {
- isVisible: function() {return !!toast;}
- }
- }
- };
- })(mui, window);
- /**
- * Popup(alert,confirm,prompt)
- * @param {Object} $
- * @param {Object} window
- * @param {Object} document
- */
- (function($, window, document) {
- var CLASS_POPUP = 'mui-popup';
- var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
- var CLASS_POPUP_IN = 'mui-popup-in';
- var CLASS_POPUP_OUT = 'mui-popup-out';
- var CLASS_POPUP_INNER = 'mui-popup-inner';
- var CLASS_POPUP_TITLE = 'mui-popup-title';
- var CLASS_POPUP_TEXT = 'mui-popup-text';
- var CLASS_POPUP_INPUT = 'mui-popup-input';
- var CLASS_POPUP_BUTTONS = 'mui-popup-buttons';
- var CLASS_POPUP_BUTTON = 'mui-popup-button';
- var CLASS_POPUP_BUTTON_BOLD = 'mui-popup-button-bold';
- var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
- var CLASS_ACTIVE = 'mui-active';
- var popupStack = [];
- var backdrop = (function() {
- var element = document.createElement('div');
- element.classList.add(CLASS_POPUP_BACKDROP);
- element.addEventListener($.EVENT_MOVE, $.preventDefault);
- element.addEventListener('webkitTransitionEnd', function() {
- if (!this.classList.contains(CLASS_ACTIVE)) {
- element.parentNode && element.parentNode.removeChild(element);
- }
- });
- return element;
- }());
- var createInput = function(placeholder) {
- return '<div class="' + CLASS_POPUP_INPUT + '"><input type="text" autofocus placeholder="' + (placeholder || '') + '"/></div>';
- };
- var createInner = function(message, title, extra) {
- 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>';
- };
- var createButtons = function(btnArray) {
- var length = btnArray.length;
- var btns = [];
- for (var i = 0; i < length; i++) {
- btns.push('<span class="' + CLASS_POPUP_BUTTON + (i === length - 1 ? (' ' + CLASS_POPUP_BUTTON_BOLD) : '') + '">' + btnArray[i] + '</span>');
- }
- return '<div class="' + CLASS_POPUP_BUTTONS + '">' + btns.join('') + '</div>';
- };
- var createPopup = function(html, callback) {
- var popupElement = document.createElement('div');
- popupElement.className = CLASS_POPUP;
- popupElement.innerHTML = html;
- var removePopupElement = function() {
- popupElement.parentNode && popupElement.parentNode.removeChild(popupElement);
- popupElement = null;
- };
- popupElement.addEventListener($.EVENT_MOVE, $.preventDefault);
- popupElement.addEventListener('webkitTransitionEnd', function(e) {
- if (popupElement && e.target === popupElement && popupElement.classList.contains(CLASS_POPUP_OUT)) {
- removePopupElement();
- }
- });
- popupElement.style.display = 'block';
- document.body.appendChild(popupElement);
- popupElement.offsetHeight;
- popupElement.classList.add(CLASS_POPUP_IN);
- if (!backdrop.classList.contains(CLASS_ACTIVE)) {
- backdrop.style.display = 'block';
- document.body.appendChild(backdrop);
- backdrop.offsetHeight;
- backdrop.classList.add(CLASS_ACTIVE);
- }
- var btns = $.qsa('.' + CLASS_POPUP_BUTTON, popupElement);
- var input = popupElement.querySelector('.' + CLASS_POPUP_INPUT + ' input');
- var popup = {
- element: popupElement,
- close: function(index, animate) {
- if (popupElement) {
- var result = callback && callback({
- index: index || 0,
- value: input && input.value || ''
- });
- if (result === false) { //返回false则不关闭当前popup
- return;
- }
- if (animate !== false) {
- popupElement.classList.remove(CLASS_POPUP_IN);
- popupElement.classList.add(CLASS_POPUP_OUT);
- } else {
- removePopupElement();
- }
- popupStack.pop();
- //如果还有其他popup,则不remove backdrop
- if (popupStack.length) {
- popupStack[popupStack.length - 1]['show'](animate);
- } else {
- backdrop.classList.remove(CLASS_ACTIVE);
- }
- }
- }
- };
- var handleEvent = function(e) {
- popup.close(btns.indexOf(e.target));
- };
- $(popupElement).on('tap', '.' + CLASS_POPUP_BUTTON, handleEvent);
- if (popupStack.length) {
- popupStack[popupStack.length - 1]['hide']();
- }
- popupStack.push({
- close: popup.close,
- show: function(animate) {
- popupElement.style.display = 'block';
- popupElement.offsetHeight;
- popupElement.classList.add(CLASS_POPUP_IN);
- },
- hide: function() {
- popupElement.style.display = 'none';
- popupElement.classList.remove(CLASS_POPUP_IN);
- }
- });
- return popup;
- };
- var createAlert = function(message, title, btnValue, callback, type) {
- if (typeof message === 'undefined') {
- return;
- } else {
- if (typeof title === 'function') {
- callback = title;
- type = btnValue;
- title = null;
- btnValue = null;
- } else if (typeof btnValue === 'function') {
- type = callback;
- callback = btnValue;
- btnValue = null;
- }
- }
- if (!$.os.plus || type === 'div') {
- return createPopup(createInner(message, title || '提示') + createButtons([btnValue || '确定']), callback);
- }
- return plus.nativeUI.alert(message, callback, title || '提示', btnValue || '确定');
- };
- var createConfirm = function(message, title, btnArray, callback, type) {
- if (typeof message === 'undefined') {
- return;
- } else {
- if (typeof title === 'function') {
- callback = title;
- type = btnArray;
- title = null;
- btnArray = null;
- } else if (typeof btnArray === 'function') {
- type = callback;
- callback = btnArray;
- btnArray = null;
- }
- }
- if (!$.os.plus || type === 'div') {
- return createPopup(createInner(message, title || '提示') + createButtons(btnArray || ['取消', '确认']), callback);
- }
- return plus.nativeUI.confirm(message, callback, title, btnArray || ['取消', '确认']);
- };
- var createPrompt = function(message, placeholder, title, btnArray, callback, type) {
- if (typeof message === 'undefined') {
- return;
- } else {
- if (typeof placeholder === 'function') {
- callback = placeholder;
- type = title;
- placeholder = null;
- title = null;
- btnArray = null;
- } else if (typeof title === 'function') {
- callback = title;
- type = btnArray;
- title = null;
- btnArray = null;
- } else if (typeof btnArray === 'function') {
- type = callback;
- callback = btnArray;
- btnArray = null;
- }
- }
- if (!$.os.plus || type === 'div') {
- return createPopup(createInner(message, title || '提示', createInput(placeholder)) + createButtons(btnArray || ['取消', '确认']), callback);
- }
- return plus.nativeUI.prompt(message, callback, title || '提示', placeholder, btnArray || ['取消', '确认']);
- };
- var closePopup = function() {
- if (popupStack.length) {
- popupStack[popupStack.length - 1]['close']();
- return true;
- } else {
- return false;
- }
- };
- var closePopups = function() {
- while (popupStack.length) {
- popupStack[popupStack.length - 1]['close']();
- }
- };
- $.closePopup = closePopup;
- $.closePopups = closePopups;
- $.alert = createAlert;
- $.confirm = createConfirm;
- $.prompt = createPrompt;
- })(mui, window, document);
- (function($, document) {
- var CLASS_PROGRESSBAR = 'mui-progressbar';
- var CLASS_PROGRESSBAR_IN = 'mui-progressbar-in';
- var CLASS_PROGRESSBAR_OUT = 'mui-progressbar-out';
- var CLASS_PROGRESSBAR_INFINITE = 'mui-progressbar-infinite';
- var SELECTOR_PROGRESSBAR = '.mui-progressbar';
- var _findProgressbar = function(container) {
- container = $(container || 'body');
- if (container.length === 0) return;
- container = container[0];
- if (container.classList.contains(CLASS_PROGRESSBAR)) {
- return container;
- }
- var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR);
- if (progressbars) {
- for (var i = 0, len = progressbars.length; i < len; i++) {
- var progressbar = progressbars[i];
- if (progressbar.parentNode === container) {
- return progressbar;
- }
- }
- }
- };
- /**
- * 创建并显示进度条
- * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
- * @param {Object} progress 可选,undefined表示循环,数字表示具体进度
- * @param {Object} color 可选,指定颜色样式(目前暂未提供实际样式,可暂时不暴露此参数)
- */
- var showProgressbar = function(container, progress, color) {
- if (typeof container === 'number') {
- color = progress;
- progress = container;
- container = 'body';
- }
- container = $(container || 'body');
- if (container.length === 0) return;
- container = container[0];
- var progressbar;
- if (container.classList.contains(CLASS_PROGRESSBAR)) {
- progressbar = container;
- } else {
- var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR + ':not(.' + CLASS_PROGRESSBAR_OUT + ')');
- if (progressbars) {
- for (var i = 0, len = progressbars.length; i < len; i++) {
- var _progressbar = progressbars[i];
- if (_progressbar.parentNode === container) {
- progressbar = _progressbar;
- break;
- }
- }
- }
- if (!progressbar) {
- progressbar = document.createElement('span');
- progressbar.className = CLASS_PROGRESSBAR + ' ' + CLASS_PROGRESSBAR_IN + (typeof progress !== 'undefined' ? '' : (' ' + CLASS_PROGRESSBAR_INFINITE)) + (color ? (' ' + CLASS_PROGRESSBAR + '-' + color) : '');
- if (typeof progress !== 'undefined') {
- progressbar.innerHTML = '<span></span>';
- }
- container.appendChild(progressbar);
- } else {
- progressbar.classList.add(CLASS_PROGRESSBAR_IN);
- }
- }
- if (progress) setProgressbar(container, progress);
- return progressbar;
- };
- /**
- * 关闭进度条
- * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
- */
- var hideProgressbar = function(container) {
- var progressbar = _findProgressbar(container);
- if (!progressbar) {
- return;
- }
- var classList = progressbar.classList;
- if (!classList.contains(CLASS_PROGRESSBAR_IN) || classList.contains(CLASS_PROGRESSBAR_OUT)) {
- return;
- }
- classList.remove(CLASS_PROGRESSBAR_IN);
- classList.add(CLASS_PROGRESSBAR_OUT);
- progressbar.addEventListener('webkitAnimationEnd', function() {
- progressbar.parentNode && progressbar.parentNode.removeChild(progressbar);
- progressbar = null;
- });
- return;
- };
- /**
- * 设置指定进度条进度
- * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
- * @param {Object} progress 可选,默认0 取值范围[0-100]
- * @param {Object} speed 进度条动画时间
- */
- var setProgressbar = function(container, progress, speed) {
- if (typeof container === 'number') {
- speed = progress;
- progress = container;
- container = false;
- }
- var progressbar = _findProgressbar(container);
- if (!progressbar || progressbar.classList.contains(CLASS_PROGRESSBAR_INFINITE)) {
- return;
- }
- if (progress) progress = Math.min(Math.max(progress, 0), 100);
- progressbar.offsetHeight;
- var span = progressbar.querySelector('span');
- if (span) {
- var style = span.style;
- style.webkitTransform = 'translate3d(' + (-100 + progress) + '%,0,0)';
- if (typeof speed !== 'undefined') {
- style.webkitTransitionDuration = speed + 'ms';
- } else {
- style.webkitTransitionDuration = '';
- }
- }
- return progressbar;
- };
- $.fn.progressbar = function(options) {
- var progressbarApis = [];
- options = options || {};
- this.each(function() {
- var self = this;
- var progressbarApi = self.mui_plugin_progressbar;
- if (!progressbarApi) {
- self.mui_plugin_progressbar = progressbarApi = {
- options: options,
- setOptions: function(options) {
- this.options = options;
- },
- show: function() {
- return showProgressbar(self, this.options.progress, this.options.color);
- },
- setProgress: function(progress) {
- return setProgressbar(self, progress);
- },
- hide: function() {
- return hideProgressbar(self);
- }
- };
- } else if (options) {
- progressbarApi.setOptions(options);
- }
- progressbarApis.push(progressbarApi);
- });
- return progressbarApis.length === 1 ? progressbarApis[0] : progressbarApis;
- };
- // $.setProgressbar = setProgressbar;
- // $.showProgressbar = showProgressbar;
- // $.hideProgressbar = hideProgressbar;
- })(mui, document);
- /**
- * Input(TODO resize)
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @returns {undefined}
- */
- (function($, window, document) {
- var CLASS_ICON = 'mui-icon';
- var CLASS_ICON_CLEAR = 'mui-icon-clear';
- var CLASS_ICON_SPEECH = 'mui-icon-speech';
- var CLASS_ICON_SEARCH = 'mui-icon-search';
- var CLASS_ICON_PASSWORD = 'mui-icon-eye';
- var CLASS_INPUT_ROW = 'mui-input-row';
- var CLASS_PLACEHOLDER = 'mui-placeholder';
- var CLASS_TOOLTIP = 'mui-tooltip';
- var CLASS_HIDDEN = 'mui-hidden';
- var CLASS_FOCUSIN = 'mui-focusin';
- var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR;
- var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH;
- var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD;
- var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER;
- var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP;
- var findRow = function(target) {
- for (; target && target !== document; target = target.parentNode) {
- if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) {
- return target;
- }
- }
- return null;
- };
- var Input = function(element, options) {
- this.element = element;
- this.options = options || {
- actions: 'clear'
- };
- if (~this.options.actions.indexOf('slider')) { //slider
- this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN;
- this.sliderActionSelector = SELECTOR_TOOLTIP;
- } else { //clear,speech,search
- if (~this.options.actions.indexOf('clear')) {
- this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN;
- this.clearActionSelector = SELECTOR_ICON_CLOSE;
- }
- if (~this.options.actions.indexOf('speech')) { //only for 5+
- this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH;
- this.speechActionSelector = SELECTOR_ICON_SPEECH;
- }
- if (~this.options.actions.indexOf('search')) {
- this.searchActionClass = CLASS_PLACEHOLDER;
- this.searchActionSelector = SELECTOR_PLACEHOLDER;
- }
- if (~this.options.actions.indexOf('password')) {
- this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD;
- this.passwordActionSelector = SELECTOR_ICON_PASSWORD;
- }
- }
- this.init();
- };
- Input.prototype.init = function() {
- this.initAction();
- this.initElementEvent();
- };
- Input.prototype.initAction = function() {
- var self = this;
- var row = self.element.parentNode;
- if (row) {
- if (self.sliderActionClass) {
- self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector);
- } else {
- if (self.searchActionClass) {
- self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector);
- self.searchAction.addEventListener('tap', function(e) {
- $.focus(self.element);
- e.stopPropagation();
- });
- }
- if (self.speechActionClass) {
- self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector);
- self.speechAction.addEventListener('click', $.stopPropagation);
- self.speechAction.addEventListener('tap', function(event) {
- self.speechActionClick(event);
- });
- }
- if (self.clearActionClass) {
- self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector);
- self.clearAction.addEventListener('tap', function(event) {
- self.clearActionClick(event);
- });
- }
- if (self.passwordActionClass) {
- self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector);
- self.passwordAction.addEventListener('tap', function(event) {
- self.passwordActionClick(event);
- });
- }
- }
- }
- };
- Input.prototype.createAction = function(row, actionClass, actionSelector) {
- var action = row.querySelector(actionSelector);
- if (!action) {
- var action = document.createElement('span');
- action.className = actionClass;
- if (actionClass === this.searchActionClass) {
- action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>';
- this.element.setAttribute('placeholder', '');
- if (this.element.value.trim()) {
- row.classList.add('mui-active');
- }
- }
- row.insertBefore(action, this.element.nextSibling);
- }
- return action;
- };
- Input.prototype.initElementEvent = function() {
- var element = this.element;
- if (this.sliderActionClass) {
- var tooltip = this.sliderAction;
- var timer = null;
- var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的
- tooltip.classList.remove(CLASS_HIDDEN);
- var offsetLeft = element.offsetLeft;
- var width = element.offsetWidth - 28;
- var tooltipWidth = tooltip.offsetWidth;
- var distince = Math.abs(element.max - element.min);
- var scaleWidth = (width / distince) * Math.abs(element.value - element.min);
- tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px';
- tooltip.innerText = element.value;
- if (timer) {
- clearTimeout(timer);
- }
- timer = setTimeout(function() {
- tooltip.classList.add(CLASS_HIDDEN);
- }, 1000);
- };
- element.addEventListener('input', showTip);
- element.addEventListener('tap', showTip);
- element.addEventListener($.EVENT_MOVE, function(e) {
- e.stopPropagation();
- });
- } else {
- if (this.clearActionClass) {
- var action = this.clearAction;
- if (!action) {
- return;
- }
- $.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) {
- (function(type) {
- element.addEventListener(type, function() {
- action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN);
- });
- })(type);
- });
- element.addEventListener('blur', function() {
- action.classList.add(CLASS_HIDDEN);
- });
- }
- if (this.searchActionClass) {
- element.addEventListener('focus', function() {
- element.parentNode.classList.add('mui-active');
- });
- element.addEventListener('blur', function() {
- if (!element.value.trim()) {
- element.parentNode.classList.remove('mui-active');
- }
- });
- }
- }
- };
- Input.prototype.setPlaceholder = function(text) {
- if (this.searchActionClass) {
- var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER);
- placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text);
- } else {
- this.element.setAttribute('placeholder', text);
- }
- };
- Input.prototype.passwordActionClick = function(event) {
- if (this.element.type === 'text') {
- this.element.type = 'password';
- } else {
- this.element.type = 'text';
- }
- this.passwordAction.classList.toggle('mui-active');
- event.preventDefault();
- };
- Input.prototype.clearActionClick = function(event) {
- var self = this;
- self.element.value = '';
- $.focus(self.element);
- self.clearAction.classList.add(CLASS_HIDDEN);
- event.preventDefault();
- };
- Input.prototype.speechActionClick = function(event) {
- if (window.plus) {
- var self = this;
- var oldValue = self.element.value;
- self.element.value = '';
- document.body.classList.add(CLASS_FOCUSIN);
- plus.speech.startRecognize({
- engine: 'iFly'
- }, function(s) {
- self.element.value += s;
- $.focus(self.element);
- plus.speech.stopRecognize();
- $.trigger(self.element, 'recognized', {
- value: self.element.value
- });
- if (oldValue !== self.element.value) {
- $.trigger(self.element, 'change');
- $.trigger(self.element, 'input');
- }
- // document.body.classList.remove(CLASS_FOCUSIN);
- }, function(e) {
- document.body.classList.remove(CLASS_FOCUSIN);
- });
- } else {
- alert('only for 5+');
- }
- event.preventDefault();
- };
- $.fn.input = function(options) {
- var inputApis = [];
- this.each(function() {
- var inputApi = null;
- var actions = [];
- var row = findRow(this.parentNode);
- if (this.type === 'range' && row.classList.contains('mui-input-range')) {
- actions.push('slider');
- } else {
- var classList = this.classList;
- if (classList.contains('mui-input-clear')) {
- actions.push('clear');
- }
- if (!($.os.android && $.os.stream) && classList.contains('mui-input-speech')) {
- actions.push('speech');
- }
- if (classList.contains('mui-input-password')) {
- actions.push('password');
- }
- if (this.type === 'search' && row.classList.contains('mui-search')) {
- actions.push('search');
- }
- }
- var id = this.getAttribute('data-input-' + actions[0]);
- if (!id) {
- id = ++$.uuid;
- inputApi = $.data[id] = new Input(this, {
- actions: actions.join(',')
- });
- for (var i = 0, len = actions.length; i < len; i++) {
- this.setAttribute('data-input-' + actions[i], id);
- }
- } else {
- inputApi = $.data[id];
- }
- inputApis.push(inputApi);
- });
- return inputApis.length === 1 ? inputApis[0] : inputApis;
- };
- $.ready(function() {
- $('.mui-input-row input').input();
- });
- })(mui, window, document);
- (function($, window) {
- var CLASS_ACTIVE = 'mui-active';
- var rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/;
- var getColor = function(colorStr) {
- var matches = colorStr.match(rgbaRegex);
- if (matches && matches.length === 5) {
- return [
- matches[1],
- matches[2],
- matches[3],
- matches[4]
- ];
- }
- return [];
- };
- var Transparent = function(element, options) {
- this.element = element;
- this.options = $.extend({
- top: 0, //距离顶部高度(到达该高度即触发)
- offset: 150, //滚动透明距离
- duration: 16, //过渡时间
- scrollby: window//监听滚动距离容器
- }, options || {});
- this.scrollByElem = this.options.scrollby || window;
- if (!this.scrollByElem) {
- throw new Error("监听滚动的元素不存在");
- }
- this.isNativeScroll = false;
- if (this.scrollByElem === window) {
- this.isNativeScroll = true;
- } else if (!~this.scrollByElem.className.indexOf('mui-scroll-wrapper')) {
- this.isNativeScroll = true;
- }
- this._style = this.element.style;
- this._bgColor = this._style.backgroundColor;
- var color = getColor(mui.getStyles(this.element, 'backgroundColor'));
- if (color.length) {
- this._R = color[0];
- this._G = color[1];
- this._B = color[2];
- this._A = parseFloat(color[3]);
- this.lastOpacity = this._A;
- this._bufferFn = $.buffer(this.handleScroll, this.options.duration, this);
- this.initEvent();
- } else {
- throw new Error("元素背景颜色必须为RGBA");
- }
- };
- Transparent.prototype.initEvent = function() {
- this.scrollByElem.addEventListener('scroll', this._bufferFn);
- if (this.isNativeScroll) { //原生scroll
- this.scrollByElem.addEventListener($.EVENT_MOVE, this._bufferFn);
- }
- }
- Transparent.prototype.handleScroll = function(e) {
- var y = window.scrollY;
- if (!this.isNativeScroll && e && e.detail) {
- y = -e.detail.y;
- }
- var opacity = (y - this.options.top) / this.options.offset + this._A;
- opacity = Math.min(Math.max(this._A, opacity), 1);
- this._style.backgroundColor = 'rgba(' + this._R + ',' + this._G + ',' + this._B + ',' + opacity + ')';
- if (opacity > this._A) {
- this.element.classList.add(CLASS_ACTIVE);
- } else {
- this.element.classList.remove(CLASS_ACTIVE);
- }
- if (this.lastOpacity !== opacity) {
- $.trigger(this.element, 'alpha', {
- alpha: opacity
- });
- this.lastOpacity = opacity;
- }
- };
- Transparent.prototype.destory = function() {
- this.scrollByElem.removeEventListener('scroll', this._bufferFn);
- this.scrollByElem.removeEventListener($.EVENT_MOVE, this._bufferFn);
- this.element.style.backgroundColor = this._bgColor;
- this.element.mui_plugin_transparent = null;
- };
- $.fn.transparent = function(options) {
- options = options || {};
- var transparentApis = [];
- this.each(function() {
- var transparentApi = this.mui_plugin_transparent;
- if (!transparentApi) {
- var top = this.getAttribute('data-top');
- var offset = this.getAttribute('data-offset');
- var duration = this.getAttribute('data-duration');
- var scrollby = this.getAttribute('data-scrollby');
- if (top !== null && typeof options.top === 'undefined') {
- options.top = top;
- }
- if (offset !== null && typeof options.offset === 'undefined') {
- options.offset = offset;
- }
- if (duration !== null && typeof options.duration === 'undefined') {
- options.duration = duration;
- }
- if (scrollby !== null && typeof options.scrollby === 'undefined') {
- options.scrollby = document.querySelector(scrollby) || window;
- }
- transparentApi = this.mui_plugin_transparent = new Transparent(this, options);
- }
- transparentApis.push(transparentApi);
- });
- return transparentApis.length === 1 ? transparentApis[0] : transparentApis;
- };
- $.ready(function() {
- $('.mui-bar-transparent').transparent();
- });
- })(mui, window);
- /**
- * 数字输入框
- * varstion 1.0.1
- * by Houfeng
- * Houfeng@DCloud.io
- */
- (function($) {
- var touchSupport = ('ontouchstart' in document);
- var tapEventName = touchSupport ? 'tap' : 'click';
- var changeEventName = 'change';
- var holderClassName = 'mui-numbox';
- var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus';
- var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus';
- var inputClassSelector = '.mui-input-numbox,.mui-numbox-input';
- var Numbox = $.Numbox = $.Class.extend({
- /**
- * 构造函数
- **/
- init: function(holder, options) {
- var self = this;
- if (!holder) {
- throw "构造 numbox 时缺少容器元素";
- }
- self.holder = holder;
- options = options || {};
- options.step = parseInt(options.step || 1);
- self.options = options;
- self.input = $.qsa(inputClassSelector, self.holder)[0];
- self.plus = $.qsa(plusClassSelector, self.holder)[0];
- self.minus = $.qsa(minusClassSelector, self.holder)[0];
- self.checkValue();
- self.initEvent();
- },
- /**
- * 初始化事件绑定
- **/
- initEvent: function() {
- var self = this;
- self.plus.addEventListener(tapEventName, function(event) {
- var val = parseInt(self.input.value) + self.options.step;
- self.input.value = val.toString();
- $.trigger(self.input, changeEventName, null);
- });
- self.minus.addEventListener(tapEventName, function(event) {
- var val = parseInt(self.input.value) - self.options.step;
- self.input.value = val.toString();
- $.trigger(self.input, changeEventName, null);
- });
- self.input.addEventListener(changeEventName, function(event) {
- self.checkValue();
- var val = parseInt(self.input.value);
- //触发顶层容器
- $.trigger(self.holder, changeEventName, {
- value: val
- });
- });
- },
- /**
- * 获取当前值
- **/
- getValue: function() {
- var self = this;
- return parseInt(self.input.value);
- },
- /**
- * 验证当前值是法合法
- **/
- checkValue: function() {
- var self = this;
- var val = self.input.value;
- if (val == null || val == '' || isNaN(val)) {
- self.input.value = self.options.min || 0;
- self.minus.disabled = self.options.min != null;
- } else {
- var val = parseInt(val);
- if (self.options.max != null && !isNaN(self.options.max) && val >= parseInt(self.options.max)) {
- val = self.options.max;
- self.plus.disabled = true;
- } else {
- self.plus.disabled = false;
- }
- if (self.options.min != null && !isNaN(self.options.min) && val <= parseInt(self.options.min)) {
- val = self.options.min;
- self.minus.disabled = true;
- } else {
- self.minus.disabled = false;
- }
- self.input.value = val;
- }
- },
- /**
- * 更新选项
- **/
- setOption: function(name, value) {
- var self = this;
- self.options[name] = value;
- },
- /**
- * 动态设置新值
- **/
- setValue: function(value) {
- this.input.value = value;
- this.checkValue();
- }
- });
- $.fn.numbox = function(options) {
- var instanceArray = [];
- //遍历选择的元素
- this.each(function(i, element) {
- if (element.numbox) {
- return;
- }
- if (options) {
- element.numbox = new Numbox(element, options);
- } else {
- var optionsText = element.getAttribute('data-numbox-options');
- var options = optionsText ? JSON.parse(optionsText) : {};
- options.step = element.getAttribute('data-numbox-step') || options.step;
- options.min = element.getAttribute('data-numbox-min') || options.min;
- options.max = element.getAttribute('data-numbox-max') || options.max;
- element.numbox = new Numbox(element, options);
- }
- });
- return this[0] ? this[0].numbox : null;
- }
- //自动处理 class='mui-locker' 的 dom
- $.ready(function() {
- $('.' + holderClassName).numbox();
- });
- }(mui));
- /**
- * Button
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @returns {undefined}
- */
- (function($, window, document) {
- var CLASS_ICON = 'mui-icon';
- var CLASS_DISABLED = 'mui-disabled';
- var STATE_RESET = 'reset';
- var STATE_LOADING = 'loading';
- var defaultOptions = {
- loadingText: 'Loading...', //文案
- loadingIcon: 'mui-spinner' + ' ' + 'mui-spinner-white', //图标,可为空
- loadingIconPosition: 'left' //图标所处位置,仅支持left|right
- };
- var Button = function(element, options) {
- this.element = element;
- this.options = $.extend({}, defaultOptions, options);
- if (!this.options.loadingText) {
- this.options.loadingText = defaultOptions.loadingText;
- }
- if (this.options.loadingIcon === null) {
- this.options.loadingIcon = 'mui-spinner';
- if ($.getStyles(this.element, 'color') === 'rgb(255, 255, 255)') {
- this.options.loadingIcon += ' ' + 'mui-spinner-white';
- }
- }
- this.isInput = this.element.tagName === 'INPUT';
- this.resetHTML = this.isInput ? this.element.value : this.element.innerHTML;
- this.state = '';
- };
- Button.prototype.loading = function() {
- this.setState(STATE_LOADING);
- };
- Button.prototype.reset = function() {
- this.setState(STATE_RESET);
- };
- Button.prototype.setState = function(state) {
- if (this.state === state) {
- return false;
- }
- this.state = state;
- if (state === STATE_RESET) {
- this.element.disabled = false;
- this.element.classList.remove(CLASS_DISABLED);
- this.setHtml(this.resetHTML);
- } else if (state === STATE_LOADING) {
- this.element.disabled = true;
- this.element.classList.add(CLASS_DISABLED);
- var html = this.isInput ? this.options.loadingText : ('<span>' + this.options.loadingText + '</span>');
- if (this.options.loadingIcon && !this.isInput) {
- if (this.options.loadingIconPosition === 'right') {
- html += ' <span class="' + this.options.loadingIcon + '"></span>';
- } else {
- html = '<span class="' + this.options.loadingIcon + '"></span> ' + html;
- }
- }
- this.setHtml(html);
- }
- };
- Button.prototype.setHtml = function(html) {
- if (this.isInput) {
- this.element.value = html;
- } else {
- this.element.innerHTML = html;
- }
- }
- $.fn.button = function(state) {
- var buttonApis = [];
- this.each(function() {
- var buttonApi = this.mui_plugin_button;
- if (!buttonApi) {
- var loadingText = this.getAttribute('data-loading-text');
- var loadingIcon = this.getAttribute('data-loading-icon');
- var loadingIconPosition = this.getAttribute('data-loading-icon-position');
- this.mui_plugin_button = buttonApi = new Button(this, {
- loadingText: loadingText,
- loadingIcon: loadingIcon,
- loadingIconPosition: loadingIconPosition
- });
- }
- if (state === STATE_LOADING || state === STATE_RESET) {
- buttonApi.setState(state);
- }
- buttonApis.push(buttonApi);
- });
- return buttonApis.length === 1 ? buttonApis[0] : buttonApis;
- };
- })(mui, window, document);
|