最近开发的项目引用了 jquery-easyui 界面框架,对于界面的布局便利了很多,但也遇到了不少问题。我也很少做总结,今天解决的这个问题搁了好久,实在不行了,才着手处理。
问题现象
为了保持界面表现的统一,对于弹出的消息框,要求使用 jquery 的
$.messager.alert(
'
信息
'
, info,
'
info
'
);
于是,对其进行了 简单地封装:
代码
//
信息框
function AlertInfo(info) {
$.messager.alert( ' 信息 ' , info, ' info ' );
return false ;
}
// 询问框
function AlertQuestion(ask) {
$.messager.alert( ' 询问 ' , ask, ' question ' );
return false ;
}
// 警告框
function AlertWarning(warn) {
$.messager.alert( ' 警告 ' , warn, ' warning ' );
alert(warn);
return false ;
}
function AlertInfo(info) {
$.messager.alert( ' 信息 ' , info, ' info ' );
return false ;
}
// 询问框
function AlertQuestion(ask) {
$.messager.alert( ' 询问 ' , ask, ' question ' );
return false ;
}
// 警告框
function AlertWarning(warn) {
$.messager.alert( ' 警告 ' , warn, ' warning ' );
alert(warn);
return false ;
}
前端调用:
OnClientClick="return AlertInfo('哦呀');"
//或
οnclick="AlertInfo('哦呀');"
//或
οnclick="AlertInfo('哦呀');"
后端调用:
代码
///
<summary>
/// 信息框
/// </summary>
/// <param name="info"> The info. </param>
public void AlertInfo( string info)
{
ExecuteScript( string .Format( " AlertInfo('{0}') " , info));
}
/// <summary>
/// 执行JavaScript 脚本
/// </summary>
/// <param name="scriptBody"> The script body. </param>
public void ExecuteScript( string scriptBody)
{
string scriptKey = " somekey " ;
ClientScript.RegisterStartupScript( typeof ( string ), scriptKey, scriptBody, true );
}
/// 信息框
/// </summary>
/// <param name="info"> The info. </param>
public void AlertInfo( string info)
{
ExecuteScript( string .Format( " AlertInfo('{0}') " , info));
}
/// <summary>
/// 执行JavaScript 脚本
/// </summary>
/// <param name="scriptBody"> The script body. </param>
public void ExecuteScript( string scriptBody)
{
string scriptKey = " somekey " ;
ClientScript.RegisterStartupScript( typeof ( string ), scriptKey, scriptBody, true );
}
在实际使用中,发现 使用后端 ClientScript.RegisterStartupScript 所注册的脚本会重复执行,两次。
原因查找
- 排除后端代码重复调用;
- 排除所封装JS的手误,BUG
- 排除所封装后端代码的重复注册BUG
- 排除页面的重复载入
最终发现,只要是页面 body 设成了 jqeury-easyui class,就会出现此情况。于是明白是因为JEUI 对页面的重新“渲染”,这必然也对页面后端注册的代码片段:
<
script type
=
"
text/javascript
"
>
// <![CDATA[
Alert( ' 吐血 ' )
} // ]]>
</ script >
// <![CDATA[
Alert( ' 吐血 ' )
} // ]]>
</ script >
也进行了重新“渲染”。
解决思路
在原有后端要注册的脚本中 加入 变量 __yltlClientScriptRegistKey,用于标识,所注册的脚本是否被执行过,若已被执行过,则中断。
后端处理代码:
代码
///
<summary>
/// 执行JavaScript 脚本
/// </summary>
/// <param name="scriptBody"> The script body. </param>
public void ExecuteScript( string scriptBody)
{
string scriptKey = " somekey " ;
string interruptedScript = @" if(window.__yltlClientScriptRegistKey == null ||
window.__yltlClientScriptRegistKey == undefined ||
window.__yltlClientScriptRegistKey !=' " + scriptKey + " ') { " +
" window.__yltlClientScriptRegistKey = ' " + scriptKey + " ' ;\r\n " +
scriptBody + " \r\n} " ;
// cdh 2010.0611 加入 拦截片段,
// 防止 页面因 UI 库的重复渲染 引起脚本重复执行。
ClientScript.RegisterStartupScript( typeof ( string ), scriptKey, interruptedScript, true );
}
/// 执行JavaScript 脚本
/// </summary>
/// <param name="scriptBody"> The script body. </param>
public void ExecuteScript( string scriptBody)
{
string scriptKey = " somekey " ;
string interruptedScript = @" if(window.__yltlClientScriptRegistKey == null ||
window.__yltlClientScriptRegistKey == undefined ||
window.__yltlClientScriptRegistKey !=' " + scriptKey + " ') { " +
" window.__yltlClientScriptRegistKey = ' " + scriptKey + " ' ;\r\n " +
scriptBody + " \r\n} " ;
// cdh 2010.0611 加入 拦截片段,
// 防止 页面因 UI 库的重复渲染 引起脚本重复执行。
ClientScript.RegisterStartupScript( typeof ( string ), scriptKey, interruptedScript, true );
}
最终产生的JS段如下:
代码
<
script type
=
"
text/javascript
"
>
// <![CDATA[
if (window.__yltlClientScriptRegistKey == null ||
window.__yltlClientScriptRegistKey == undefined ||
window.__yltlClientScriptRegistKey != ' somekey ' ) {
window.__yltlClientScriptRegistKey = ' somekey ' ;
Alert( ' 吐血 ' )
} // ]]>
< / script>
// <![CDATA[
if (window.__yltlClientScriptRegistKey == null ||
window.__yltlClientScriptRegistKey == undefined ||
window.__yltlClientScriptRegistKey != ' somekey ' ) {
window.__yltlClientScriptRegistKey = ' somekey ' ;
Alert( ' 吐血 ' )
} // ]]>
< / script>
此记, 希望能给后来者一个线索.