在函数内调用函数 (Javascript)
calling function within a function (Javascript)
简而言之,我希望在单击此按钮时执行以下功能:
<input type="button" value="upload" onclick="generateUpload();" />
但它似乎没有响应,我从控制台收到零错误。
下面是 generateUpload()
函数,我知道该函数内部的内容是有效的,因为我曾尝试用它加载页面并且 google 驱动器选择器会 运行 但我只希望它在单击按钮时 运行。
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
<script type="text/javascript">
function generateUpload()
{
// The Browser API key obtained from the Google Developers Console.
var developerKey = 'id';
// The Client ID obtained from the Google Developers Console.
var clientId = 'id';
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/photos'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': true
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
addView(google.picker.ViewId.PDFS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
var message = 'The following(s) were stored in Parse: ' + url;
document.getElementById('result').innerHTML = message;
}
}
}
</script>
下面是正文中找到的按钮:
<input type="button" value="Create Short" onclick="generateUpload();" /> <br/>
更新:
以下是完整代码:
<!DOCTYPE html>
<html>
<head>
<script src="http://www.parsecdn.com/js/parse-1.2.12.min.js"></script>
<script src="angular.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
<!--======================================================================-->
<!--Custom website css file is linked here-->
<link href="css/style1.css" rel="stylesheet">
<!--Font Awesome CSS link-->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
Parse.initialize("ID", "ID");
var module = angular.module("AuthApp", []);
module.controller("MyCntrl", function($scope) {
$scope.currentUser = Parse.User.current();
$scope.userIdChanged = function () {
$scope.loading = true;
// now access $scope.userId here
var query = new Parse.Query(Parse.User);
query.get($scope.userId, {
success: function(userInfo) {
// The object was retrieved successfully.
var address = userInfo.get("Address");
$scope.address = 'address: ' + address;
var email = userInfo.get("Email");
$scope.email = 'Email: ' + email;
var phone = userInfo.get("Phone");
$scope.phone = 'Phone: ' + phone;
var scanURL = '<a href="scan.html">Scan</a>';
$scope.scanURL = scanURL;
$scope.loading = false;
},
error: function(object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
$scope.loading = false;
}
});
};
});
</script>
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
<script type="text/javascript">
function generateUpload()
{
// The Browser API key obtained from the Google Developers Console.
var developerKey = 'ID';
// The Client ID obtained from the Google Developers Console.
var clientId = 'ID';
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/photos'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': true
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
addView(google.picker.ViewId.PDFS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
var message = 'The following(s) were stored in Parse: ' + url;
document.getElementById('result').innerHTML = message;
}
}
addOnOnApiLoadedCallback(onApiLoad); // register API load
}
var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
gapi_loaded = true;
// run buffered callbacks
for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
gapi_buffered_callbacks();
}
}
function addOnOnApiLoadedCallback(callback) {
if (gapi_loaded) {
callback(); // api is loaded, call immediately
} else {
gapi_buffered_callbacks.push(callback); // add to callback list
}
}
</script>
</head>
<body ng-app="AuthApp">
<div>
<div class="row row-centered">
<div class="col-xs- col-centered col-fixed"><div class="item"><div class="content">
<div ng-controller="MyCntrl">
<div ng-show="currentUser">
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<div id="navbar" class="navbar-collapse collapse">
<h2> Admin Panel </h2>
</div></div></div></div>
<div id="content">
<h3> Upload a new user document </h3>
<h4><b> Step 1: <input type="text" class="form-control" ng-model="userId" ng-blur="userIdChanged()"/>
<div>{{email}}</div>
<br />
<input type="text" id="subjectP" placeholder="Subject line">
<textarea cols="50" rows="4" name="comment" id="notesP" placeholder="notes"></textarea>
<br />
<h4><b> Step 2</b></h4>
<input type="button" value="Create Short" onclick="generateUpload();" /> <br/> <br/>
<div id="result"></div>
</div></div></div></div>
</div>
</div>
</body>
</html>
乍一看,您调用的函数名称似乎有误,您使用的是 gBenerateUpload 并在 JQuery 文件中声明为 generateUpload
我想我明白了。您已将 google API 设置为在加载完成后调用 onApiLoad
。但是这个函数在全局范围内不存在,所以你会得到一个错误。
棘手的部分是当您单击按钮 和 google API 已完成加载时,您想 运行 您的代码.
有两种方法可以解决这个问题:
1) 在 Google API 完成加载之前不要渲染按钮。这涉及在 onApiLoad
函数中渲染(或使按钮可见)。
由于 UI/UX 的原因,这可能不可行,因此有一个更复杂的解决方案:
2) 为 onApiLoad
事件编写处理程序:
var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
gapi_loaded = true;
// run buffered callbacks
for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
gapi_buffered_callbacks();
}
}
function addOnOnApiLoadedCallback(callback) {
if (gapi_loaded) {
callback(); // api is loaded, call immediately
} else {
gapi_buffered_callbacks.push(callback); // add to callback list
}
}
然后在你的 generateUpload
函数中添加:
addOnOnApiLoadedCallback(onApiLoad);
正如您所见,这需要大量的簿记工作。已经开发出一些想法来使这更容易。 Promises
就是其中之一。如果您想探索更多,我建议您从这里开始。
完整代码如下:
function generateUpload()
{
// The Browser API key obtained from the Google Developers Console.
var developerKey = 'id';
// The Client ID obtained from the Google Developers Console.
var clientId = 'id';
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/photos'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': true
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
addView(google.picker.ViewId.PDFS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
var message = 'The following(s) were stored in Parse: ' + url;
document.getElementById('result').innerHTML = message;
}
}
addOnOnApiLoadedCallback(onApiLoad); // register API load
}
var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
gapi_loaded = true;
// run buffered callbacks
for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
gapi_buffered_callbacks();
}
}
function addOnOnApiLoadedCallback(callback) {
if (gapi_loaded) {
callback(); // api is loaded, call immediately
} else {
gapi_buffered_callbacks.push(callback); // add to callback list
}
}
对此稍有不同的方法是将所有 functions/variables 等按设计放回全局范围,而不是删除指向 Google 脚本的 script
标记.相反,将其注入点击处理程序:
function generateUpload()
{
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://apis.google.com/js/api.js?onload=onApiLoad';
document.getElementsByTagName('head')[0].appendChild(script);
}
简而言之,我希望在单击此按钮时执行以下功能:
<input type="button" value="upload" onclick="generateUpload();" />
但它似乎没有响应,我从控制台收到零错误。
下面是 generateUpload()
函数,我知道该函数内部的内容是有效的,因为我曾尝试用它加载页面并且 google 驱动器选择器会 运行 但我只希望它在单击按钮时 运行。
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
<script type="text/javascript">
function generateUpload()
{
// The Browser API key obtained from the Google Developers Console.
var developerKey = 'id';
// The Client ID obtained from the Google Developers Console.
var clientId = 'id';
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/photos'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': true
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
addView(google.picker.ViewId.PDFS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
var message = 'The following(s) were stored in Parse: ' + url;
document.getElementById('result').innerHTML = message;
}
}
}
</script>
下面是正文中找到的按钮:
<input type="button" value="Create Short" onclick="generateUpload();" /> <br/>
更新: 以下是完整代码:
<!DOCTYPE html>
<html>
<head>
<script src="http://www.parsecdn.com/js/parse-1.2.12.min.js"></script>
<script src="angular.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
<!--======================================================================-->
<!--Custom website css file is linked here-->
<link href="css/style1.css" rel="stylesheet">
<!--Font Awesome CSS link-->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
Parse.initialize("ID", "ID");
var module = angular.module("AuthApp", []);
module.controller("MyCntrl", function($scope) {
$scope.currentUser = Parse.User.current();
$scope.userIdChanged = function () {
$scope.loading = true;
// now access $scope.userId here
var query = new Parse.Query(Parse.User);
query.get($scope.userId, {
success: function(userInfo) {
// The object was retrieved successfully.
var address = userInfo.get("Address");
$scope.address = 'address: ' + address;
var email = userInfo.get("Email");
$scope.email = 'Email: ' + email;
var phone = userInfo.get("Phone");
$scope.phone = 'Phone: ' + phone;
var scanURL = '<a href="scan.html">Scan</a>';
$scope.scanURL = scanURL;
$scope.loading = false;
},
error: function(object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
$scope.loading = false;
}
});
};
});
</script>
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
<script type="text/javascript">
function generateUpload()
{
// The Browser API key obtained from the Google Developers Console.
var developerKey = 'ID';
// The Client ID obtained from the Google Developers Console.
var clientId = 'ID';
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/photos'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': true
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
addView(google.picker.ViewId.PDFS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
var message = 'The following(s) were stored in Parse: ' + url;
document.getElementById('result').innerHTML = message;
}
}
addOnOnApiLoadedCallback(onApiLoad); // register API load
}
var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
gapi_loaded = true;
// run buffered callbacks
for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
gapi_buffered_callbacks();
}
}
function addOnOnApiLoadedCallback(callback) {
if (gapi_loaded) {
callback(); // api is loaded, call immediately
} else {
gapi_buffered_callbacks.push(callback); // add to callback list
}
}
</script>
</head>
<body ng-app="AuthApp">
<div>
<div class="row row-centered">
<div class="col-xs- col-centered col-fixed"><div class="item"><div class="content">
<div ng-controller="MyCntrl">
<div ng-show="currentUser">
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<div id="navbar" class="navbar-collapse collapse">
<h2> Admin Panel </h2>
</div></div></div></div>
<div id="content">
<h3> Upload a new user document </h3>
<h4><b> Step 1: <input type="text" class="form-control" ng-model="userId" ng-blur="userIdChanged()"/>
<div>{{email}}</div>
<br />
<input type="text" id="subjectP" placeholder="Subject line">
<textarea cols="50" rows="4" name="comment" id="notesP" placeholder="notes"></textarea>
<br />
<h4><b> Step 2</b></h4>
<input type="button" value="Create Short" onclick="generateUpload();" /> <br/> <br/>
<div id="result"></div>
</div></div></div></div>
</div>
</div>
</body>
</html>
乍一看,您调用的函数名称似乎有误,您使用的是 gBenerateUpload 并在 JQuery 文件中声明为 generateUpload
我想我明白了。您已将 google API 设置为在加载完成后调用 onApiLoad
。但是这个函数在全局范围内不存在,所以你会得到一个错误。
棘手的部分是当您单击按钮 和 google API 已完成加载时,您想 运行 您的代码.
有两种方法可以解决这个问题:
1) 在 Google API 完成加载之前不要渲染按钮。这涉及在 onApiLoad
函数中渲染(或使按钮可见)。
由于 UI/UX 的原因,这可能不可行,因此有一个更复杂的解决方案:
2) 为 onApiLoad
事件编写处理程序:
var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
gapi_loaded = true;
// run buffered callbacks
for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
gapi_buffered_callbacks();
}
}
function addOnOnApiLoadedCallback(callback) {
if (gapi_loaded) {
callback(); // api is loaded, call immediately
} else {
gapi_buffered_callbacks.push(callback); // add to callback list
}
}
然后在你的 generateUpload
函数中添加:
addOnOnApiLoadedCallback(onApiLoad);
正如您所见,这需要大量的簿记工作。已经开发出一些想法来使这更容易。 Promises
就是其中之一。如果您想探索更多,我建议您从这里开始。
完整代码如下:
function generateUpload()
{
// The Browser API key obtained from the Google Developers Console.
var developerKey = 'id';
// The Client ID obtained from the Google Developers Console.
var clientId = 'id';
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/photos'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': true
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
addView(google.picker.ViewId.PDFS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
var message = 'The following(s) were stored in Parse: ' + url;
document.getElementById('result').innerHTML = message;
}
}
addOnOnApiLoadedCallback(onApiLoad); // register API load
}
var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
gapi_loaded = true;
// run buffered callbacks
for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
gapi_buffered_callbacks();
}
}
function addOnOnApiLoadedCallback(callback) {
if (gapi_loaded) {
callback(); // api is loaded, call immediately
} else {
gapi_buffered_callbacks.push(callback); // add to callback list
}
}
对此稍有不同的方法是将所有 functions/variables 等按设计放回全局范围,而不是删除指向 Google 脚本的 script
标记.相反,将其注入点击处理程序:
function generateUpload()
{
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://apis.google.com/js/api.js?onload=onApiLoad';
document.getElementsByTagName('head')[0].appendChild(script);
}