
Html5+的概念非常新颖,这套技术碾压现有的跨平台开发技术。但是。。。
为什么没有英文版的HBuilder?另外dcloud也没有提产品的使用权限,也不象是开源软件,这样模糊不清的产品实在是不敢用来开发企业软件啊。这方面有什么信息?
为什么没有英文版的HBuilder?另外dcloud也没有提产品的使用权限,也不象是开源软件,这样模糊不清的产品实在是不敢用来开发企业软件啊。这方面有什么信息?

【分享】MUI集成facebook第三方登录
首先要到facebook那申请第三方登录,申请完会得到一个client_id,一个ID对应一个APP的
前端
var token = Math.random().toString(36).substr(2);
var url = syslinks + "oauth/token/" + token;//回调地址
plus.nativeUI.showWaiting("");
$.openWindow({
url: "https://m.facebook.com/dialog/oauth?client_id=**xxx**&response_type=code&redirect_uri=" + url + "&scope=email,public_profile",
id: 'facebook',
createNew: true,
show: {
aniShow: 'pop-in'
}
});
然后自己写个定时器或什么的,查询下就好
后端,我用的是thinkkphp
/**
* 第三方登陆
*/
public function oauth(){
$code = I("get.code");
$uid = I("uid");
$token = I("token");
$nickname = I("nickname");
if(!$uid || !$token) exit(json_encode(array('status'=>0,'msg'=>"error")));
$oauth = M('oauth')->where(array("token"=>$token,"uid"=>$uid))->find();
if($oauth){
$user_id = $oauth['user_id'];
}else{
$data = array();
$data['nickname'] = $nickname;
$data['reg_time'] = strtotime(date('Y-m-d H:i:s'));
$user_id = M('users')->add($data);
$data = array();
$data["uid"] = $uid;
$data["token"] = $token;
$data["user_id"] = $user_id;
M('oauth')->add($data);
}
$user = M("users")->find($user_id);
exit(json_encode(array('status'=>1,'msg'=>$user)));
}
首先要到facebook那申请第三方登录,申请完会得到一个client_id,一个ID对应一个APP的
前端
var token = Math.random().toString(36).substr(2);
var url = syslinks + "oauth/token/" + token;//回调地址
plus.nativeUI.showWaiting("");
$.openWindow({
url: "https://m.facebook.com/dialog/oauth?client_id=**xxx**&response_type=code&redirect_uri=" + url + "&scope=email,public_profile",
id: 'facebook',
createNew: true,
show: {
aniShow: 'pop-in'
}
});
然后自己写个定时器或什么的,查询下就好
后端,我用的是thinkkphp
/**
* 第三方登陆
*/
public function oauth(){
$code = I("get.code");
$uid = I("uid");
$token = I("token");
$nickname = I("nickname");
if(!$uid || !$token) exit(json_encode(array('status'=>0,'msg'=>"error")));
$oauth = M('oauth')->where(array("token"=>$token,"uid"=>$uid))->find();
if($oauth){
$user_id = $oauth['user_id'];
}else{
$data = array();
$data['nickname'] = $nickname;
$data['reg_time'] = strtotime(date('Y-m-d H:i:s'));
$user_id = M('users')->add($data);
$data = array();
$data["uid"] = $uid;
$data["token"] = $token;
$data["user_id"] = $user_id;
M('oauth')->add($data);
}
$user = M("users")->find($user_id);
exit(json_encode(array('status'=>1,'msg'=>$user)));
}
收起阅读 »

