Criando eventos de cliente personalizados
Funcionalidade AJAX no ASP.NET inclui um modelo de evento cliente multicamada completo.A classe Sys.Application fornece eventos no nível do aplicativo.A classe Sys.WebForms.PageRequestManager fornece eventos que pertencem a partes da página envolvida em renderização de página parcial.Componentes individuais, como controles e comportamentos, têm seus próprios eventos.Para obter mais informações sobre esses eventos, consulte Eventos de ciclo de vida de cliente AJAX.
O ASP.NET também permite que você adicione eventos ao ciclo de vida do cliente.A classe Sys.UI.DomEvent permite que você vincule eventos DOM (modelo de objeto de documento HTML) a componentes personalizados ASP.NET AJAX.Além disso, a classe Sys.EventHandlerList permite que você crie novos eventos de cliente ASP.NET AJAX diretamente.
Anexando a eventos DOM
Em muitos casos, um evento com o qual você deseja trabalhar corresponde a um evento definido em HTML DOM.Por exemplo, um controle de botão ASP.NET AJAX personalizado pode usar o evento click do elemento <button> do HTML que está conectado a ele.Para vincular um evento baseado em DOM a um aplicativo ASP.NET AJAX ou a um componente personalizado, você usa o método addHandler da classe DomEvent, conforme mostrado no exemplo a seguir:
Sys.UI.DomEvent.addHandler(element, 'click', this.myClickHandler);
Você também pode usar o atalho $addHandler, conforme mostrado no exemplo a seguir:
$addHandler(element, 'click', this.myClickHandler);
The addHandler método usa três parâmetros: element, eventName, e handler. O parâmetro element é uma referência ao elemento DOM que expõe o evento.O parâmetro eventName é o próprio nome do evento DOM.O parâmetro handler é uma referência para a função para chamar quando o evento é gerado.Para obter mais informações, consulte AddHandler Sys.UI.DomEvent método.
Para remover um manipulador para um evento DOM, você chama o método Sys.UI.DomEvent.removeHandler ou o atalho $removeHandler, passando os mesmos parâmetros que você passa para addHandler.
Observação: |
---|
evento nomes passado para o addHandler e removeHandlerfunções não devem incluir o prefixo "on". Por exemplo, use "click", não "onclick". |
Adicionando e removendo manipuladores de eventos personalizados
Para adicionar um novo manipulador de eventos para um evento de um componente personalizado ASP.NET AJAX, use o método addHandler da classe Sys.EventHandlerList .Todos os eventos do cliente e manipuladores de evento associados no modelo de evento AJAX ASP.NET são armazenados em um objeto EventHandlerList, que é um dicionário especializado para essa finalidade.Cada componente, incluindo o objeto Application atual, tem sua própria instância EventHandlerList.Adicionando um item ao objeto EventHandlerList, você adiciona um novo evento e manipulador de eventos para o componente associado.Adicione eventos, usando a seguinte sintaxe:
this.get_events().addHandler(event, handler);
A propriedade events da classe Sys.Component retorna a instância EventHandlerList para este componente.A propriedade events é herdada pelas classes Sys.UI.Control, Sys.UI.Behavior e Sys.Application.O parâmetro event é o nome do evento novo ou existente, ao qual adiciona-se um manipulador.O parâmetro handler é uma referência para a função para chamar quando o evento é gerado.Definindo o parâmetro event para um novo valor, você adiciona um novo evento ao dicionário.
Para remover um evento personalizado do dicionário, você usa o método removeHandler da classe Sys.EventHandlerList, que usa os mesmos parâmetros que addHandler.
Para adicionar manipuladores para eventos que já estão definidos em Microsoft AJAX Library, use o acessador add_ para esse evento, como no exemplo a seguir:
Sys.Application.add_load(myLoadHandler);
Elevando eventos personalizados
Para elevar um evento personalizado, chame o método getHandler da instância EventHandlerList, passando o nome do evento como um parâmetro.Esse método retorna uma função que agrega todas as funções que são manipuladores para o evento.Chame a função retornada para gerar o evento, como no exemplo a seguir:
var h = this.get_events().getHandler('myCustomEvent')
if (h) h(this, Sys.EventArgs.Empty);
Por convenção, os manipuladores de eventos levam dois parâmetros: sender e eventArgs.O remetente é o componente ao qual o evento se aplica, normalmente this.O parâmetro eventArgs se refere a um objeto Sys.EventArgs.Este objeto pode conter informações passadas para o evento, como as coordenadas do mouse.Você pode omitir os parâmetros sender e eventArgs, enquanto a assinatura da função retornada por getHandler coincida com todas as funções do manipulador associadas.No entanto, a prática recomendada é incluir os parâmetros, como no exemplo mostrado anteriormente.
Exemplo
Descrição
O exemplo a seguir cria um teste de múltipla escolha simples com duas seções.Quando todas as perguntas em uma seção são respondidas, a cor do plano de fundo da seção é alterada.Quando o usuário clica no botão no final do teste, um mensagem de status próximo a cada pergunta aparece se a resposta estiver correta.
O aplicativo inclui instâncias de dois controles personalizados.O controle Question anexa um elemento <select> HTML e o controle Section anexa a um elemento <div> que contém um ou mais controles Question.O controle Question expõe um evento select, que está acoplado ao evento onChange do elemento <select> subjacente por uma instância Sys.UI.DomEvent.O controle Section expõe um evento complete, que é gerado por uma função definida pelo usuário quando todos os controles Question na instância Section são respondidos.
Código
O exemplo a seguir mostra a página Default.aspx que cria as instâncias de componente e trata os eventos.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" >
<title>Custom Events Example</title>
</head>
<body>
<form id="form1" >
<asp:ScriptManager ID="ScriptManager1" >
<Scripts>
<asp:ScriptReference Path="question.js" />
<asp:ScriptReference Path="section.js" />
</Scripts>
</asp:ScriptManager>
<script type="text/javascript">
// Add handler to init event
Sys.Application.add_init(appInitHandler);
function appInitHandler() {
// create components
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question1'));
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question2'));
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question3'));
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question4'));
$create(Demo.Section, null,
{complete: onSectionComplete},null, $get('group1'));
$create(Demo.Section, null,
{complete: onSectionComplete},null, $get('group2'));
}
function onAnswer(question) {
// If all questions in this section answered,
// raise complete event
var section = question.get_element().parentElement;
var questions = section.children;
$get(question.get_id() + 'Status').innerHTML = '';
for (var i=0; i<questions.length; i++) {
if (questions[i].selectedIndex === -1) {
return;
}
}
$find(section.id).raiseComplete();
}
function onSectionComplete(section) {
// Change background color of <div>.
section.get_element().style.backgroundColor = 'yellow';
}
function done() {
// Display correct answers where needed.
var c = Sys.Application.getComponents();
for (var i=0; i<c.length; i++) {
var type = Object.getType(c[i]).getName();
if (type !== 'Demo.Question') continue;
var element = c[i].get_element();
var answer = element.selectedIndex;
var correct = $find(c[i].get_id()).get_correct();
var statusElement = c[i].get_id() + 'Status';
if (answer !== correct) {
$get(statusElement).innerHTML = 'Incorrect. Try again.';
}
else
{
$get(statusElement).innerHTML = 'Correct.';
}
}
}
function resethandler() {
var c = Sys.Application.getComponents();
for (var i=0; i<c.length; i++) {
var type = Object.getType(c[i]).getName();
if (type === 'Demo.Question') {
var element = c[i].get_element();
element.selectedIndex = -1;
var answer = element.selectedIndex;
var statusElement = c[i].get_id() + 'Status';
$get(statusElement).innerHTML = '';
}
else if (type === 'Demo.Section') {
c[i].get_element().style.backgroundColor = 'White';
}
}
}
</script>
<h3>Addition</h3><br />
<div id="Group1">
2 + 2 =
<select id="Question1">
<option>2</option>
<option>22</option>
<option>4</option>
<option>5</option>
</select><span id="Question1Status"></span><br />
2 + 3 =
<select id="Question2" >
<option>3</option>
<option>23</option>
<option>5</option>
<option>6</option>
</select><span id="Question2Status"></span><br />
</div><br /> <br />
<h3>Subtraction</h3><br />
<div id="Group2">
2 - 1 =
<select id="Question3" >
<option>2</option>
<option>0</option>
<option>1</option>
<option>-2</option>
</select><span id="Question3Status"></span><br />
2 - 2 =
<select id="Question4" >
<option>2</option>
<option>-2</option>
<option>0</option>
<option>-4</option>
</select><span id="Question4Status"></span><br />
</div><br /><br />
<input id="Submit1" type="button" value="Check Answers" onclick="done()" />
<input id="Reset1" type="button" value="Start Again" onclick="resethandler()" />
</form>
</body>
</html>
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" >
<title>Custom Events Example</title>
</head>
<body>
<form id="form1" >
<asp:ScriptManager ID="ScriptManager1" >
<Scripts>
<asp:ScriptReference Path="question.js" />
<asp:ScriptReference Path="section.js" />
</Scripts>
</asp:ScriptManager>
<script type="text/javascript">
// Add handler to init event
Sys.Application.add_init(appInitHandler);
function appInitHandler() {
// create components
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question1'));
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question2'));
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question3'));
$create(Demo.Question, {correct: '3'},
{select: onAnswer},null, $get('Question4'));
$create(Demo.Section, null,
{complete: onSectionComplete},null, $get('group1'));
$create(Demo.Section, null,
{complete: onSectionComplete},null, $get('group2'));
}
function onAnswer(question) {
// If all questions in this section answered,
// raise complete event
var section = question.get_element().parentElement;
var questions = section.children;
$get(question.get_id() + 'Status').innerHTML = '';
for (var i=0; i<questions.length; i++) {
if (questions[i].selectedIndex === -1) {
return;
}
}
$find(section.id).raiseComplete();
}
function onSectionComplete(section) {
// Change background color of <div>.
section.get_element().style.backgroundColor = 'yellow';
}
function done() {
// Display correct answers where needed.
var c = Sys.Application.getComponents();
for (var i=0; i<c.length; i++) {
var type = Object.getType(c[i]).getName();
if (type !== 'Demo.Question') continue;
var element = c[i].get_element();
var answer = element.selectedIndex;
var correct = $find(c[i].get_id()).get_correct();
var statusElement = c[i].get_id() + 'Status';
if (answer !== correct) {
$get(statusElement).innerHTML = 'Incorrect. Try again.';
}
else
{
$get(statusElement).innerHTML = 'Correct.';
}
}
}
function resethandler() {
var c = Sys.Application.getComponents();
for (var i=0; i<c.length; i++) {
var type = Object.getType(c[i]).getName();
if (type === 'Demo.Question') {
var element = c[i].get_element();
element.selectedIndex = -1;
var answer = element.selectedIndex;
var statusElement = c[i].get_id() + 'Status';
$get(statusElement).innerHTML = '';
}
else if (type === 'Demo.Section') {
c[i].get_element().style.backgroundColor = 'White';
}
}
}
</script>
<h3>Addition</h3><br />
<div id="Group1">
2 + 2 =
<select id="Question1">
<option>2</option>
<option>22</option>
<option>4</option>
<option>5</option>
</select><span id="Question1Status"></span><br />
2 + 3 =
<select id="Question2" >
<option>3</option>
<option>23</option>
<option>5</option>
<option>6</option>
</select><span id="Question2Status"></span><br />
</div><br /> <br />
<h3>Subtraction</h3><br />
<div id="Group2">
2 - 1 =
<select id="Question3" >
<option>2</option>
<option>0</option>
<option>1</option>
<option>-2</option>
</select><span id="Question3Status"></span><br />
2 - 2 =
<select id="Question4" >
<option>2</option>
<option>-2</option>
<option>0</option>
<option>-4</option>
</select><span id="Question4Status"></span><br />
</div><br /><br />
<input id="Submit1" type="button" value="Check Answers" onclick="done()" />
<input id="Reset1" type="button" value="Start Again" onclick="resethandler()" />
</form>
</body>
</html>
O exemplo a seguir mostra o arquivo Question.js que define o controle Demo.Question.
Type.registerNamespace("Demo");
// Constructor
Demo.Question = function(element) {
Demo.Question.initializeBase(this, [element]);
// Create a delegate for the select event.
this._selectDelegate = null;
}
Demo.Question.prototype = {
// correct property accessors
get_correct: function() {
return this.get_element().name - 1;
},
set_correct: function(value) {
this.get_element().name = value;
},
// Bind and unbind to select event.
add_select: function(handler) {
this.get_events().addHandler('select', handler);
},
remove_select: function(handler) {
this.get_events().removeHandler('select', handler);
},
// Release resources before control is disposed.
dispose: function() {
var element = this.get_element();
if (this._selectDelegate) {
$clearHandlers(element);
delete this._selectDelegate;
}
Demo.Question.callBaseMethod(this, 'dispose');
},
initialize: function() {
var element = this.get_element();
// Make sure no option is selected.
element.value = "";
// Attach delegate to select event.
if (this._selectDelegate === null) {
this._selectDelegate = Function.createDelegate(this, this._selectHandler);
}
Sys.UI.DomEvent.addHandler(element, 'change', this._selectDelegate);
Demo.Question.callBaseMethod(this, 'initialize');
},
_selectHandler: function(event) {
var h = this.get_events().getHandler('select');
if (h) h(this, Sys.EventArgs.Empty);
}
}
Demo.Question.registerClass('Demo.Question', Sys.UI.Control);
// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager
// that this is the end of the script.
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Type.registerNamespace("Demo");
// Constructor
Demo.Question = function(element) {
Demo.Question.initializeBase(this, [element]);
// Create a delegate for the select event.
this._selectDelegate = null;
}
Demo.Question.prototype = {
// correct property accessors
get_correct: function() {
return this.get_element().name - 1;
},
set_correct: function(value) {
this.get_element().name = value;
},
// Bind and unbind to select event.
add_select: function(handler) {
this.get_events().addHandler('select', handler);
},
remove_select: function(handler) {
this.get_events().removeHandler('select', handler);
},
// Release resources before control is disposed.
dispose: function() {
var element = this.get_element();
if (this._selectDelegate) {
$clearHandlers(element);
delete this._selectDelegate;
}
Demo.Question.callBaseMethod(this, 'dispose');
},
initialize: function() {
var element = this.get_element();
// Make sure no option is selected.
element.value = "";
// Attach delegate to select event.
if (this._selectDelegate === null) {
this._selectDelegate = Function.createDelegate(this, this._selectHandler);
}
Sys.UI.DomEvent.addHandler(element, 'change', this._selectDelegate);
Demo.Question.callBaseMethod(this, 'initialize');
},
_selectHandler: function(event) {
var h = this.get_events().getHandler('select');
if (h) h(this, Sys.EventArgs.Empty);
}
}
Demo.Question.registerClass('Demo.Question', Sys.UI.Control);
// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager
// that this is the end of the script.
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
O exemplo a seguir mostra o arquivo Section.js que define o controle Demo.Section.
Type.registerNamespace("Demo");
// Constructor
Demo.Section = function(element) {
Demo.Section.initializeBase(this, [element]);
}
Demo.Section.prototype = {
// Create add and remove accessors fot the complete event.
add_complete: function(handler) {
this.get_events().addHandler("complete", handler);
},
remove_complete: function(handler) {
this.get_events().removeHandler("complete", handler);
},
// Create a function to raise the complete event.
raiseComplete: function() {
var h = this.get_events().getHandler('complete');
if (h) h(this);
},
// Release resources before control is disposed.
dispose: function() {
var element = this.get_element();
$clearHandlers(element);
Demo.Section.callBaseMethod(this, 'dispose');
}
}
Demo.Section.registerClass('Demo.Section', Sys.UI.Control);
// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager
// that this is the end of the script.
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Type.registerNamespace("Demo");
// Constructor
Demo.Section = function(element) {
Demo.Section.initializeBase(this, [element]);
}
Demo.Section.prototype = {
// Create add and remove accessors fot the complete event.
add_complete: function(handler) {
this.get_events().addHandler("complete", handler);
},
remove_complete: function(handler) {
this.get_events().removeHandler("complete", handler);
},
// Create a function to raise the complete event.
raiseComplete: function() {
var h = this.get_events().getHandler('complete');
if (h) h(this);
},
// Release resources before control is disposed.
dispose: function() {
var element = this.get_element();
$clearHandlers(element);
Demo.Section.callBaseMethod(this, 'dispose');
}
}
Demo.Section.registerClass('Demo.Section', Sys.UI.Control);
// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager
// that this is the end of the script.
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Consulte também
Tarefas
Criar Controles de Cliente Personalizados AJAX