h5怎么引serve static模块块

没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!深入理解html5中的position
原创
841
摘要:static:静态定位。如果你没有设置position属性,那么缺省就是static。top,left,bottom,right等属性,在static的情况下是无效的,要使用这些属性,必须把position设置为其他三个值之一。
CSS的Position很重要,position一共有4个属性值,就是以下几个值:                static,relative,absolute,fixed。元素的位置通过 &left&, &top&, &right& 以及 &bottom& 属性进行规定,显示层级通过z-index控制。static:静态定位。如果你没有设置position属性,那么缺省就是static。top,left,bottom,right等属性,在static的情况下是无效的,要使用这些属性,必须把position设置为其他三个值之一。relative:relative 元素遵循正常的文档流,所以周围元素不会忽略它的存在,relative 元素同样支持 top,bottom,left,right等属性。当我们使用 top,bottom,left,right等属性对 relative 元素进行相对定位时的效果有点类似于 margin 属性达到的效果,但是区别在于, relative 元素周围的元素将会忽略 relative 元素的移动# p
background:# width:200 height:200
position: left:200 top:200px
}absolute:absolute 元素将会脱离正常的文档流,所以 其周围的元素将会忽略它的存在。如同 absolute 元素的 display 属性被设为了 none 一样。此时,我们可以使用 top,bottom,left,right 等属性对 absolute 元素进行绝对定位。一般情况下定义两个属性,top 或 bottom,left 或 right。# p
background:# width:200 height:200
position: left:200 top:200px
}fixed:固定定位。元素将被设置在浏览器上一个固定位置上,不会随其他元素滚动。形象点说,上下拉动滚动条的时候,fixed的元素在屏幕上的位置不变。需要注意的是IE6并不支持此属性。首先,fixed 元素定位与它的父元素无任何关系,它永远是相对最外层的 window 进行定位的。第二,fixed 元素正如它的名字一样,它是固定在屏幕的某个位置,它不会因为屏幕的滚动而消失。# p
background:# width:200 height:200
position: left:200 top:200px
}position属性在CSS布局中是至关重要的,真正的了解了position属性会对今后学习p加CSS有很大的帮助以上就是深入理解html5中的position的详细内容,更多请关注php中文网其它相关文章!
江湖传言:PHP是世界上最好的编程语言。真的是这样吗?这个梗究竟是从哪来的?学会本课程,你就会明白了。
PHP中文网出品的PHP入门系统教学视频,完全从初学者的角度出发,绝不玩虚的,一切以实用、有用...
ThinkPHP是国内最流行的中文PHP开发框架,也是您Web项目的最佳选择。《php.cn独孤九贱(5)-ThinkPHP5视频教程》课程以ThinkPHP5最新版本为例,从最基本的框架常识开始,将...
本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目。
所有计算机语言的学习都要从基础开始,《PHP入门视频教程之一周学会PHP》不仅是PHP的基础部分更主要的是PHP语言的核心技术,是学习PHP必须掌握的内容,任何PHP项目的实现都离不开这部分的内容,通...
《php.cn原创html5视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了HTML知识。
本课以最新版ThinkPHP5.0.10为基础进行开发,全程实录一个完整企业点,从后台到前台,从控制器到路由的全套完整教程,不论是你是新人,还是有一定开发经验的程序员,都可以从中学到实用的知识~~
ThinkPHP是一个快速、开源的轻量级国产PHP开发框架,是业内最流行的PHP框架之一。本课程以博客系统为例,讲述如何使用TP实战开发,从中学习Thinkphp的实践应用。模版下载地址:http:/...
本课程是php实战开发课程,以爱奇艺电影网站为蓝本从零开发一个自己的网站。目的是让大家了解真实项目的架构及开发过程
本课以一个极简的PHP开发框架为案例,向您展示了一个PHP框架应该具有的基本功能,以及具体的实现方法,让您快速对PHP开发框架的底层实现有一个清楚的认识,为以后学习其实的开发框架打下坚实的基础。
javascript是运行在浏览器上的脚本语言,连续多年,被评为全球最受欢迎的编程语言。是前端开发必备三大法器中,最具杀伤力。如果前端开发是降龙十八掌,好么javascript就是第18掌:亢龙有悔。...
本站9月直播课已经结束,本套教程是直播实录,没有报上名或者漏听学员福利来了,赶紧看看吧,说不定这里就有你的菜
轻松明快,简洁生动,让你快速走入HTML5的世界,体会语义化开发的魅力
《php用户注册登录系统》主要介绍网站的登录注册功能,我们会从最简单的实现登录注册功能开始,增加验证码,cookie验证等,丰富网站的登录注册功能
Bootstrap 是最受欢迎的 HTML、CSS 和 JS 框架,用于开发响应式布局、移动设备优先的 WEB 项目。为所有开发者、所有应用场景而设计,它让前端开发更快速、简单,所有开发者都能快速上手...
JavaScript能够称得上是史上使用最广泛的编程语言,也是前端开发必须掌握的三技能之一:描述网页内容的HTML、描述网页样式的CSS以及描述网页行为的JavaScript。本章节将帮助大家迅速掌握...
《PHP学生管理系统视频教程》主要给大家讲解了HTML,PHP,MySQL之间的相互协作,实现动态的网页显示和获取数据.
《php.cn独孤九贱(2)-css视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了CSS知识...
《弹指间学会HTML视频教程》从最基本的概念开始讲起,步步深入,带领大家学习HTML,了解各种常用标签的意义以及基本用法,学习HTML知识为以后的学习打下基础
jQuery是一个快速、简洁的JavaScript框架。设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的...
《最新微信小程序开发视频教程》本节课程是由微趋道录制,讲述了如何申请一个微信小程序,以及开发中需要使用哪些工具,和需要注意哪些等。
文章总浏览数在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
做一个活动,在app里嵌入一个H5页面。
如何让用户点击H5页面上的按钮跳转到APP的另一个页面?
比如说点击H5页面上的充值按钮,跳转到充值界面(这个页面是APP原生的),点击立即抢购按钮,跳转到商品页面(这个页面是APP原生的)。
H5与APP端是如何进行数据交互的?
后台该如何写?
有没有例子?
请大牛之支招。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
上看到的,你看行不行.
webview.addJavascriptInterface(new Object() {
@JavascriptInterface
public void openActivity(String activity){
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(activity));
mContext.startActivity(i);
}, "android");
&a href="javascript:void(0)" onclick="alert(android.openActivity('Recharge'))"&充值&/a&
&a href="javascript:void(0)" onclick="alert(android.openActivity('Goods'))"&抢购&/a&
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
Android端,WebView加载H5,H5中js代码可以这样:
&script type="text/javascript"&
function jumpToAppPages(){
toActivity.OpenLinkH5("https://www.baidu.com");
在当前WebView所在Activity这样写:
mWebViewContent.addJavascriptInterface(new JumpAppInterFace(mContext),"toActivity");
其中,JumpAppInterFace 就是你需要注入的跳转到另一Activity的类,大致长这样:
public class JumpAppInterFace {
private static final String TAG = "JumpAppInterFace";
private android.content.Context C
public JumpAppInterFace(android.content.Context Context) {
this.Context = C
@JavascriptInterface
public void OpenLinkH5(String url){
if (!TextUtil.isEmpty(url)){
Intent intent=new Intent(Context, AnotherActivity.class);
intent.putExtra("url",url);
Context.startActivity(intent);
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
上面几个方法都挺不错的。但其实只是单纯跳转问题,不用搞得那么复杂。从webview中抓取跳转信息,然后android端和前段商量好接口,就直接处理就好了。例如:web中有个跳转
&a href="example://jumpToSettings"&跳转设置&/a&
点击后会出发webview中的shouldOverrideUrlLoading函数,Android端:
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
L.i(url); // 获取到 example://jumpToSettings ,然后接下来就是字符串处理了
optionUrl(url); // 判断如果是跳转字符串,进行跳转
// 消费,不让网页跳转
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
JavaScriptCore网上很多例子的,apple文档也很详细
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。文档中心 | QuickSDK——专业的手游第三方SDK接入服务平台,渠道SDK聚合,广告跟踪,客服,登录充值SDK
免费聚合全球700余家渠道SDK,一次接入批量出包,100%上架。
QuickGame SDK国内版助力手游开发商快速拥有自主发行的能力。
QuickGame SDK海外版帮助发行商快速搭建海外自主发行平台。
检测广告效果,提供结算依据,优化投放策略为用户提供真实的广告监测数据
游戏客服服务、重度玩家跟踪、玩家情感分析、提升玩家忠诚度和参与度。
分析玩家行为数据,提升运营效果,用数据推动业务增长。
H5转渠道版接入文档
1.流程描述
QuickSDK-H5 是一套建立在H5手游和游戏渠道之间的接入中间件,用以统一各H5渠道、Android渠道、iOS渠道的差异化,游戏研发只需接入QuickSDK即可和本地游戏一样直接上线所有Andorid渠道、iOS渠道.
区别与H5网页版接入方式,此种接入方式因为最终调用的登录支付为渠道的安卓、iOS代码故需要打包后方可运行,不能直接在PC浏览器上运行.
QuickSDK的工作流程如下:
& &· 在QuickSDK后台创建对应平台的产品。
& &· 添加键名为 "H5GameUrl" 的产品自定义参数(参见《如何创建使用自定义参数》).
& &· 游戏研发同学按照本文档接入登录、支付、服务器通知等接口
& &· 运营同学在QuickSDK后台添加配置各渠道参数,各渠道中的H5GameUrl参数即为该渠道实际的游戏地址.
& &· 运营同学使用QuickSDK打包工具一健打出Android各渠道的apk包。
QuickSDK登录流程如下:
& &· 游戏加载完成后,调用QuickSDK.login(callback) 方法,此方法会调起各渠道的登录界面。
& &· 用户完成登录后,游戏传入的callback回调方法会被调用,调用时QuickSDK会传入用户信息对象。
& &· 游戏获取对象的用户UID等信息,完成对用户的授权
QuickSDK支付流程如下:
& &· 当用户在游戏点击购买,游戏可调用QuickSDK.pay(orderInfo,callback)方法调起各自渠道的支付页面.
& &· 当用户完成购买够,QuickSDK会向游戏事前配置的发送地址POST数据.
& &· 游戏服务器接收到QuickSDK服务器通知后,根据通知内容向用户发送道具.
& &· 游戏客户端也可以从callback中渠道支付通知,但此通知仅做UI展示,不能作为发货依据.
2.游戏接入
2.1 引用JS类库
& & &在游戏页面引入QuickSDK的JS类库
& & &http://h5.sdk.quicksdk.net/static/lib/libQuickSDKH5_To_Client.js&
或 https://sdkapi02.quicksdk.net/static/lib/libQuickSDKH5_To_Client.js
2.2 初始化QuickSDK.
游戏应调用QuickSDK的init接口,同时传入QuickSDK后台分配给游戏的参数.
var productCode = '';
//QuickSDK后台自动分配
var productKey = '';
//QuickSDK后台自动分配
QuickSDK.init(productCode,productKey,true);
2.3 主动调用登录接口
& &针对H5投放平台,QuickSDK会默认生成游客帐号,登录不是必须的,游戏可根据自身情况调用登录接口要求用户完成登录.
& &针对Android/iOS平台,由于受渠道审核限制,游戏必须在游戏开始时自动调用登录接口。
& &调用QuickSDK的login方法示例如下:
QuickSDK.login(function(callbackData){
if(callbackData.status){
message = 'GameDemo:QuickSDK登录成功: uid=&' + callbackData.data.
message = 'GameDemo:QuickSDK登录失败:' + callbackData.
document.getElementById('loginMessage').innerHTML =
调用后,会触发回调函数.
回调的callbackData对象类型如下:
是否登录成功,true成功,false失败
渠道Username
游戏服务器需通过v2/checkUserInfo接口(参见服务器接口文档)验证token和UID的正确性
是否游客,登录后此值为true
status为false时,此字段为Failed表示登录失败,为cancel表示玩家取消登录
JSON表现如下:
{“status”:true,”data”:{“uid”:”123”,”username”:”quicksdk”,”token”:””,”isLogin”:true},”message”:”登录成功”}
&除主动调用登录后,游戏同时需处理切换帐号的回调通知.注册切换帐号的回调方法如下:
QuickSDK.setSwitchAccountNotification(function(callbackData){
此回调回在玩家切换帐号后触发,参数格式和登录回调一致,游戏需重新完成玩家信息认证操作.
2.4 调用支付接口
用户点击购买时,游戏可调用pay方法传入orderInfo对象调起支付页面.
调用示例如下:
var orderInfo = new Object();
orderInfo.productCode = “”;
orderInfo.uid = “uid”;
orderInfo.userRoleId = 'roleId1';
orderInfo.userRoleName = '小朋友';
orderInfo.userServer = '内测1区';
orderInfo.userLevel = 1;
orderInfo.cpOrderNo = 'cpOrderNo000001';
orderInfo.amount = '0.01';
orderInfo.subject = '大袋钻石';
orderInfo.desc = '一大袋钻石60个';
orderInfo.callbackUrl = '';
orderInfo.extrasParams = '';
orderInfo.goodsId = '';
orderInfo.count = 60;
orderInfo.quantifier = '个';
var orderInfoJson = JSON.stringify(orderInfo);
QuickSDK.pay(orderInfoJson,function(payStatusObject){
console.log('GameDemo:下单通知' + JSON.stringify(payStatusObject));
支付后,可触发回调函数,函数中可获取是否支付成功,但需要注意,此结果仅仅作为UI展示(或完全不用),发货应以服务器通知为准.
orderInfo对象如下:
productCode
QuickSDK后台自动分配的参数
渠道username
userRoleId
游戏内角色ID
userRoleName
userServer
角色所在区服
游戏内的订单,服务器通知中会回传
购买商品个数
quantifier
购买商品单位,如,个
callbackUrl
服务器通知地址
extrasParams
透传参数,服务器通知中原样回传
回调函数payStatusObject对象中status为true时为支付成功.
服务器通知接口参见《》
2.5 调用/注册退出接口
调用退出接口调用示例:
QuickSDK.logout(function(logoutObject){console.log('Game:成功退出游戏');})
logoutObject对象包含status和message属性.
注册退出接口示例:
QuickSDK.setLogoutNotification(function(logoutObject){console.log('Game:玩家点击注销帐号');})
此回调会在玩家主动在渠道SDK中点击注销或切换帐号时触发
2.6 上传角色信息接口
游戏需要在玩家登录或角色发生变化调用此接口.
调用示例如下:
function uploadGameRoleInfo(){
var roleInfo = new Object();
roleInfo.isCreateRole =
roleInfo.roleCreateTime = ;
roleInfo.serverId = 1;
roleInfo.serverName = '内测1区';
roleInfo.userRoleName = '小朋友';
roleInfo.userRoleId = 'roleId1';
roleInfo.userRoleBalance = 1000;
roleInfo.vipLevel = 1;
roleInfo.userRoleLevel = 1;
roleInfo.partyId = 1;
roleInfo.partyName = '行会名称';
roleInfo.gameRoleGender = '男';
roleInfo.gameRolePower = 100;
roleInfo.partyRoleId = 1;
roleInfo.partyRoleName = '会长';
roleInfo.professionId = '1';
roleInfo.profession = '武士';
roleInfo.friendlist ='';
var roleInfoJson = JSON.stringify(roleInfo);
QuickSDK.uploadGameRoleInfo(roleInfoJson,function(response){
if(response.status){
document.getElementById('uploadMessage').innerHTML = '提交信息成功';
document.getElementById('uploadMessage').innerHTML = response.
roleInfo对象字段如下
isCreateRole
仅创建角色时传true,更新信息时传false
roleCreateTime
角色创建时间
serverName
userRoleId
游戏内角色ID
userRoleName
userRoleBalance
角色游戏内货币余额
角色VIP等级
userRoleLevel
公会/社团ID
公会/社团名称
gameRoleGender
gameRolePower
partyRoleId
角色在帮派中的ID
partyRoleName
角色在帮派中的名称
professionId
角色职业ID
profession
角色职业名称
friendlist
角色好友列表
2.7 其他接口&
& & & & & &1.QuickSDK.getChannelType(); & &获取渠道ID
& & & & & &2.QuickSDK.getExtrasConfig(key); & &获取后台配置的产品自定义参数
& & & & & &3.QuickSDK.setOnResumeNotification(callback) ; 注册恢复home键时通知
& & & & & &4.QuickSDK.setOnStopNotification(callback); 注册按下home键时通知
另附QuickSDK-H5转APK后台配置流程:https://www.quicksdk.com/doc-213.html
成都极娱网络科技有限公司
&&|&&川网文[4
官方技术交流群项目语言:JAVASCRIPT
权限:read-only(如需更高权限请先加入项目)
Index: readme.md
===================================================================
--- readme.md (revision 0)
+++ readme.md (revision 2)
@@ -0,0 +1,304 @@
+# detector
+客户端信息识别模块,用于自动识别用户使用的客户端环境。包括:
+1. 硬件设备。
+2. 操作系统。
+3. 浏览器。
+4. 浏览器渲染引擎。
+## 使用说明
+### 外链形式
+&script src=&{{src}}&&&/script&
+if (detector.browser.ie) {
console.log('您使用的是IE浏览器');
+&/script&
+### 模块加载形式
require(['{{module}}'], function(detector) {
if(detector.browser.ie && detector.browser.version & 8){
alert(&你的浏览器太老了。&);
+&/script&
+## 信息结构
+识别到的信息结构如下:
+```javascript
+detector = {
name: &iphone&,
version: -1,
fullVersion: &-1&,
[iphone]: -1
name: &ios&,
version: 6.1,
fullVersion: &6.1&,
[ios]: 6.1
browser: {
name: &chrome&:
version: 26.0,
fullVersion: &26.0.1410.50&,
mode: 26.0,
fullMode: &26.0.1410.50&,
compatible: false,
[chrome]: 26.0
name: &webkit&,
version: 536.26,
fullVersion: &536.26&,
mode: 523.26,
fullMode: &523.26&,
compatible: false,
[webkit]: 536.26
+备注:上面的 `[iphone]`, `[ios]`, `[chrome]`, `[webkit]` 是动态的,根据实际识别
+到的信息不同而有所不同。
+* 有些场景只需要简单识别特定的信息,可以参考 [识别特定浏览器最佳实践](docs:best_practice.md) 而无需使用 detector。
+* 也可以使用 QW.Core 模块提供的轻量级[浏览器 UA 检测](detail.html?name=QW.Core&path=qwrap-core/1.1.5&ver=1.1.5#_%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AF%86%E5%88%AB)。
+## 使用范例
+一般情况下,常见使用范例:
+```javascript
+// 判断浏览器名
+detector.browser.name === &chrome& // true
+// 判断浏览器名方法 2.
+!!detector.browser.ie // false
+// 判断老旧浏览器
+if(detector.browser.ie && detector.browser.version & 8){
alert(&你的浏览器太老了。&);
+// 判断 Trident 4(IE8) 以下版本浏览器引擎
+if(detector.engine.trident && detector.engine.mode & 4){
// hack code.
+// 收集客户端详细信息
+detector.browser.name + &/& + detector.browser.fullV
+### detector.device.name *{{String}}*
+设备名称。
+### detector.device.version *{{Number}}*
+设备版本号。
+### detector.device.fullVersion *{{String}}*
+设备完整版本号。
+### detector.device[device_name] *{{Number}}*
+直接判断设备名。
+可以识别的设备名称为:
+* `pc`: Windows PC.
+* `mac`: Macintosh PC.
+* `iphone`: iPhone.
+* `ipad`: iPad.
+* `ipod`: iPod.
+* `android`: Android.
+* `blackberry`: 黑莓(Blackberry)手机。
+* `wp`: Windows Phone.
+* `mi`: 小米。
+* `meizu`: 魅族。
+* `nexus`: Nexus.
+* `nokia`: Nokia.
+* `samsung`: 三星手机。
+* `aliyun`: 阿里云手机。
+* `huawei`: 华为手机。
+* `lenovo`: 联想手机。
+* `zte`: 中兴手机。
+* `vivo`: 步步高手机。
+* `htc`: HTC。
+* `oppo`: OPPO 手机。
+* `konka`: 康佳手机。
+* `sonyericsson`: 索尼爱立信手机。
+* `coolpad`: 酷派手机。
+* `lg`: LG 手机。
+### detector.os.name *{{String}}*
+操作系统名。
+### detector.os.version *{{Number}}*
+操作系统版本号。
+### detector.os.fullVersion *{{String}}*
+操作系统完整版本号。
+### detector.os[os_name] *{{Number}}*
+直接判断操作系统。
+可以识别的操作系统包括:
+* `windows`: Windows.
+* `macosx`: Macintosh.
+* `ios`: iOS.
+* `android`: Android.
+* `chromeos`: Chrome OS.
+* `linux`: Linux.
+* `wp`: Windows Phone.
+* `windowsce`: Windows CE, 包括 Windows Mobile, Smartphone, PPC.
+* `symbian`: Symbian OS.
+* `blackberry`: Blackberry.
+* `yunos`: 阿里云系统。
+* `meego`: Meego
+### detector.browser.name *{{String}}*
+浏览器名。
+### detector.browser.version *{{Number}}*
+浏览器真实版本。兼容模式下浏览器声明自己是某老旧浏览器,但这个属性返回的是
+其真正的版本号。
+适用于收集统计分析客户端信息。
+IE9 兼容模式声明自己是 IE7,但是 `detector.browser.version` 返回 `9.0`
+### detector.browser.fullVersion *{{String}}*
+浏览器完整的真实版本号。
+### detector.browser.mode *{{Number}}*
+浏览器模式。即浏览器当时使用的模式,IE 兼容模式时,version 和 mode 值不同。
+### detector.browser.fullMode *{{String}}*
+浏览器模式的完整版本号。
+### detector.browser[browser_name] *{{Number}}*
+直接判断浏览器。
+可以识别的浏览器为:
+* `ie`: Microsoft Internet Explorer.
+* `chrome`: Google Chrome.
+* `firefox`: Mozilla Firefox.
+* `safari`: Apple Safari.
+* `opera`: Opera.
+* `360`: 包括奇虎 360 安全浏览器和 360 极速浏览器。
+* `mx`: 傲游浏览器(Maxthon)。
+* `sg`: 搜狗浏览器(Sogou)。
+* `tw`: 世界之窗浏览器(TheWorld)。
+* `green`: GreenBrowser.
+* `qq`: QQ 浏览器。
+* `tt`: TencentTraveler.
+* `lb`: 猎豹浏览器。
+* `tao`: 淘宝浏览器。
+* `fs`: 枫树浏览器。
+* `sy`: 闪游浏览器。
+* `uc`: UC 浏览器。
+* `mi`: 小米浏览器。
+* `baidu`: 百度浏览器。
+* `nokia`: 诺基亚浏览器。
+* `webview`: iOS 系统的提供的 WebView。
+国产浏览器名称均使用缩写方式,`ie` 由于习俗也使用缩写。
+### detector.browser.compatible *{{Boolean}}*
+浏览器是否处于兼容模式。
+### detector.engine.name *{{String}}*
+渲染引擎名(又称排版引擎、浏览器内核)。
+### detector.engine.version *{{Number}}*
+渲染引擎版本号。
+### detector.engine.fullVersion *{{String}}*
+渲染引擎完整版本号。
+### detector.engine.mode *{{Number}}*
+渲染引擎模式,即 IE 浏览器的文档模式。
+### detector.engine.fullMode *{{String}}*
+渲染引擎模式完整版本号。
+### detector.engine[engine_name] *{{Number}}*
+直接判断渲染引擎。
+可以识别的渲染引擎为:
+* `trident`: Trident.
+* `webkit`: Webkit.
+* `gecko`: Gecko.
+* `presto`: Presto.
+* `androidwebkit`: Android Webkit.
+* `coolpadwebkit`: Coolpad Webkit.
+### detector.parse(String ua) *{{detector}}*
+根据 userAgent 字符串识别客户端信息的接口。
+服务端程序可以使用这个接口识别客户端信息,由于服务端程序的特殊性,可以补充更完善的检测规则。
+对于不能识别的信息,统一如下:
+* 所有不能识别的名称均归类为 `na`,即 Not Available.
+* 所有不能识别的版本号归类为 `-1`。
Index: examples/demo1.md
===================================================================
--- examples/demo1.md (revision 0)
+++ examples/demo1.md (revision 2)
@@ -0,0 +1,113 @@
+# 演示文档
+您正在使用:
+&pre id=&detector&&&/pre&
+&pre id=&ua&&&/pre&
+&script type=&text/javascript&&
function isObject(obj){
return Object.prototype.toString.call(obj) === &[object Object]&;
function expandObject(obj){
if(!isObject(obj)){}
var s = '{';
for(var k in obj){
if(obj.hasOwnProperty(k)){
s += k + ':' + typeof obj[k] + ',';
s += '}';
require(['{{module}}'], function(detector) {
var OS_ALIAS = {
&windows/4&:
&Windows 95&,
&windows/4.1&: &Windows 98&,
&windows/4.9&: &Windows ME&,
&windows/5&:
&Windows 2000&,
&windows/5.1&:
&Windows XP&,
&windows/5.2&:
&Windows Server 2003&,
&windows/6&:
&Windows Vista&,
&windows/6.1&:
&Windows 7&,
&windows/6.2&:
&Windows 8&,
&windows/6.3&:
&Windows 8.1&,
&macosx/10&: &Mac OS X Cheetah&,
&macosx/10.1&: &Mac OS X Puma&,
&macosx/10.2&: &Mac OS X Jaguar&,
&macosx/10.3&: &Mac OS X Panther&,
&macosx/10.4&: &Mac OS X Tiger&,
&macosx/10.5&: &Mac OS X Leopard&,
&macosx/10.6&: &Mac OS X Snow Leopard&,
&macosx/10.7&: &Mac OS X Lion&,
&macosx/10.8&: &Mac OS X Mountain Lion&,
&macosx/10.9&: &Mac OS X Mavericks&
var detectedInfo = [];
detectedInfo.push(&* 硬件设备:&+detector.device.name+& &+detector.device.fullVersion);
var osAlias = OS_ALIAS[detector.os.name+&/&+detector.os.version] || &N/A&;
detectedInfo.push(&* 操作系统:&+detector.os.name+& &+detector.os.fullVersion + & (&+osAlias+&)&);
detectedInfo.push(&* 浏览器:&+detector.browser.name+& &+detector.browser.fullVersion+
(detector.browser.compatible ? &(& + String(detector.browser.fullMode) + & 兼容模式)& : &&));
detectedInfo.push(&* 渲染引擎:& + detector.engine.name + & & + detector.engine.fullVersion +
(detector.engine.compatible ? &(& + String(detector.engine.fullMode) + & 兼容模式)& : &&));
document.getElementById(&detector&).innerHTML = detectedInfo.join(&&br /&&);
if(!window.external){
ext = &undefined&;
}if(Object.prototype.toString.call(window.external)===&[object Object]&){
for(var k in window.external){
ext.push(k+&: &+typeof(window.external[k])+
(window.external.hasOwnProperty(k)?&&:&[prototype]&));
}catch(ex){window.console && console.log(&1. &+k+&:&+ex.message);}
ext = &{&+ext.join(&, &)+&}&;
ext = window.external +&[&+typeof(window.external)+&]&;
var info = {
ua : navigator.userAgent,
vendor : navigator.vendor,
vendorSub : navigator.vendorSub,
platform : navigator.platform,
external : ext,
appCodeName : navigator.appCodeName,
appName : navigator.appName,
appVersion : navigator.appVersion,
product : navigator.product,
productSub : navigator.productSub,
screenWidth : screen.width,
screenHeight : screen.height,
colorDepth : screen.colorDepth,
documentMode: document.documentMode,
compatMode: document.compatMode
&| 字段 | 值 |&,
&|------|----|&
for(var k in info){
if(!info.hasOwnProperty(k)){}
try{ // IE10 不支持此属性或方法。。。
a.push(&| &+k+& | &+String(info[k])+& |&);
}catch(ex){window.console && console.log(&2. &+k+&:&+ex.message);}
document.getElementById(&ua&).innerHTML = a.join(&&br /&&);
+&/script&
Index: examples/index.html
===================================================================
--- examples/index.html (revision 0)
+++ examples/index.html (revision 2)
@@ -0,0 +1,23 @@
+&!doctype html&
+&html lang=&en&&
&meta charset=&UTF-8&&
&script type=&text/javascript& src=&../../../jquery/1.9.1/jquery.js&&&/script&
&script type=&text/javascript& src=&../../../require/2.1.8/require.js&&&/script&
+require.config({
baseUrl: '../../../xpc/0.2',
detect: 'detect'
+require(['detect'], function(detect) {
+&/script&
\ No newline at end of file
Index: package.json
===================================================================
--- package.json (revision 0)
+++ package.json (revision 2)
@@ -0,0 +1,8 @@
+ &name&: &Detector&,
+ &version&: &1.3.0&,
&keywords& : [&util&],
+ &maintainers&: [&梁超 &&&],
+ &description&: &全面的客户端信息识别模块。&,
+ &output&: &detector.js&
\ No newline at end of file
Index: detector.js
===================================================================
--- detector.js (revision 0)
+++ detector.js (revision 2)
@@ -0,0 +1,444 @@
+(function(root, factory) {
if(typeof exports === 'object') {
module.exports = factory();
else if(typeof define === 'function' && define.amd) {
define('module/detector/1.3.0/detector', [], factory);
root['detector'] = factory();
+}(this, function() {
+ var detector = {};
var NA_VERSION = &-1&;
var userAgent = navigator.userAgent || &&;
//var platform = navigator.platform || &&;
var appVersion = navigator.appVersion || &&;
var vendor = navigator.vendor || &&;
var external = window.
var re_msie = /\b(?:msie |ie |trident\/[0-9].*rv[ :])([0-9.]+)/;
function toString(object){
return Object.prototype.toString.call(object);
function isObject(object){
return toString(object) === &[object Object]&;
function isFunction(object){
return toString(object) === &[object Function]&;
function each(object, factory, argument){
for(var i=0,b,l=object. i&l; i++){
if(factory.call(object, object[i], i) === false){}
// 硬件设备信息识别表达式。
// 使用数组可以按优先级排序。
var DEVICES = [
[&nokia&, function(ua){
// 不能将两个表达式合并,因为可能出现 & nokia 960&
// 这种情况下会优先识别出 nokia/-1
if(ua.indexOf(&nokia &) !== -1){
return /\bnokia ([0-9]+)?/;
}else if(ua.indexOf(&noain&) !== -1){
return /\bnoain ([a-z0-9]+)/;
return /\bnokia([a-z0-9]+)?/;
// 三星有 Android 和 WP 设备。
[&samsung&, function(ua){
if(ua.indexOf(&samsung&) !== -1){
return /\bsamsung(?:\-gt)?[ \-]([a-z0-9\-]+)/;
return /\b(?:gt|sch)[ \-]([a-z0-9\-]+)/;
[&wp&, function(ua){
return ua.indexOf(&windows phone &) !== -1 ||
ua.indexOf(&xblwp&) !== -1 ||
ua.indexOf(&zunewp&) !== -1 ||
ua.indexOf(&windows ce&) !== -1;
[&pc&, &windows&],
[&ipad&, &ipad&],
// ipod 规则应置于 iphone 之前。
[&ipod&, &ipod&],
[&iphone&, /\biphone\b|\biph(\d)/],
[&mac&, &macintosh&],
[&mi&, /\bmi[ \-]?([a-z0-9 ]+(?= build))/],
[&aliyun&, /\baliyunos\b(?:[\-](\d+))?/],
[&meizu&, /\b(?:meizu\/|m)([0-9]+)\b/],
[&nexus&, /\bnexus ([0-9s.]+)/],
[&huawei&, function(ua){
if(ua.indexOf(&huawei-huawei&) !== -1){
return /\bhuawei\-huawei\-([a-z0-9\-]+)/;
return /\bhuawei[ _\-]?([a-z0-9]+)/;
[&lenovo&, function(ua){
if(ua.indexOf(&lenovo-lenovo&) !== -1){
return /\blenovo\-lenovo[ \-]([a-z0-9]+)/;
return /\blenovo[ \-]?([a-z0-9]+)/;
[&zte&, function(ua){
if(/\bzte\-[tu]/.test(ua)){
return /\bzte-[tu][ _\-]?([a-su-z0-9\+]+)/;
return /\bzte[ _\-]?([a-su-z0-9\+]+)/;
[&vivo&, /\bvivo ([a-z0-9]+)/],
[&htc&, function(ua){
if(/\bhtc[a-z0-9 _\-]+(?= build\b)/.test(ua)){
return /\bhtc[ _\-]?([a-z0-9 ]+(?= build))/;
return /\bhtc[ _\-]?([a-z0-9 ]+)/;
[&oppo&, /\boppo[_]([a-z0-9]+)/],
[&konka&, /\bkonka[_\-]([a-z0-9]+)/],
[&sonyericsson&, /\bmt([a-z0-9]+)/],
[&coolpad&, /\bcoolpad[_ ]?([a-z0-9]+)/],
[&lg&, /\blg[\-]([a-z0-9]+)/],
[&android&, &android&],
[&blackberry&, &blackberry&]
// 操作系统信息识别表达式
var OS = [
[&wp&, function(ua){
if(ua.indexOf(&windows phone &) !== -1){
return /\bwindows phone (?:os )?([0-9.]+)/;
}else if(ua.indexOf(&xblwp&) !== -1){
return /\bxblwp([0-9.]+)/;
}else if(ua.indexOf(&zunewp&) !== -1){
return /\bzunewp([0-9.]+)/;
return &windows phone&;
[&windows&, /\bwindows nt ([0-9.]+)/],
[&macosx&, /\bmac os x ([0-9._]+)/],
[&ios&, function(ua){
if(/\bcpu(?: iphone)? os /.test(ua)){
return /\bcpu(?: iphone)? os ([0-9._]+)/;
}else if(ua.indexOf(&iph os &) !== -1){
return /\biph os ([0-9_]+)/;
return /\bios\b/;
[&yunos&, /\baliyunos ([0-9.]+)/],
[&android&, /\bandroid[\/\- ]?([0-9.x]+)?/],
[&chromeos&, /\bcros i686 ([0-9.]+)/],
[&linux&, &linux&],
[&windowsce&, /\bwindows ce(?: ([0-9.]+))?/],
[&symbian&, /\bsymbian(?:os)?\/([0-9.]+)/],
[&meego&, /\bmeego\b/],
[&blackberry&, &blackberry&]
* 解析使用 Trident 内核的浏览器的 `浏览器模式` 和 `文档模式` 信息。
* @param {String} ua, userAgent string.
* @return {Object}
function IEMode(ua){
if(!re_msie.test(ua)){}
engineMode, engineVersion,
browserMode, browserVersion,
compatible=
// IE8 及其以上提供有 Trident 信息,
// 默认的兼容模式,UA 中 Trident 版本不发生变化。
if(ua.indexOf(&trident/&) !== -1){
m = /\btrident\/([0-9.]+)/.exec(ua);
if(m && m.length&=2){
// 真实引擎版本。
engineVersion = m[1];
var v_version = m[1].split(&.&);
v_version[0] = parseInt(v_version[0], 10) + 4;
browserVersion = v_version.join(&.&);
m = re_msie.exec(ua);
browserMode = m[1];
var v_mode = m[1].split(&.&);
if(&undefined& === typeof browserVersion){
browserVersion = browserM
v_mode[0] = parseInt(v_mode[0], 10) - 4;
engineMode = v_mode.join(&.&);
if(&undefined& === typeof engineVersion){
engineVersion = engineM
browserVersion: browserVersion,
browserMode: browserMode,
engineVersion: engineVersion,
engineMode: engineMode,
compatible: engineVersion !== engineMode
* 针对同源的 TheWorld 和 360 的 external 对象进行检测。
* @param {String} key, 关键字,用于检测浏览器的安装路径中出现的关键字。
* @return {Undefined,Boolean,Object} 返回 undefined 或 false 表示检测未命中。
function checkTW360External(key){
if(!external){} // return undefined.
360安装路径:
C:%5CPROGRA~1%5C360%5C360se3%5C360SE.exe
var runpath = external.twGetRunPath.toLowerCase();
// 360SE 3.x ~ 5.x support.
// 暴露的 external.twGetVersion 和 external.twGetSecurityID 均为 undefined。
// 因此只能用 try/catch 而无法使用特性判断。
var security = external.twGetSecurityID(window);
var version = external.twGetVersion(security);
if(runpath && runpath.indexOf(key) === -1){}
if(version){return {version: version};}
}catch(ex){}
var ENGINE = [
[&trident&, re_msie],
//[&blink&, /blink\/([0-9.+]+)/],
[&webkit&, /\bapplewebkit[\/]?([0-9.+]+)/],
[&gecko&, /\bgecko\/(\d+)/],
[&presto&, /\bpresto\/([0-9.]+)/],
[&androidwebkit&, /\bandroidwebkit\/([0-9.]+)/],
[&coolpadwebkit&, /\bcoolpadwebkit\/([0-9.]+)/]
var BROWSER = [
[&sg&, / se ([0-9.x]+)/],
// TheWorld (世界之窗)
// 由于裙带关系,TW API 与 360 高度重合。
// 只能通过 UA 和程序安装路径中的应用程序名来区分。
// TheWorld 的 UA 比 360 更靠谱,所有将 TheWorld 的规则放置到 360 之前。
[&tw&, function(ua){
var x = checkTW360External(&theworld&);
if(typeof x !== &undefined&){}
return &theworld&;
// 360SE, 360EE.
[&360&, function(ua) {
var x = checkTW360External(&360se&);
if(typeof x !== &undefined&){}
if(ua.indexOf(&360 aphone browser&) !== -1){
return /\b360 aphone browser \(([^\)]+)\)/;
return /\b360(?:se|ee|chrome|browser)\b/;
// Maxthon
[&mx&, function(ua){
if(external && (external.mxVersion || external.max_version)){
version: external.mxVersion || external.max_version
}catch(ex){}
return /\bmaxthon(?:[ \/]([0-9.]+))?/;
[&qq&, /\bm?qqbrowser\/([0-9.]+)/],
[&green&, &greenbrowser&],
[&tt&, /\btencenttraveler ([0-9.]+)/],
[&lb&, function(ua){
if(ua.indexOf(&lbbrowser&) === -1){}
if(external && external.LiebaoGetVersion){
version = external.LiebaoGetVersion();
}catch(ex){}
version: version || NA_VERSION
[&tao&, /\btaobrowser\/([0-9.]+)/],
[&fs&, /\bcoolnovo\/([0-9.]+)/],
[&sy&, &saayaa&],
// 有基于 Chromniun 的急速模式和基于 IE 的兼容模式。必须在 IE 的规则之前。
[&baidu&, /\bbidubrowser[ \/]([0-9.x]+)/],
// 后面会做修复版本号,这里只要能识别是 IE 即可。
[&ie&, re_msie],
[&mi&, /\bmiuibrowser\/([0-9.]+)/],
// Opera 15 之后开始使用 Chromniun 内核,需要放在 Chrome 的规则之前。
[&opera&, function(ua){
var re_opera_old = /\bopera.+version\/([0-9.ab]+)/;
var re_opera_new = /\bopr\/([0-9.]+)/;
return re_opera_old.test(ua) ? re_opera_old : re_opera_
[&chrome&, / (?:chrome|crios|crmo)\/([0-9.]+)/],
// UC 浏览器,可能会被识别为 Android 浏览器,规则需要前置。
[&uc&, function(ua){
if(ua.indexOf(&ucbrowser/&) &= 0){
return /\bucbrowser\/([0-9.]+)/;
}else if(/\buc\/[0-9]/.test(ua)){
return /\buc\/([0-9.]+)/;
}else if(ua.indexOf(&ucweb&) &= 0){
return /\bucweb[\/]?([0-9.]+)?/;
return /\b(?:ucbrowser|uc)\b/;
// Android 默认浏览器。该规则需要在 safari 之前。
[&android&, function(ua){
if(ua.indexOf(&android&) === -1){}
return /\bversion\/([0-9.]+(?: beta)?)/;
[&safari&, /\bversion\/([0-9.]+(?: beta)?)(?: mobile(?:\/[a-z0-9]+)?)? safari\//],
// 如果不能被识别为 Safari,则猜测是 WebView。
[&webview&, /\bcpu(?: iphone)? os (?:[0-9._]+).+\bapplewebkit\b/],
[&firefox&, /\bfirefox\/([0-9.ab]+)/],
[&nokia&, /\bnokiabrowser\/([0-9.]+)/]
* UserAgent Detector.
* @param {String} ua, userAgent.
* @param {Object} expression
* @return {Object}
返回 null 表示当前表达式未匹配成功。
function detect(name, expression, ua){
var expr = isFunction(expression) ? expression.call(null, ua) :
if(!expr){}
var info = {
name: name,
version: NA_VERSION,
codename: &&
var t = toString(expr);
if(expr === true){
}else if(t === &[object String]&){
if(ua.indexOf(expr) !== -1){
}else if(isObject(expr)){ // Object
if(expr.hasOwnProperty(&version&)){
info.version = expr.
}else if(expr.exec){ // RegExp
var m = expr.exec(ua);
if(m.length &= 2 && m[1]){
info.version = m[1].replace(/_/g, &.&);
info.version = NA_VERSION;
var na = {name:&na&, version:NA_VERSION};
// 初始化识别。
function init(ua, patterns, factory, detector){
var detected =
each(patterns, function(pattern){
var d = detect(pattern[0], pattern[1], ua);
detected =
factory.call(detector, detected.name, detected.version);
* 解析 UserAgent 字符串
* @param {String} ua, userAgent string.
* @return {Object}
var parse = function(ua){
ua = (ua || &&).toLowerCase();
var d = {};
init(ua, DEVICES, function(name, version){
var v = parseFloat(version);
d.device = {
name: name,
version: v,
fullVersion: version
d.device[name] =
init(ua, OS, function(name, version){
var v = parseFloat(version);
name: name,
version: v,
fullVersion: version
d.os[name] =
var ieCore = IEMode(ua);
init(ua, ENGINE, function(name, version){
var mode =
// IE 内核的浏览器,修复版本号及兼容模式。
if(ieCore){
version = ieCore.engineVersion || ieCore.engineM
mode = ieCore.engineM
var v = parseFloat(version);
d.engine = {
name: name,
version: v,
fullVersion: version,
mode: parseFloat(mode),
fullMode: mode,
compatible: ieCore ? ieCore.compatible : false
d.engine[name] =
init(ua, BROWSER, function(name, version){
var mode =
// IE 内核的浏览器,修复浏览器版本及兼容模式。
if(ieCore){
// 仅修改 IE 浏览器的版本,其他 IE 内核的版本不修改。
if(name === &ie&){
version = ieCore.browserV
mode = ieCore.browserM
var v = parseFloat(version);
d.browser = {
name: name,
version: v,
fullVersion: version,
mode: parseFloat(mode),
fullMode: mode,
compatible: ieCore ? ieCore.compatible : false
d.browser[name] =
detector = parse(userAgent + & & + appVersion + & & + vendor);
detector.parse =
Index: docs/best_practice.md
===================================================================
--- docs/best_practice.md (revision 0)
+++ docs/best_practice.md (revision 2)
@@ -0,0 +1,65 @@
+#最佳实践
+本文来源:[https://github.com/aralejs/detector/issues/18](https://github.com/aralejs/detector/issues/18)
+有时候在模块中需要针对某个特定浏览器进行识别,可以 *不需要*、或 *不希望* 依赖 `detector` 进行识别(例如 sticky 只需要识别 IE6),这里提供一些最佳实践,供需要时参考。
+## 基本原则
+1. 尽量针对特定功能使用正确的特性识别。
+1. 浏览器识别尽量使用 userAgent 信息。
+1. 不要使用不相干的特性检测。例如 isIE6 = !window.XMLHttpR
+##最佳实践
+针对 IE 或 IE 内核浏览器的代码兼容性支持:
+// 单个浏览器识别:
+var isIE6 = navigator.userAgent.indexOf(&MSIE 6.0&) !== -1;
+var isIE7 = navigator.userAgent.indexOf(&MSIE 7.0&) !== -1;
+var isIE8 = navigator.userAgent.indexOf(&MSIE 8.0&) !== -1;
+var isIE9 = navigator.userAgent.indexOf(&MSIE 9.0&) !== -1;
+var isIE10 = navigator.userAgent.indexOf(&MSIE 10.0&) !== -1;
+//!var isIE11 = navigator.userAgent.indexOf(&IE 11.0&) !== -1;
+var isIE11 = /\btrident\/[0-9].*rv[ :]11\.0/.test(navigator.userAgent);
+// 多个浏览器识别
+var isIE678 = /\bMSIE [678]\.0\b/.test(navigator.userAgent);
+针对真实浏览器版本识别,可用于浏览器升级提示,但是为了避免将 IE 内核的浏览器识别为 IE,建议使用 detector:
+function IEMode(){
var ua = navigator.userAgent.toLowerCase();
var re_trident = /\btrident\/([0-9.]+)/;
var re_msie = /\b(?:msie |ie |trident\/[0-9].*rv[ :])([0-9.]+)/;
if(!re_msie.test(ua)){}
var m = re_trident.exec(ua);
version = m[1].split(&.&);
version[0] = parseInt(version[0], 10) + 4;
version = version.join(&.&);
m = re_msie.exec(ua);
version = m[1];
return parseFloat(version);
+var ie = IEMode();
+if(ie && ie & 8){
// 你的浏览器太老了。
+var isIE6 = navigator.userAgent.indexOf(&MSIE 6.0&) !== -1;
+var isIE7 = IEMode() == 7;
+var isIE8 = navigator.userAgent.indexOf(&Trident 4.0&) !== -1;
+var isIE9 = navigator.userAgent.indexOf(&Trident 5.0&) !== -1;
+var isIE10 = navigator.userAgent.indexOf(&Trident 6.0&) !== -1;
+var isIE11 = navigator.userAgent.indexOf(&Trident 7.0&) !== -1;
\ No newline at end of file
(C)&&2013&&Alibaba&&Inc.&&All&&rights&&resvered.
Powered by

我要回帖

更多关于 模块不存在 static 的文章

 

随机推荐