facebook登录插件(android版)
贴出源码回报社区!
下面贴出关键代码,稍后完善更多细节步骤。个人android开发经验不多,如果有更好的集成方式,请大家分享!
前提:
- 能在android stuido成功运行官方给出的android SDK集成和插件示例程序和离线打包
- 能在android stuido成功运行官方给出的集成示例facebook-android-sdk(https://github.com/facebook/facebook-android-sdk) 中的 FBLoginSample 示例程序
- 注册了facebook开发者平台,并完成了官方android集成步骤(https://developers.facebook.com/docs/facebook-login/android?locale=zh_CN)
- 下面的部分.facebook.plugin.的代码采用了官方示例代码,参考:https://github.com/facebook/facebook-android-sdk/tree/master/samples/FBLoginSample
源代码目录结构
1.js层代码调用插件login.js
var App ={
loginWithFacebook: function()
{
Common.showLoading();
setTimeout(function(){
if(App.timeout)
{
Common.hideLoading();
mui.toast(Common.messages.LOGIN_TIMEOUT,{ duration:'short', type:'div' });
}
}, 5000);
if(Common.debug)
{
setTimeout(function(){
App.facebookAuthSuccessCallBack('{"picture":{"data":{"height":50,"is_silhouette":false,"url":"https:\/\/platform-lookaside.fbsbx.com\/platform\/profilepic\/?asid=1791872767573170&height=50&width=50&ext=1529946538&hash=AeT-c8Gg8kljhvAC","width":50}},"name":"Nick Name","id":"1791872767544170","email":"your@email.com","permissions":{"data":[{"permission":"user_birthday","status":"granted"},{"permission":"user_hometown","status":"granted"},{"permission":"user_location","status":"granted"},{"permission":"user_posts","status":"granted"},{"permission":"user_gender","status":"granted"},{"permission":"user_link","status":"granted"},{"permission":"user_age_range","status":"granted"},{"permission":"email","status":"granted"},{"permission":"public_profile","status":"granted"}]},"age_range":{"min":21},"link":"","gender":"male","birthday":"01\/01\/1991","location":{"id":"106324046073002","name":"Shanghai, China"}}');
//App.facebookAuthCancelCallBack();
//App.facebookAuthErrorCallBack("auth fail!");
}, 2000);
}else
{
//plus.facebookplug.logOut();
plus.facebookplug.logIn();
}
},
// 这个回调函数会在 cn.your.app.SDK_WebApp.java 原生类中调用, 参考类中的excuteJSCode()方法
facebookAuthSuccessCallBack: function(data)
{
App.timeout = false;
if(data != null)
{
// data example: '{"picture":{"data":{"height":50,"is_silhouette":false,"url":"https:\/\/platform-lookaside.fbsbx.com\/platform\/profilepic\/?asid=1791872767573170&height=50&width=50&ext=1529946538&hash=AeT-c8Gg8kljhvAC","width":50}},"name":"Nick Name","id":"1791872767544170","email":"your@email.com","permissions":{"data":[{"permission":"user_birthday","status":"granted"},{"permission":"user_hometown","status":"granted"},{"permission":"user_location","status":"granted"},{"permission":"user_posts","status":"granted"},{"permission":"user_gender","status":"granted"},{"permission":"user_link","status":"granted"},{"permission":"user_age_range","status":"granted"},{"permission":"email","status":"granted"},{"permission":"public_profile","status":"granted"}]},"age_range":{"min":21},"link":"","gender":"male","birthday":"01\/01\/1991","location":{"id":"106324046073002","name":"Shanghai, China"}}'
try{
var facebookUser = JSON.parse(data);
facebookUser.unionid = facebookUser.id;
mui.toast(Common.messages.LOGIN_SUCCESS,{ duration:'short', type:'div' });
App.checkUserIsExist(facebookUser, "facebook");
}catch(err)
{
Common.hideLoading();
mui.toast(Common.messages.LOGIN_FAIL,{ duration:'long', type:'div' });
Common.log("====login.js, facebookAuthSuccessCallBack(), decode facebook user JSON string fail!");
}
}else
{
Common.hideLoading();
App.facebookAuthErrorCallBack();
}
},
// 这个回调函数会在 cn.your.app.SDK_WebApp.java 原生类中调用, 参考类中的excuteJSCode()方法
facebookAuthCancelCallBack: function()
{
App.timeout = false;
Common.hideLoading();
mui.toast(Common.messages.LOGIN_CANCEL,{ duration:'long', type:'div' });
},
// 这个回调函数会在 cn.your.app.SDK_WebApp.java 原生类中调用, 参考类中的excuteJSCode()方法
facebookAuthErrorCallBack: function(error)
{
App.timeout = false;
Common.hideLoading();
mui.toast(Common.messages.LOGIN_FAIL,{ duration:'long', type:'div' });
}
};
if(window.plus){
App.init();
}else{
document.addEventListener( "plusready", App.init, false );
}
2. js层代码插件facebookplug.js
document.addEventListener( "plusready", function()
{
var facebookplug =
{
logIn : function ()
{
window.plus.bridge.exec('facebookplug', "logIn", []);
},
logOut : function ()
{
window.plus.bridge.exec('facebookplug', "logOut", []);
},
};
window.plus.facebookplug = facebookplug;
}, true );
3. 原生层FacebookLoginPlugin.java
package cn.your.app.plugin.facebook;
import cn.your.app.SDK_WebApp;
import cn.your.app.plugin.facebook.callbacks.GetUserCallback;
import cn.your.app.plugin.facebook.requests.UserRequest;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
import io.dcloud.common.util.JSUtil;
import org.json.JSONArray;
import android.content.Context;
import android.os.Bundle;
import com.facebook.AccessToken;
import com.facebook.login.LoginManager;
import java.util.Arrays;
public class FacebookLoginPlugin extends StandardFeature
{
public void onStart(Context pContext, Bundle pSavedInstanceState, String[] pRuntimeArgs) {
/**
* 如果需要在应用启动时进行初始化,可以继承这个方法,并在properties.xml文件的service节点添加扩展插件的注册即可触发onStart方法
* */
}
public void logIn(IWebview pWebview, JSONArray array)
{
if (AccessToken.getCurrentAccessToken() == null) {
/*
* 获取用户属性的权限,参考官方文档:https://developers.facebook.com/docs/facebook-login/permissions/
* 有2中属性,一种是默认公开的(Default fields),参考: https://developers.facebook.com/docs/facebook-login/permissions/#reference-default_fields
* 另一种是需要在应用控制面板提交审查才可以获取的字段(Read Permissions)
*/
// 只获取公开的属性
//LoginManager.getInstance().logInWithReadPermissions(pWebview.getActivity(), Arrays.asList("public_profile"));
// 获取更多属性(应用处于开发阶段时,不需要提交审查即可获取所有字段权限)
LoginManager.getInstance().logInWithReadPermissions(pWebview.getActivity(),Arrays.asList("email", "user_age_range", "user_birthday", "user_gender", "user_hometown", "user_link", "user_location"));
} else {
UserRequest.makeUserRequest(new GetUserCallback((SDK_WebApp)pWebview.getActivity()).getCallback());
}
}
public void logOut(IWebview pWebview, JSONArray array)
{
LoginManager.getInstance().logOut();
}
}
4. 原生层SDK_WebApp.java (在官方给出的android SDK集成代码基础上增加如下代码)
package cn.your.app;
import io.dcloud.EntryProxy;
import io.dcloud.RInformation;
import io.dcloud.common.DHInterface.IApp;
import io.dcloud.common.DHInterface.IApp.IAppStatusListener;
import io.dcloud.common.DHInterface.ICore;
import io.dcloud.common.DHInterface.ICore.ICoreStatusListener;
import io.dcloud.common.DHInterface.IOnCreateSplashView;
import io.dcloud.common.DHInterface.ISysEventListener.SysEventType;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.IWebviewStateListener;
import io.dcloud.common.util.BaseInfo;
import io.dcloud.common.util.ImageLoaderUtil;
import io.dcloud.feature.internal.sdk.SDK;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import cn.your.app.plugin.facebook.callbacks.GetUserCallback;
import cn.your.app.plugin.facebook.entities.FacebookUser;
import cn.your.app.plugin.facebook.requests.UserRequest;
import java.util.ArrayList;
/**
* 本demo为以WebApp方式集成5+ sdk,
*
*/
public class SDK_WebApp extends Activity implements GetUserCallback.IGetUserResponse {
boolean doHardAcc = true;
EntryProxy mEntryProxy = null;
CallbackManager callbackManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
if (mEntryProxy == null) {
FrameLayout f = new FrameLayout(this);
// 创建5+内核运行事件监听
WebappModeListener wm = new WebappModeListener(this, f);
// 初始化5+内核
mEntryProxy = EntryProxy.init(this, wm);
// 启动5+内核
mEntryProxy.onCreate(this, savedInstanceState, SDK.IntegratedMode.WEBAPP, null);
setContentView(f);
}
// 注册Facebook授权登录回调方法
registerFacebookAuthCallback();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mEntryProxy.onActivityExecute(this, SysEventType.onActivityResult, new Object[] { requestCode, resultCode, data });
// facebook授权成功通知
callbackManager.onActivityResult(requestCode, resultCode, data);
}
/** ================Facebook Login START============== **/
protected void registerFacebookAuthCallback()
{
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
UserRequest.makeUserRequest(new GetUserCallback(SDK_WebApp.this).getCallback());
}
@Override
public void onCancel() {
excuteJSCode("App.facebookAuthCancelCallBack()");
}
@Override
public void onError(FacebookException error) {
excuteJSCode("App.facebookAuthErrorCallBack('" + error.getMessage() + "')");
}
});
}
@Override
public void onCompleted(FacebookUser user) {
excuteJSCode("App.facebookAuthSuccessCallBack('" + user.getName() + "')");
}
@Override
public void onGotFacebookUserData(String user)
{
excuteJSCode("App.facebookAuthSuccessCallBack('" + user + "')");
}
// 调用login.html内的JS函数, 参考引用的 /js/login.js 文件
protected void excuteJSCode(String jsCode)
{
ArrayList<IWebview> ss = SDK.obtainAllIWebview();
for (IWebview iWebview : ss) {
if (iWebview.getOriginalUrl().equals("login.html")) {
iWebview.evalJS(jsCode);
break;
}
}
}
/** ================Facebook Login END============== **/
}
}
5. 配置文件/app/src/main/res/values/strings.xml
<resources>
<string name="app_name">应用名</string>
<string name="facebook_app_id">193445774573048</string>
<string name="fb_login_protocol_scheme">fb121135774573048</string>
</resources>
6. 配置文件/app/src/main/assets/data/dcloud_properties.xm(在原基础上新增的部分)
<properties>
<features>
<feature
name="facebookloginplugin"
value="cn.shaketowin.app.plugin.facebook.FacebookLoginPlugin" />
</features>
<services>
<!--<service name="facebookloginplugin" value="cn.shaketowin.app.plugin.facebook.FacebookLoginPlugin"/>-->
</services>
</properties>
7. 配置文件/app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.shaketowin.app">
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true" />
<!-- facebook login begin -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- facebook login end -->
<application
android:name="io.dcloud.application.DCloudApplication"
android:allowBackup="true"
android:allowClearUserData="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true">
<!-- facebook login begin -->
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<!-- facebook login end -->
<activity
android:name="cn.shaketowin.app.ActivityEntry"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="user"
android:windowSoftInputMode="adjustResize">
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--</intent-filter>-->
</activity>
<activity
android:name="cn.shaketowin.app.SDK_WebApp"
android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"
android:screenOrientation="user"
android:theme="@style/DCloudTheme"> <!-- 离线配置沉浸式 SDK_WebApp 作为apk入口时 必须设置 SDK_WebApp 的主题为android:theme="@style/DCloudTheme" -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
贴出源码回报社区!
下面贴出关键代码,稍后完善更多细节步骤。个人android开发经验不多,如果有更好的集成方式,请大家分享!
前提:
- 能在android stuido成功运行官方给出的android SDK集成和插件示例程序和离线打包
- 能在android stuido成功运行官方给出的集成示例facebook-android-sdk(https://github.com/facebook/facebook-android-sdk) 中的 FBLoginSample 示例程序
- 注册了facebook开发者平台,并完成了官方android集成步骤(https://developers.facebook.com/docs/facebook-login/android?locale=zh_CN)
- 下面的部分.facebook.plugin.的代码采用了官方示例代码,参考:https://github.com/facebook/facebook-android-sdk/tree/master/samples/FBLoginSample
源代码目录结构
1.js层代码调用插件login.js
var App ={
loginWithFacebook: function()
{
Common.showLoading();
setTimeout(function(){
if(App.timeout)
{
Common.hideLoading();
mui.toast(Common.messages.LOGIN_TIMEOUT,{ duration:'short', type:'div' });
}
}, 5000);
if(Common.debug)
{
setTimeout(function(){
App.facebookAuthSuccessCallBack('{"picture":{"data":{"height":50,"is_silhouette":false,"url":"https:\/\/platform-lookaside.fbsbx.com\/platform\/profilepic\/?asid=1791872767573170&height=50&width=50&ext=1529946538&hash=AeT-c8Gg8kljhvAC","width":50}},"name":"Nick Name","id":"1791872767544170","email":"your@email.com","permissions":{"data":[{"permission":"user_birthday","status":"granted"},{"permission":"user_hometown","status":"granted"},{"permission":"user_location","status":"granted"},{"permission":"user_posts","status":"granted"},{"permission":"user_gender","status":"granted"},{"permission":"user_link","status":"granted"},{"permission":"user_age_range","status":"granted"},{"permission":"email","status":"granted"},{"permission":"public_profile","status":"granted"}]},"age_range":{"min":21},"link":"","gender":"male","birthday":"01\/01\/1991","location":{"id":"106324046073002","name":"Shanghai, China"}}');
//App.facebookAuthCancelCallBack();
//App.facebookAuthErrorCallBack("auth fail!");
}, 2000);
}else
{
//plus.facebookplug.logOut();
plus.facebookplug.logIn();
}
},
// 这个回调函数会在 cn.your.app.SDK_WebApp.java 原生类中调用, 参考类中的excuteJSCode()方法
facebookAuthSuccessCallBack: function(data)
{
App.timeout = false;
if(data != null)
{
// data example: '{"picture":{"data":{"height":50,"is_silhouette":false,"url":"https:\/\/platform-lookaside.fbsbx.com\/platform\/profilepic\/?asid=1791872767573170&height=50&width=50&ext=1529946538&hash=AeT-c8Gg8kljhvAC","width":50}},"name":"Nick Name","id":"1791872767544170","email":"your@email.com","permissions":{"data":[{"permission":"user_birthday","status":"granted"},{"permission":"user_hometown","status":"granted"},{"permission":"user_location","status":"granted"},{"permission":"user_posts","status":"granted"},{"permission":"user_gender","status":"granted"},{"permission":"user_link","status":"granted"},{"permission":"user_age_range","status":"granted"},{"permission":"email","status":"granted"},{"permission":"public_profile","status":"granted"}]},"age_range":{"min":21},"link":"","gender":"male","birthday":"01\/01\/1991","location":{"id":"106324046073002","name":"Shanghai, China"}}'
try{
var facebookUser = JSON.parse(data);
facebookUser.unionid = facebookUser.id;
mui.toast(Common.messages.LOGIN_SUCCESS,{ duration:'short', type:'div' });
App.checkUserIsExist(facebookUser, "facebook");
}catch(err)
{
Common.hideLoading();
mui.toast(Common.messages.LOGIN_FAIL,{ duration:'long', type:'div' });
Common.log("====login.js, facebookAuthSuccessCallBack(), decode facebook user JSON string fail!");
}
}else
{
Common.hideLoading();
App.facebookAuthErrorCallBack();
}
},
// 这个回调函数会在 cn.your.app.SDK_WebApp.java 原生类中调用, 参考类中的excuteJSCode()方法
facebookAuthCancelCallBack: function()
{
App.timeout = false;
Common.hideLoading();
mui.toast(Common.messages.LOGIN_CANCEL,{ duration:'long', type:'div' });
},
// 这个回调函数会在 cn.your.app.SDK_WebApp.java 原生类中调用, 参考类中的excuteJSCode()方法
facebookAuthErrorCallBack: function(error)
{
App.timeout = false;
Common.hideLoading();
mui.toast(Common.messages.LOGIN_FAIL,{ duration:'long', type:'div' });
}
};
if(window.plus){
App.init();
}else{
document.addEventListener( "plusready", App.init, false );
}
2. js层代码插件facebookplug.js
document.addEventListener( "plusready", function()
{
var facebookplug =
{
logIn : function ()
{
window.plus.bridge.exec('facebookplug', "logIn", []);
},
logOut : function ()
{
window.plus.bridge.exec('facebookplug', "logOut", []);
},
};
window.plus.facebookplug = facebookplug;
}, true );
3. 原生层FacebookLoginPlugin.java
package cn.your.app.plugin.facebook;
import cn.your.app.SDK_WebApp;
import cn.your.app.plugin.facebook.callbacks.GetUserCallback;
import cn.your.app.plugin.facebook.requests.UserRequest;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
import io.dcloud.common.util.JSUtil;
import org.json.JSONArray;
import android.content.Context;
import android.os.Bundle;
import com.facebook.AccessToken;
import com.facebook.login.LoginManager;
import java.util.Arrays;
public class FacebookLoginPlugin extends StandardFeature
{
public void onStart(Context pContext, Bundle pSavedInstanceState, String[] pRuntimeArgs) {
/**
* 如果需要在应用启动时进行初始化,可以继承这个方法,并在properties.xml文件的service节点添加扩展插件的注册即可触发onStart方法
* */
}
public void logIn(IWebview pWebview, JSONArray array)
{
if (AccessToken.getCurrentAccessToken() == null) {
/*
* 获取用户属性的权限,参考官方文档:https://developers.facebook.com/docs/facebook-login/permissions/
* 有2中属性,一种是默认公开的(Default fields),参考: https://developers.facebook.com/docs/facebook-login/permissions/#reference-default_fields
* 另一种是需要在应用控制面板提交审查才可以获取的字段(Read Permissions)
*/
// 只获取公开的属性
//LoginManager.getInstance().logInWithReadPermissions(pWebview.getActivity(), Arrays.asList("public_profile"));
// 获取更多属性(应用处于开发阶段时,不需要提交审查即可获取所有字段权限)
LoginManager.getInstance().logInWithReadPermissions(pWebview.getActivity(),Arrays.asList("email", "user_age_range", "user_birthday", "user_gender", "user_hometown", "user_link", "user_location"));
} else {
UserRequest.makeUserRequest(new GetUserCallback((SDK_WebApp)pWebview.getActivity()).getCallback());
}
}
public void logOut(IWebview pWebview, JSONArray array)
{
LoginManager.getInstance().logOut();
}
}
4. 原生层SDK_WebApp.java (在官方给出的android SDK集成代码基础上增加如下代码)
package cn.your.app;
import io.dcloud.EntryProxy;
import io.dcloud.RInformation;
import io.dcloud.common.DHInterface.IApp;
import io.dcloud.common.DHInterface.IApp.IAppStatusListener;
import io.dcloud.common.DHInterface.ICore;
import io.dcloud.common.DHInterface.ICore.ICoreStatusListener;
import io.dcloud.common.DHInterface.IOnCreateSplashView;
import io.dcloud.common.DHInterface.ISysEventListener.SysEventType;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.IWebviewStateListener;
import io.dcloud.common.util.BaseInfo;
import io.dcloud.common.util.ImageLoaderUtil;
import io.dcloud.feature.internal.sdk.SDK;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import cn.your.app.plugin.facebook.callbacks.GetUserCallback;
import cn.your.app.plugin.facebook.entities.FacebookUser;
import cn.your.app.plugin.facebook.requests.UserRequest;
import java.util.ArrayList;
/**
* 本demo为以WebApp方式集成5+ sdk,
*
*/
public class SDK_WebApp extends Activity implements GetUserCallback.IGetUserResponse {
boolean doHardAcc = true;
EntryProxy mEntryProxy = null;
CallbackManager callbackManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
if (mEntryProxy == null) {
FrameLayout f = new FrameLayout(this);
// 创建5+内核运行事件监听
WebappModeListener wm = new WebappModeListener(this, f);
// 初始化5+内核
mEntryProxy = EntryProxy.init(this, wm);
// 启动5+内核
mEntryProxy.onCreate(this, savedInstanceState, SDK.IntegratedMode.WEBAPP, null);
setContentView(f);
}
// 注册Facebook授权登录回调方法
registerFacebookAuthCallback();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mEntryProxy.onActivityExecute(this, SysEventType.onActivityResult, new Object[] { requestCode, resultCode, data });
// facebook授权成功通知
callbackManager.onActivityResult(requestCode, resultCode, data);
}
/** ================Facebook Login START============== **/
protected void registerFacebookAuthCallback()
{
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
UserRequest.makeUserRequest(new GetUserCallback(SDK_WebApp.this).getCallback());
}
@Override
public void onCancel() {
excuteJSCode("App.facebookAuthCancelCallBack()");
}
@Override
public void onError(FacebookException error) {
excuteJSCode("App.facebookAuthErrorCallBack('" + error.getMessage() + "')");
}
});
}
@Override
public void onCompleted(FacebookUser user) {
excuteJSCode("App.facebookAuthSuccessCallBack('" + user.getName() + "')");
}
@Override
public void onGotFacebookUserData(String user)
{
excuteJSCode("App.facebookAuthSuccessCallBack('" + user + "')");
}
// 调用login.html内的JS函数, 参考引用的 /js/login.js 文件
protected void excuteJSCode(String jsCode)
{
ArrayList<IWebview> ss = SDK.obtainAllIWebview();
for (IWebview iWebview : ss) {
if (iWebview.getOriginalUrl().equals("login.html")) {
iWebview.evalJS(jsCode);
break;
}
}
}
/** ================Facebook Login END============== **/
}
}
5. 配置文件/app/src/main/res/values/strings.xml
<resources>
<string name="app_name">应用名</string>
<string name="facebook_app_id">193445774573048</string>
<string name="fb_login_protocol_scheme">fb121135774573048</string>
</resources>
6. 配置文件/app/src/main/assets/data/dcloud_properties.xm(在原基础上新增的部分)
<properties>
<features>
<feature
name="facebookloginplugin"
value="cn.shaketowin.app.plugin.facebook.FacebookLoginPlugin" />
</features>
<services>
<!--<service name="facebookloginplugin" value="cn.shaketowin.app.plugin.facebook.FacebookLoginPlugin"/>-->
</services>
</properties>
7. 配置文件/app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.shaketowin.app">
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true" />
<!-- facebook login begin -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- facebook login end -->
<application
android:name="io.dcloud.application.DCloudApplication"
android:allowBackup="true"
android:allowClearUserData="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true">
<!-- facebook login begin -->
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<!-- facebook login end -->
<activity
android:name="cn.shaketowin.app.ActivityEntry"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="user"
android:windowSoftInputMode="adjustResize">
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--</intent-filter>-->
</activity>
<activity
android:name="cn.shaketowin.app.SDK_WebApp"
android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"
android:screenOrientation="user"
android:theme="@style/DCloudTheme"> <!-- 离线配置沉浸式 SDK_WebApp 作为apk入口时 必须设置 SDK_WebApp 的主题为android:theme="@style/DCloudTheme" -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
收起阅读 »

