引用 Cordova/Onsen 中的模板化 HTML 元素
Referencing Templated HTML Elements in Cordova/Onsen
这可能不是 Cordova/Onsen 特有的,但我是 Javascript 的新手,所以我只是提供我认为相关的信息。我想知道引用模板化 HTML 元素的正确方法是什么。这是我目前正在做的事情(片段):
HTML:
<ons-navigator title="myApp" var="myNavigator">
<ons-page id="mainPage">
<ons-toolbar>
<div class="center">Title</div>
</ons-toolbar>
<ons-list>
<ons-list-item id="button" modifier="chevron">
Button Text
</ons-list-item>
</ons-list>
</ons-page>
</ons-navigator>
<ons-template id="newPage.html">
<ons-page id="newPage">
<ons-toolbar>
<div class="left">
<ons-back-button>Back</ons-back-button>
</div>
<div class="center">Page Title</div>
</ons-toolbar>
<button id="submit-btn" class="button button--large">Submit</button><br>
</ons-page>
</ons-template>
Javascript:
(function () {
"use strict";
/* Event Registration */
document.addEventListener('deviceready', onDeviceReady.bind(this), false);
// Listening for pageinit event to grab submit button.
document.addEventListener("pageinit", function (event) {
console.log("init Fired!");
if (event.target.id == "newPage") {
initPage();
}
}, false);
function initPage() {
$('#submit-btn').on('click', doSomethingUseful);
}
function onDeviceReady() {
// Handle the Cordova pause and resume events
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener('resume', onResume.bind(this), false);
// TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
$('#button').on('click', function () {
myNavigator.pushPage('newPage.html', { animation: 'slide' })
});
};
} )();
本质上,我在等待 Onsen 发出 pageinit 事件信号,然后再从模板化页面中获取按钮。 pageinit 信号在页面加载后发送,即当按下 "button" 时。
尽管这可行,但感觉应该有更好的方法来做到这一点。在设置按钮处理程序和其他东西之前不必等待页面加载,我似乎应该能够提前设置它们。但是,如果我尝试在加载页面之前访问模板化元素,它就不起作用(jQuery 选择器 returns null)。
仅供参考,我没有使用 Angular。 (大多数 Onsen 示例都在 Angular 中,但我目前正在学习足够多的新东西,此时不想再有其他东西来增加混乱。)
正如@Munsterlander 提到的那样 - 您不能将事件附加到尚未添加到 DOM 的元素。目前,您正在做的事情被认为是最好的做事方式。所以我只是建议尝试简化现有代码而不实际改变它的总体思路。例如:内联某些函数并使用 ons.ready
而不是 deviceready
。此代码的同等且更简单的版本可以是:
document.addEventListener("pageinit", function (event) {
console.log("init Fired!");
if (event.target.id == "newPage") {
$('#submit-btn').on('click', doSomethingUseful);
}
});
ons.ready(function () {
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener('resume', onResume.bind(this), false);
// TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
$('#button').on('click', function () {
myNavigator.pushPage('newPage.html', { animation: 'slide' })
});
});
通常我还建议使用页面 ID 制作类似对象的东西。类似于:
var handlers = {
newPage: function(e) { $('#submit-btn').click(doSomethingUseful); },
page2: function(e) { $('#submit-btn2').click(doSomethingUseful2); }
};
和
document.addEventListener('pageinit', function(e) {
if (handlers.hasOwnProperty(e.target.id)) {
handlers[e.target.id](e);
}
});
我想现在是给出您想要的真正答案的时候了。由于您无法在将元素添加到 DOM 之前收听它们,因此如果您愿意,您可以收听事件并以与处理 pageinit
事件相同的方式过滤它们的目标。使用 jQuery 有一种相对简单的方法可以做到这一点:
$(document).on(eventName, selector, handler);
因此您可以随时执行此操作
$(document).on('click', '#submit-btn', doSomethingUseful);
它会起作用,因为它将处理程序附加到文档而不是元素。因此,这将适用于您将来添加到 DOM 的所有 #submit-btn
。 :)(尽管不建议这样做,但如果您愿意,您仍然可以这样做。)
这可能不是 Cordova/Onsen 特有的,但我是 Javascript 的新手,所以我只是提供我认为相关的信息。我想知道引用模板化 HTML 元素的正确方法是什么。这是我目前正在做的事情(片段):
HTML:
<ons-navigator title="myApp" var="myNavigator">
<ons-page id="mainPage">
<ons-toolbar>
<div class="center">Title</div>
</ons-toolbar>
<ons-list>
<ons-list-item id="button" modifier="chevron">
Button Text
</ons-list-item>
</ons-list>
</ons-page>
</ons-navigator>
<ons-template id="newPage.html">
<ons-page id="newPage">
<ons-toolbar>
<div class="left">
<ons-back-button>Back</ons-back-button>
</div>
<div class="center">Page Title</div>
</ons-toolbar>
<button id="submit-btn" class="button button--large">Submit</button><br>
</ons-page>
</ons-template>
Javascript:
(function () {
"use strict";
/* Event Registration */
document.addEventListener('deviceready', onDeviceReady.bind(this), false);
// Listening for pageinit event to grab submit button.
document.addEventListener("pageinit", function (event) {
console.log("init Fired!");
if (event.target.id == "newPage") {
initPage();
}
}, false);
function initPage() {
$('#submit-btn').on('click', doSomethingUseful);
}
function onDeviceReady() {
// Handle the Cordova pause and resume events
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener('resume', onResume.bind(this), false);
// TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
$('#button').on('click', function () {
myNavigator.pushPage('newPage.html', { animation: 'slide' })
});
};
} )();
本质上,我在等待 Onsen 发出 pageinit 事件信号,然后再从模板化页面中获取按钮。 pageinit 信号在页面加载后发送,即当按下 "button" 时。
尽管这可行,但感觉应该有更好的方法来做到这一点。在设置按钮处理程序和其他东西之前不必等待页面加载,我似乎应该能够提前设置它们。但是,如果我尝试在加载页面之前访问模板化元素,它就不起作用(jQuery 选择器 returns null)。
仅供参考,我没有使用 Angular。 (大多数 Onsen 示例都在 Angular 中,但我目前正在学习足够多的新东西,此时不想再有其他东西来增加混乱。)
正如@Munsterlander 提到的那样 - 您不能将事件附加到尚未添加到 DOM 的元素。目前,您正在做的事情被认为是最好的做事方式。所以我只是建议尝试简化现有代码而不实际改变它的总体思路。例如:内联某些函数并使用 ons.ready
而不是 deviceready
。此代码的同等且更简单的版本可以是:
document.addEventListener("pageinit", function (event) {
console.log("init Fired!");
if (event.target.id == "newPage") {
$('#submit-btn').on('click', doSomethingUseful);
}
});
ons.ready(function () {
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener('resume', onResume.bind(this), false);
// TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
$('#button').on('click', function () {
myNavigator.pushPage('newPage.html', { animation: 'slide' })
});
});
通常我还建议使用页面 ID 制作类似对象的东西。类似于:
var handlers = {
newPage: function(e) { $('#submit-btn').click(doSomethingUseful); },
page2: function(e) { $('#submit-btn2').click(doSomethingUseful2); }
};
和
document.addEventListener('pageinit', function(e) {
if (handlers.hasOwnProperty(e.target.id)) {
handlers[e.target.id](e);
}
});
我想现在是给出您想要的真正答案的时候了。由于您无法在将元素添加到 DOM 之前收听它们,因此如果您愿意,您可以收听事件并以与处理 pageinit
事件相同的方式过滤它们的目标。使用 jQuery 有一种相对简单的方法可以做到这一点:
$(document).on(eventName, selector, handler);
因此您可以随时执行此操作
$(document).on('click', '#submit-btn', doSomethingUseful);
它会起作用,因为它将处理程序附加到文档而不是元素。因此,这将适用于您将来添加到 DOM 的所有 #submit-btn
。 :)(尽管不建议这样做,但如果您愿意,您仍然可以这样做。)