自定义原生二维码扫描样式
。。。。。这个 好像只能等官方改了!
不过我们可以从另一个方面来写。
先看效果(阿里云学生服务器哈,总出口就100kb)
!
我讲下大概的实现吧,双webview,最上面webview背景透明,webview之间通信用evalJS。
贴点代码?!
1.加载子页面(最上层webview),背景透明
mui.init({
subpages: [{
url: 'scan_main.html',
id: 'scan_main.html',
styles: {
top: 0,
bottom: 0,
background: 'transparent'
},
}]
});
2.webview通信
var scan_win = null;
mui.plusReady(function() {
scan_win = plus.webview.getWebviewById('html/scan_win.html');
})
scan_win.evalJS('XXXXXXXXXXXXXX');//打开关闭闪光灯、图库啊等等
3.虽然中间那个扫码框和扫码条暂时只能改颜色,但是通过这样也可以做的跟大厂一样的效果了
。。。。。这个 好像只能等官方改了!
不过我们可以从另一个方面来写。
先看效果(阿里云学生服务器哈,总出口就100kb)
!
我讲下大概的实现吧,双webview,最上面webview背景透明,webview之间通信用evalJS。
贴点代码?!
1.加载子页面(最上层webview),背景透明
mui.init({
subpages: [{
url: 'scan_main.html',
id: 'scan_main.html',
styles: {
top: 0,
bottom: 0,
background: 'transparent'
},
}]
});
2.webview通信
var scan_win = null;
mui.plusReady(function() {
scan_win = plus.webview.getWebviewById('html/scan_win.html');
})
scan_win.evalJS('XXXXXXXXXXXXXX');//打开关闭闪光灯、图库啊等等
3.虽然中间那个扫码框和扫码条暂时只能改颜色,但是通过这样也可以做的跟大厂一样的效果了
收起阅读 »
广州,混合app开发,来搞事情呢,8k-15k
派我科技找你来做事呢:
1、负责Android及IOS移动App平台应用程序的前端开发,实现各模块功能,并确保开发质量与进度;
2、根据开发流程、规范要求完成相应开发文档;
3、持续的优化前端体验和页面响应速度,并保证兼容性和执行效率;
4、熟悉HTML/CSS/Javascript等前端技术;
5、对前端框架设计有一定见解,可构建高性能的 Web 应用程序;
6、1-2年经验。
ok就发信息来,给个机会让我撩撩你!
派我科技找你来做事呢:
1、负责Android及IOS移动App平台应用程序的前端开发,实现各模块功能,并确保开发质量与进度;
2、根据开发流程、规范要求完成相应开发文档;
3、持续的优化前端体验和页面响应速度,并保证兼容性和执行效率;
4、熟悉HTML/CSS/Javascript等前端技术;
5、对前端框架设计有一定见解,可构建高性能的 Web 应用程序;
6、1-2年经验。
ok就发信息来,给个机会让我撩撩你!
收起阅读 »
快速上手 - wap2app教程
下载/登录开发工具
前往 dcloud.io 根据自己的操作系统,下载对应的 HBuilder 安装包,解压即可使用。
PS:首次使用需注册一个开发者账号,方便后续的打包以及应用管理。
创建项目
按照如下步骤在HBuilder中新建 wap2app 工程
- 顶部菜单,文件 -> 新建 -> Wap2App
- 输入应用名称、wap 站首页地址,点击“完成”
工程建成后,默认目录结构如下:
配置应用图标及启动图
应用图标
应用图标是App安装到手机后,在手机桌面显示的图标;按照如下步骤配置应用图标:
双击打开manifest.json文件,点击下方“图标配置”选项卡
在图标配置页面,按照要求配置各种分辨率的图标
建议配置1024*1024的大图标,然后自动生成并替换各种分辨率的图标。
启动图片
启动图片是用户从点击桌面图标到进入应用首页中间显示的欢迎图片;按照如下步骤配置应用图标。
点击“启动图片(splash)配置”选项卡,会打开启动图配置界面
根据需要配置不同分辨率的启动图片,例如仅生成Android安装包,则仅配置Android启动图片即可。
应用发布
wap2app项目可以打包成iOS平台的ipa安装包、Android平台的apk安装包。
但注意:iOS平台只能发布企业版或越狱包,无法上Appstore。因为苹果要求强制wkwebview,而wap2app需要使用uiwebview。导致iOS上的wap2app可以真机运行,但没法上Appstore。
在HBuilder中,点击顶部“发行”菜单,点击“云打包-打原生安装包”,如下:
打开原生打包配置界面,如下图所示:
选择需要打包的平台(iOS平台打包需要配置iOS证书),点击“打包”按钮即可提交云端打包,打包完成后会自动下载安装包,安装到手机即可体验。
好了,到此为止,你已经快速体验了wap2app的创建到发布过程,更多强化功能实现请继续阅读wap2app的相关教程。
下载/登录开发工具
前往 dcloud.io 根据自己的操作系统,下载对应的 HBuilder 安装包,解压即可使用。
PS:首次使用需注册一个开发者账号,方便后续的打包以及应用管理。
创建项目
按照如下步骤在HBuilder中新建 wap2app 工程
- 顶部菜单,文件 -> 新建 -> Wap2App
- 输入应用名称、wap 站首页地址,点击“完成”
工程建成后,默认目录结构如下:
配置应用图标及启动图
应用图标
应用图标是App安装到手机后,在手机桌面显示的图标;按照如下步骤配置应用图标:
双击打开manifest.json文件,点击下方“图标配置”选项卡
在图标配置页面,按照要求配置各种分辨率的图标
建议配置1024*1024的大图标,然后自动生成并替换各种分辨率的图标。
启动图片
启动图片是用户从点击桌面图标到进入应用首页中间显示的欢迎图片;按照如下步骤配置应用图标。
点击“启动图片(splash)配置”选项卡,会打开启动图配置界面
根据需要配置不同分辨率的启动图片,例如仅生成Android安装包,则仅配置Android启动图片即可。
应用发布
wap2app项目可以打包成iOS平台的ipa安装包、Android平台的apk安装包。
但注意:iOS平台只能发布企业版或越狱包,无法上Appstore。因为苹果要求强制wkwebview,而wap2app需要使用uiwebview。导致iOS上的wap2app可以真机运行,但没法上Appstore。
在HBuilder中,点击顶部“发行”菜单,点击“云打包-打原生安装包”,如下:
打开原生打包配置界面,如下图所示:
选择需要打包的平台(iOS平台打包需要配置iOS证书),点击“打包”按钮即可提交云端打包,打包完成后会自动下载安装包,安装到手机即可体验。
好了,到此为止,你已经快速体验了wap2app的创建到发布过程,更多强化功能实现请继续阅读wap2app的相关教程。
收起阅读 »
力谱云V2.0新发布,分销&外卖配送大升级!
力谱云厚积薄发,隆重上线V2.0版本咯!
在本次版本中,我们将重点针对B2C分销、B2B2C配送、B2B2C外卖等三大方面进行App平台功能大升级!并对App商品分享、订单预约等功能进行了优化。另对14项细节处,进行了新功能追加与更新!赶紧抢先阅读吧!
以下为本次重点App更新功能↓↓↓
B2C分销功能大升级
B2B2C配送功能大升级,支持生鲜和外卖行业抢单和派单
B2B2C外卖行业优化,支持外卖模式的店铺布局,并可自动打印订单
支持App中的商品,以小程序卡片方式分享到微信
电商大管家和商户端支持服务预约的订单处理。针对多次型消费服务模式,店铺方可进行多次核销。
B2C分销
可对每个商品设置三级分销提成比例
有分销提成的用户可在移动端界面看到每个订单的分销提成
分销提成方式支持余额,提现更方便
支持通过推荐码建立分销体系。用户在注册平台时,输入推荐码,即可在注册同时,即能加入上级进行分销
管理后台可以修改会员的推荐人。可防止因推荐人退团,导致分销团队离散。
B2B2C配送
支持派单模式。当无人抢单时,商家可通过查看配送员的离店距离、当前接单数等信息,进行筛查,选择最合适的配送员进行手动派单。
配送抢单可以设置抢单范围
B2B2C外卖
店铺支持外卖布局,如美团/饿了么等模式
店铺管家和店铺管理后台支持一键打烊
订单可以自动打印到热敏打印机
其他4项新功能和优化
App可以以小程序卡片的方式分享商品到微信
优化移动端下单体验
支付更流畅
商品待发货时,显示【申请退款】。交易成功时,显示【申请售后】。优化用户购物体验,并提升售后服务。
B2B2C每个店铺可以设置不一样的消费返积分比例
改进订单详情界面物流信息显示
其他14处细节新功能和优化
B2B2C平台可以发放代金券给每个用户
为B2B2C店铺生成二维码,支持扫一扫进入店铺首页
店铺管家可以处理预定订单
B2B2C可以设置某些商品的排序权重,可在分类页和搜索页优先排序
B2C和B2B2C商品支持显示起订量,方便商品批发
B2C商城可对未登陆用户隐藏价格
管理后台可以查看用户余额变更明细
管理后台支持批量导入订单物流信息
配送端多规格商品在详情页显示多规格属性
优化管理后台B2C、B2B2C订单详情和导出
优化管理后台订单支付流水界面
会员导出增加会员自定义属性
文章列表显示阅读量
付费文章在列表页显示积分价格
力谱云助力企业轻松打造专属移动电商平台
再次感谢各位新老用户对力谱云平台的信赖与支持!在上半年度,力谱云主要集中精力打通了小程序平台等各项功能,并针对电商分销系统、外卖配送等功能进行了整体优化与升级。
目前,力谱云倾力打造移动电商App平台,终于厚积薄发,全新推出关于社交分销、多商户社交电商平台、新零售、移动订货平台等4大移动解决方案,采用云集、拼多多、生鲜/外卖配送、裂变新渠道等丰富新电商元素,以期让企业运营、销售、营销迸发出更多商业新活力!此外,我们还将再接再厉,持续攀登行业高峰,努力为企业用户们带来更多前沿、专业、高效、盈利丰厚的移动电商解决方案。
选择力谱云,让我们为您提供最专业的专属移动电商解决方案吧!
力谱云厚积薄发,隆重上线V2.0版本咯!
在本次版本中,我们将重点针对B2C分销、B2B2C配送、B2B2C外卖等三大方面进行App平台功能大升级!并对App商品分享、订单预约等功能进行了优化。另对14项细节处,进行了新功能追加与更新!赶紧抢先阅读吧!
以下为本次重点App更新功能↓↓↓
B2C分销功能大升级
B2B2C配送功能大升级,支持生鲜和外卖行业抢单和派单
B2B2C外卖行业优化,支持外卖模式的店铺布局,并可自动打印订单
支持App中的商品,以小程序卡片方式分享到微信
电商大管家和商户端支持服务预约的订单处理。针对多次型消费服务模式,店铺方可进行多次核销。
B2C分销
可对每个商品设置三级分销提成比例
有分销提成的用户可在移动端界面看到每个订单的分销提成
分销提成方式支持余额,提现更方便
支持通过推荐码建立分销体系。用户在注册平台时,输入推荐码,即可在注册同时,即能加入上级进行分销
管理后台可以修改会员的推荐人。可防止因推荐人退团,导致分销团队离散。
B2B2C配送
支持派单模式。当无人抢单时,商家可通过查看配送员的离店距离、当前接单数等信息,进行筛查,选择最合适的配送员进行手动派单。
配送抢单可以设置抢单范围
B2B2C外卖
店铺支持外卖布局,如美团/饿了么等模式
店铺管家和店铺管理后台支持一键打烊
订单可以自动打印到热敏打印机
其他4项新功能和优化
App可以以小程序卡片的方式分享商品到微信
优化移动端下单体验
支付更流畅
商品待发货时,显示【申请退款】。交易成功时,显示【申请售后】。优化用户购物体验,并提升售后服务。
B2B2C每个店铺可以设置不一样的消费返积分比例
改进订单详情界面物流信息显示
其他14处细节新功能和优化
B2B2C平台可以发放代金券给每个用户
为B2B2C店铺生成二维码,支持扫一扫进入店铺首页
店铺管家可以处理预定订单
B2B2C可以设置某些商品的排序权重,可在分类页和搜索页优先排序
B2C和B2B2C商品支持显示起订量,方便商品批发
B2C商城可对未登陆用户隐藏价格
管理后台可以查看用户余额变更明细
管理后台支持批量导入订单物流信息
配送端多规格商品在详情页显示多规格属性
优化管理后台B2C、B2B2C订单详情和导出
优化管理后台订单支付流水界面
会员导出增加会员自定义属性
文章列表显示阅读量
付费文章在列表页显示积分价格
力谱云助力企业轻松打造专属移动电商平台
再次感谢各位新老用户对力谱云平台的信赖与支持!在上半年度,力谱云主要集中精力打通了小程序平台等各项功能,并针对电商分销系统、外卖配送等功能进行了整体优化与升级。
目前,力谱云倾力打造移动电商App平台,终于厚积薄发,全新推出关于社交分销、多商户社交电商平台、新零售、移动订货平台等4大移动解决方案,采用云集、拼多多、生鲜/外卖配送、裂变新渠道等丰富新电商元素,以期让企业运营、销售、营销迸发出更多商业新活力!此外,我们还将再接再厉,持续攀登行业高峰,努力为企业用户们带来更多前沿、专业、高效、盈利丰厚的移动电商解决方案。
选择力谱云,让我们为您提供最专业的专属移动电商解决方案吧!

闭包 作用域 原型链
// 代码1
if(!("userName" in window)) {
var userName = "yang"
}
console.log(userName) // undefined
if是一个块,在ES6里有块级作用域,在ES5里是没有这个概念的。
// 代码2
var obj = {
user: "yang",
getName: function () {
return this.user;
}
}
var getNameFn = obj.getName;
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined
console.log(obj.getName()) // Uncaught ReferenceError: user is not defined
var obj = {
user: "yang",
getName: function () {
return this.user;
}
}
var getNameFn = obj.getName;
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined
console.log(obj.getName()) // "yang"
作用域
1、程序级
2、文件级
3、函数级
4、块级
全局作用域、函数作用域、块级作用域(es6)
js中只有一个局部作用域就是函数作用域
// 代码3
var global = 1;
function doSomething() {
var inner = 2;
globalA = 3;
}
doSomething();
alert(global); // 1
alert(globalA); // 3
alert(inner); // undefined
什么是作用域链?
在js中,函数也是对象,函数对象和其他对象一样,拥有可以通过代码访问的属性和一系列仅供js引擎访问的内部函数,其中一个内部属性是【scope】,由ECMA-262标准第三版定义,该内部属性包含了函数被创建作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
var x = 1;
function foo () {
var y = 1 + x;
return function () {
var z = 1 + y;
return z;
}
}
foo()();
// 代码4
var test = "aa"
function doSomething() {
alert(test) // undefined 变量与函数的声明提前,永远访问不到外部的test
var test = "bb"
alert(test) // bb
}
doSomething()
alert(test) //aa
**变量与函数的声明提前**
function foo () {
alert(test);
var test = "bb"
alert(test)
}
foo()
执行顺序:
1.声明函数foo
2. 调用函数foo
3. 声明变量test
4. alert(test)
5.test变量赋值为bb
6.alert(test)
js中this关键字
this指向哪里?
在js中,this指向函数执行时的当前对象。
this的使用场景
》普通函数中:
严格模式中:undefined
非严格模式中:全局对象(window)
》构造函数中:对象的实例
》对象方法:对象本身
call、apply、bind
通过这三个方法可以改变被调用函数中this指向的对象
原型对象是什么
在js中,每定义一个对象(函数)时,对象中都会包含一些预定义的属性。其中函数对象的一个属性就是原型对象prototype。普通对象没有prototype属性,但有proto属性
function f1() {};
console.log(typeof f1.prototype) // Object
console.log(typeof Function.prototype) // Function,这个特殊
console.log(typeof Object.prototype) // Object
console.log(typeof Function.prototype.prototype) //undefined
原型对象有什么用?
面向对象开发、类的继承
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
var sub = new Person("yang")
sub.getName() //yang
构造函数
使用new关键字调用一个函数的时候,这个函数就叫构造函数
构造函数可以实例化一个对象
返回值,默认返回类的实例
特殊情况:没有返回值、简单数据类型、对象类型
原型链
1.每个函数都有一个prototype的对象属性
- 每个对象都有一个 proto 属性,该属性指向其父类的prototype对象
原型对象中的constructor
每个原型对象prototype中都有一个constructor属性,默认指向函数本身// test 1 function make(num) { return function () { return num; } }
var arr = [make(0),make(1),make(2)]
alert(arr[0]()) // 0
alert(arr[1]()) // 1
alert(arr[2]()) // 2
// test 2
var name = "global"
function A(name) {
// 参数name就是一个变量声明
alert(name) // 3
this.name = name
var name = "1" // 这个name完全不影响
}
A.prototype.name = "2" // 在原型链上后调用
var a = new A("3")
alert(a.name) // 3
delete a.name
alert(a.name) // 2
// test 3
function fun (n,o) {
console.log(o)
return {
fun: function(m) {
return fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}
var a = fun(0) // undefined
a.fun(1) // 一定是通过这种方法才能访问到对象的fun,而函数fun不同
a.fun(2)
var b = fun(0).fun(1).fun(2).fun(3)
var c = fun(0).fun(1)
c.fun(2)
c.fun(3)
相关说明:https://segmentfault.com/a/1190000004187681
其实是这样的
function _fun (n,o) {
console.log(o)
return {
fun: function(m) {
return _fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}
chrome调试作用域链
闭包就是一个函数一个作用域,使用场景
使用的i函数就是一个局部作用域,就是一个闭包
闭包会引起内存泄漏为什么还要用它?
涉及到js的垃圾回收,循环引用,会在闭包执行完之后进行回收,内存泄漏是认为写代码不当导致的,函数式编程中闭包更常用。
变量的提前声明
《函数式编程》
lodash
// 代码1
if(!("userName" in window)) {
var userName = "yang"
}
console.log(userName) // undefined
if是一个块,在ES6里有块级作用域,在ES5里是没有这个概念的。
// 代码2
var obj = {
user: "yang",
getName: function () {
return this.user;
}
}
var getNameFn = obj.getName;
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined
console.log(obj.getName()) // Uncaught ReferenceError: user is not defined
var obj = {
user: "yang",
getName: function () {
return this.user;
}
}
var getNameFn = obj.getName;
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined
console.log(obj.getName()) // "yang"
作用域
1、程序级
2、文件级
3、函数级
4、块级
全局作用域、函数作用域、块级作用域(es6)
js中只有一个局部作用域就是函数作用域
// 代码3
var global = 1;
function doSomething() {
var inner = 2;
globalA = 3;
}
doSomething();
alert(global); // 1
alert(globalA); // 3
alert(inner); // undefined
什么是作用域链?
在js中,函数也是对象,函数对象和其他对象一样,拥有可以通过代码访问的属性和一系列仅供js引擎访问的内部函数,其中一个内部属性是【scope】,由ECMA-262标准第三版定义,该内部属性包含了函数被创建作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
var x = 1;
function foo () {
var y = 1 + x;
return function () {
var z = 1 + y;
return z;
}
}
foo()();
// 代码4
var test = "aa"
function doSomething() {
alert(test) // undefined 变量与函数的声明提前,永远访问不到外部的test
var test = "bb"
alert(test) // bb
}
doSomething()
alert(test) //aa
**变量与函数的声明提前**
function foo () {
alert(test);
var test = "bb"
alert(test)
}
foo()
执行顺序:
1.声明函数foo
2. 调用函数foo
3. 声明变量test
4. alert(test)
5.test变量赋值为bb
6.alert(test)
js中this关键字
this指向哪里?
在js中,this指向函数执行时的当前对象。
this的使用场景
》普通函数中:
严格模式中:undefined
非严格模式中:全局对象(window)
》构造函数中:对象的实例
》对象方法:对象本身
call、apply、bind
通过这三个方法可以改变被调用函数中this指向的对象
原型对象是什么
在js中,每定义一个对象(函数)时,对象中都会包含一些预定义的属性。其中函数对象的一个属性就是原型对象prototype。普通对象没有prototype属性,但有proto属性
function f1() {};
console.log(typeof f1.prototype) // Object
console.log(typeof Function.prototype) // Function,这个特殊
console.log(typeof Object.prototype) // Object
console.log(typeof Function.prototype.prototype) //undefined
原型对象有什么用?
面向对象开发、类的继承
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
var sub = new Person("yang")
sub.getName() //yang
构造函数
使用new关键字调用一个函数的时候,这个函数就叫构造函数
构造函数可以实例化一个对象
返回值,默认返回类的实例
特殊情况:没有返回值、简单数据类型、对象类型
原型链
1.每个函数都有一个prototype的对象属性
- 每个对象都有一个 proto 属性,该属性指向其父类的prototype对象
原型对象中的constructor
每个原型对象prototype中都有一个constructor属性,默认指向函数本身// test 1 function make(num) { return function () { return num; } }
var arr = [make(0),make(1),make(2)]
alert(arr[0]()) // 0
alert(arr[1]()) // 1
alert(arr[2]()) // 2
// test 2
var name = "global"
function A(name) {
// 参数name就是一个变量声明
alert(name) // 3
this.name = name
var name = "1" // 这个name完全不影响
}
A.prototype.name = "2" // 在原型链上后调用
var a = new A("3")
alert(a.name) // 3
delete a.name
alert(a.name) // 2
// test 3
function fun (n,o) {
console.log(o)
return {
fun: function(m) {
return fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}
var a = fun(0) // undefined
a.fun(1) // 一定是通过这种方法才能访问到对象的fun,而函数fun不同
a.fun(2)
var b = fun(0).fun(1).fun(2).fun(3)
var c = fun(0).fun(1)
c.fun(2)
c.fun(3)
相关说明:https://segmentfault.com/a/1190000004187681
其实是这样的
function _fun (n,o) {
console.log(o)
return {
fun: function(m) {
return _fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}
chrome调试作用域链
闭包就是一个函数一个作用域,使用场景
使用的i函数就是一个局部作用域,就是一个闭包
闭包会引起内存泄漏为什么还要用它?
涉及到js的垃圾回收,循环引用,会在闭包执行完之后进行回收,内存泄漏是认为写代码不当导致的,函数式编程中闭包更常用。
变量的提前声明
《函数式编程》
lodash
收起阅读 »

支持mui的vue脚手架,可下载apk体验,支持ES6/7/8,支持多页面打包
mogoH5+ v0.2 脚手架发布啦,支持vue,多页面,ES6/7/8,压缩/打包,完全支持mui.可以下载体验apk
体验apk:https://fir.im/p52j
脚手架地址:https://github.com/tyaqing/mogo-h5plus
欢迎各位提出宝贵意见
- 支持 Npm 生态
- 支持 vue 语法,以及 vue 生态,比如 vux,mint,vant
- 支持 ES6/ES7 语法
- 使用 VConsole 调试
- VSCode 友好
- 局域网便捷调试,不插数据线也可以调试
- 支持mui的使用
mogoH5+ v0.2 脚手架发布啦,支持vue,多页面,ES6/7/8,压缩/打包,完全支持mui.可以下载体验apk
体验apk:https://fir.im/p52j
脚手架地址:https://github.com/tyaqing/mogo-h5plus
欢迎各位提出宝贵意见
- 支持 Npm 生态
- 支持 vue 语法,以及 vue 生态,比如 vux,mint,vant
- 支持 ES6/ES7 语法
- 使用 VConsole 调试
- VSCode 友好
- 局域网便捷调试,不插数据线也可以调试
- 支持mui的使用