مقدمة:
غالبًا ما يكون من المفيد عرض رسائل "الرجاء الانتظار" أو صور GIF المتحركة أثناء عملية إرسال النموذج لتطبيق الويب، خاصة عندما تستغرق عملية الإرسال وقتًا طويلاً. لقد قمت مؤخرًا بتطوير برنامج إرسال استطلاع حيث يقوم المستخدمون الداخليون بتحميل جداول بيانات Excel عبر صفحة ويب. يقوم البرنامج بإدراج بيانات جدول البيانات التي تم تحميلها في قاعدة البيانات. تستغرق هذه العملية بضع ثوانٍ فقط، ولكن حتى لو كانت بضع ثوانٍ، فهي عملية انتظار واضحة جدًا من منظور صفحة الويب. أثناء اختبار البرنامج، قام بعض المستخدمين بالنقر فوق زر التحميل بشكل متكرر. لذلك، من المفيد تقديم رسالة مرئية لإخبار الأشخاص بأن التحميل قيد التقدم. وإخفاء زر التحميل في نفس الوقت لمنع النقرات المتعددة. عنصر التحكم المقدم هنا هو فئة فرعية من عنصر التحكم Button، والذي يوضح كيفية تغليف تعليمات JavaScript البرمجية من جانب العميل في عنصر تحكم خادم ASP.NET لتوفير وظائف ملائمة.
على الرغم من وجود العديد من أمثلة جافا سكريبت لإنجاز ذلك، فقد وجدت بعض المشكلات عندما حاولت تغليف هذه الوظائف في عناصر تحكم ASP.NET. لقد حاولت أولاً إبطال الزر من خلال معالج جافا سكريبت onclick واستبداله بنص آخر. لكنني وجدت الأمر صعبًا للغاية، لأن هذا سيعيق وظيفة حدث النقر على جانب خادم asp.net. ما نجح أخيرًا وحصل على دعم جيد للمتصفحات المختلفة هو عرض الزر في علامة div. يمكن إخفاء div وإبعاده عن حدث النقر الخاص بـ asp.net.
استخدام عنصر التحكم
باعتباره مشتقًا من عنصر التحكم بالزر العادي، فإن وظائف PleaseWaitButton هي نفسها بشكل أساسي. ويستخدم ثلاث خصائص إضافية لإدارة عرض رسائل أو صور "الرجاء الانتظار" عند النقر فوق الزر.
يرجى الانتظارالنص
هذه هي الرسالة النصية من جانب العميل التي يتم عرضها، وإذا كانت موجودة، فسوف تحل محل الزر عند النقر فوق الزر.
من فضلك انتظر الصورة
هذا هو ملف الصورة (مثل صورة gif المتحركة) الذي يتم عرضه، وإذا كان موجودًا، فسيتم استبدال الزر عند النقر فوقه. ستصبح هذه السمة سمة src في علامة <img>.
من فضلك انتظر النوع
إحدى قيم تعداد PleaseWaitTypeEnum: TextOnly، أو ImageOnly، أو TextThenImage، أو ImageThenText. يتحكم في تخطيط الرسائل والصور.
يوجد أدناه مثال لملف .aspx يوضح PleastWaitButton مع مجموعة PleaseWaitText وPleaseWaitImage.
<%@ لغة الصفحة = "C#" %>
<%@ تسجيل TagPrefix = "cc1" مساحة الاسم = "JavaScriptControls"
التجميع = "PleaseWaitButton" %>
<script runat = "server">
الفراغ الخاص PleaseWaitButton1_Click(object sender, System.EventArgs e)
{
// معالج حدث النقر من جانب الخادم؛
// محاكاة شيء قد يستغرق وقتًا طويلاً،
// مثل تحميل ملف أو معالجة خادم تستغرق وقتًا طويلاً
DateTime dt = DateTime.Now.AddSeconds(5);
بينما (DateTime.Now <dt)
{
// لا تفعل شيئًا؛ محاكاة توقف مؤقت لمدة 5 ثوانٍ
}
// في نهاية الحلقة عرض رسالة نجاح
// وإخفاء نموذج الإرسال
PanelSuccess.Visible = true;
PleaseWaitButton1.Visible = false;
}
</script>
<أتش تي أم أل>
<الرأس>
<title>اختبار PleaseWaitButton</title>
</الرأس>
<الجسم>
<form id="Form1"method="post" runat="server">
<P>اختبار عنصر التحكم PleaseWaitButton.</p>
<cc1:PleaseWaitButton معرف = "PleaseWaitButton1" runat = "الخادم"
Text="انقر فوقي لبدء عملية تستغرق وقتًا طويلاً"
يرجى الانتظارالنص = "الرجاء الانتظار"
من فضلك انتظر الصورة = "من فضلك انتظر.gif"
OnClick="PleaseWaitButton1_Click" />
<asp: معرف اللوحة = "panelSuccess" runat = "الخادم"
مرئي = "خطأ">
شكرا لك على تقديم هذا النموذج أنت حقا
أروع مستخدم سعدت بخدمته على الإطلاق.
لا، حقا، أعني ذلك، كان هناك آخرون، بالتأكيد،
لكنك حقًا في فصل دراسي بمفردك.
</asp:لوحة>
</النموذج>
</الجسم>
</html>
كيف يعمل
عنصر التحكم PleaseWaitButton يعرض زر ASP.NET قياسي داخل علامة <div>. كما يعرض أيضًا علامة <div> فارغة للمعلومات/الصورة. عند النقر على الزر، يتم التحكم في إخفاء الزر وعرض المعلومات بواسطة وظيفة Javascript (انظر وظيفة العميل أدناه). للراحة، تتم معالجة تنفيذ جميع أكواد عميل جافا سكريبت الضرورية من خلال التحكم في خادم PleaseWaitButton.
نظرًا لأن PleaseWaitButton تنفذ معالج جافا سكريبت onclick الخاص بها، يتعين علينا اتخاذ بعض الخطوات الإضافية للحفاظ على معالج onclick الأصلي والسماح لعنصر التحكم بتشغيل بعض تعليمات التحقق من الصحة من جانب العميل بشكل نظيف. من أجل تحقيق هذا الهدف، نقوم أولاً باستعادة الفئة الأساسية للزر إلى المخزن المؤقت للسلسلة، ثم نتعامل معها بمهارة لتضمين رمز onclick الذي حددناه.
تجاوز محمي عرض باطلة (إخراج HtmlTextWriter)
{
// إخراج HTML للزر (مع السمات)
// إلى HtmlTextWriter الوهمي
StringWriter sw = new StringWriter();
HtmlTextWriter wr = new HtmlTextWriter(sw);
base.Render(wr);
string sButtonHtml = sw.ToString();
wr.Close();
sw.Close();
// الآن قم بتعديل الكود ليتضمن معالج "onclick".
// من خلال استدعاء الدالة PleaseWait() بشكل مناسب
// بعد أي عملية تحقق من جانب العميل.
sButtonHtml = ModifyJavaScriptOnClick(sButtonHtml);
// قبل عرض الزر، قم بإخراج <div> فارغًا
// سيتم ملؤها من جانب العميل عبر جافا سكريبت
// مع رسالة "الرجاء الانتظار""
Output.Write(string.Format("<div id='pleaseWaitButtonDiv2_{0}'>"،
this.ClientID));
put.Write("</div>");
// عرض الزر في علامة <div> مغلفة خاصة به
Output.Write(string.Format("<div id='pleaseWaitButtonDiv_{0}'>",
this.ClientID));
Output.Write(sButtonHtml);
Output.Write("</div>");
}
من المؤكد أن هذه التقنية المتمثلة في تقليل الزر إلى مخزن مؤقت للسلسلة ثم معالجة محتواه عند النقر هي اختراق ولكنها تسمح لنا بتنفيذ كود التحقق القياسي في فئة الزر الأصلي ثم تنفيذ استدعاء دالة Javascript PleaseWait(). بدون القيام بذلك، سيتعين علينا تنفيذ استدعاء دالة PleaseWait() في سمة onclick قبل رمز التحقق، إلا إذا كنا على استعداد لتجاوز عرض سمة فئة Button الأصلية بشكل كامل. بهذه الطريقة، حتى لو كانت هناك أخطاء في الإدخال على الصفحة، فسيكون لها تأثير إخفاء الزر وعرض رسالة "الرجاء الانتظار" التي لا نريدها. لذلك، يجب أن نجبر وظيفة عميلنا PleaseWait() في معالج onclick على الظهور بعد التحقق من صحة صفحة العميل.
يتم تعديل سمة onclick في وظيفة ModifyJavaScriptOnClick(). تحصل هذه الوظيفة على سلسلة HTML التي يعرضها الزر وتتحقق لمعرفة ما إذا كانت سمة onclick موجودة أم لا. إذا كان الأمر كذلك، فإن هذه الوظيفة تتحقق من استخدام رمز التحقق من جانب العميل. إذا كان الأمر كذلك، فستتم إضافة وظيفة PleaseWait() التي حددناها في نهاية رمز onclick الموجود، مباشرة بعد فحص المتغير المنطقي Page_IsValid بواسطة العميل. يمثل هذا المتغير ما إذا كان يتم استخدام عنصر تحكم التحقق من الصحة. إذا كانت قيمة Page_IsValid خاطئة، فلن يتم عرض الرسالة "الرجاء الانتظار". يتم عرضه إذا كان صحيحًا.
سلسلة خاصة ModifyJavaScriptOnClick (سلسلة sHtml)
{
// شكرًا لعضو CodeProject KJELLSJ (Kjell-Sverre Jerijaervi)
// لأفكار التعليمات البرمجية للسماح للزر بالعمل مع التحقق من جانب العميل
string sReturn = "";
string sPleaseWaitCode = GeneratePleaseWaitJavascript();
// هل هناك سمة موجودة عند النقر؟
Regex rOnclick = new Regex("onclick="(?<onclick>[^"]*)");
Match mOnclick = rOnclick.Match(sHtml);
إذا (mOnclick.Success)
{
// هناك سمة onclick موجودة؛
// أضف الكود الخاص بنا إلى نهايته إذا كان من جانب العميل
// تم التحقق من الصحة، تأكد
// نتحقق لمعرفة ما إذا كانت الصفحة صالحة؛
سلسلة sExisting = mOnclick.Groups["onclick"].Value;
سلسلة sReplace = sExisting
+ (sExisting.Trim().EndsWith(";") ? "" : "; ");
إذا (IsValidatorIncludeScript() && this.CausesValidation)
{
// تضمين التعليمات البرمجية للتحقق مما إذا كانت الصفحة صالحة
string sCode = "if (Page_IsValid)" + sPleaseWaitCode
+ "إرجاع Page_IsValid؛"؛
// أضف الكود الخاص بنا إلى نهاية كود onclick الموجود؛
sReplace = sReplace + sCode;
}
آخر
{
// لا تقلق بشأن صلاحية الصفحة؛
sReplace = sReplace + sPleaseWaitCode;
}
// الآن استبدل رمز onclick الخاص بنا
sReplace = "onclick="" + sReplace;
sReturn = rOnclick.Replace(sHtml, sReplace);
}
آخر
{
// لا توجد خاصية onclick موجودة؛
// أضف لنا
int i = sHtml.Trim().Length - 2;
string sInsert = "onclick="" + sPleaseWaitCode + "" "؛
sReturn = sHtml.Insert(i, sInsert);
}
return sReturn;
}
يستخدم IsValidatorIncludeScript() الفحص أعلاه لمعرفة ما إذا كان هناك كتلة تعليمات برمجية قياسية لـ Javascript للتحكم في التحقق من صحة asp.net مسجلة في الصفحة. يستخدم ما يلي طريقة بسيطة لاختبار ما إذا كان هناك رمز التحقق من الصحة ومتغيرات مثل Page_IsValid.
المنطق المنطقي الخاص IsValidatorIncludeScript()
{
// قم بإرجاع TRUE إذا كانت هذه الصفحة قد سجلت جافا سكريبت
// للتحقق من جانب العميل، قد لا يتم تسجيل هذا الرمز
// إذا اكتشف ASP.NET ما يفكر فيه (بشكل صحيح أو غير صحيح)
// هو متصفح ذو مستوى أدنى
return this.Page.IsStartupScriptRegistered("ValidatorIncludeScript");
} يقوم GeneratePleaseWaitJavascript() التالي بإنشاء وظيفة PleaseWait() Javascript الموجودة في سمة onclick. يمكننا تحديد التخطيط المطلوب من خلال فحص خصائص عنصر التحكم.
سلسلة خاصة GeneratePleaseWaitJavascript()
{
// إنشاء استدعاء دالة JavaScript "PleaseWait()".
// مناسب للاستخدام في
سلسلة معالجة الأحداث عند النقر sMessage = "";
string sText = _pleaseWaitText؛
string sImage = (_pleaseWaitImage != String.Empty
سلسلة.تنسيق(؟
"<img src="{0}" align="absmiddle" alt="{1}"/>"
، _PleaseWaitImage، _PleaseWaitText )
: String.Empty)؛
// إنشاء التخطيط بناءً على PleaseWaitType
التبديل (_pleaseWaitType)
{
الحالة PleaseWaitTypeEnum.TextThenImage:
sMessage = sText + sImage;
استراحة؛
الحالة PleaseWaitTypeEnum.ImageThenText:
sMessage = sImage + sText;
استراحة؛
الحالة PleaseWaitTypeEnum.TextOnly:
sMessage = sText;
استراحة؛
الحالة PleaseWaitTypeEnum.ImageOnly:
sMessage = sImage;
استراحة؛
}
// إرجاع قطعة الكود النهائية
رمز السلسلة = string.Format(
"الرجاء الانتظار('الرجاء الانتظارButtonDiv_{0}'،
'PleaseWaitButtonDiv2_{1}', '{2}');"
، this.ClientID، this.ClientID، sMessage)؛
sCode = sCode.Replace(""", """);
return sCode;
}
إذا قمت بتحديد PleaseWaitImage، فيجب عليك تضمين جزء إضافي من كود Javascript لإعلام العميل بتحميل الصورة مسبقًا. يجب أن يظهر تسجيل هذا البرنامج النصي في طريقة OnPreRender التي تم تجاوزها. المفتاح المسجل هو اسم الصورة؛ إذا كانت هناك أزرار متعددة تستخدم نفس الصورة، فيجب تنفيذ البرنامج النصي للتحميل المسبق مرة واحدة فقط. يتم استخدام التعبير العادي هنا لإنشاء متغير صورة Javascript لضمان تحويل الأحرف الخاصة (مثل الشرطة المائلة في مسارات الملفات) إلى شرطة سفلية.
تجاوز محمي باطل OnPreRender (EventArgs e)
{
base.OnPreRender (e);
// إذا كنا نستخدم صورة، فقم بتسجيل بعض جافا سكريبت
// للتحميل المسبق للصورة من جانب العميل
إذا (_pleaseWaitImage != String.Empty
&& _pleaseWaitType != PleaseWaitTypeEnum.TextOnly)
RegisterJavascriptPreloadImage(_pleaseWaitImage);
}
باطلة خاصة RegisterJavascriptPreloadImage(string sImage)
{
Regex rex = new Regex("[^a-zA-Z0-9]");
string sImgName = "img_" + rex.Replace(sImage, "_");
StringBuilder sb = new StringBuilder();
sb.Append("<script language='JavaScript'>");
sb.Append("if (document.images) { ");
sb.AppendFormat("{0} = صورة جديدة();"، sImgName);
sb.AppendFormat("{0}.src = "{1}";"، sImgName, sImage);
sb.Append(" } ");
sb.Append("</script>");
this.Page.RegisterClientScriptBlock(sImgName + "_PreloadScript",
sb.ToString());
}
وظائف جانب العميل
يحتوي الملف النصي المضمن javascript.txt على <div> الذي يخفي الزر والتعليمات البرمجية من جانب العميل التي تعرض الرسالة أو الصورة "الرجاء الانتظار". يتم تحميل هذه الرموز في الطريقة الخاصة RegisterJavascriptFromResource() التي يتم استدعاؤها في طريقة OnInit() التي تم تجاوزها. تستدعي هذه الطريقة الطريقة العامة GetEmbeddedTextFile()، التي تقوم بتحميل الملف كمصدر وإرجاع المحتوى كسلسلة.
تجاوز محمي باطل OnInit (EventArgs e)
{
base.OnInit(e);
// يتم الاحتفاظ بكود جافا سكريبت من جانب العميل
// في المورد المضمن، قم بتحميل البرنامج النصي
// وقم بتسجيله في الصفحة.
RegisterJavascriptFromResource();
}
الفراغ الخاص RegisterJavascriptFromResource()
{
// تحميل الملف النصي المضمن "javascript.txt"
// وقم بتسجيل محتوياته كبرنامج نصي من جانب العميل
string sScript = GetEmbeddedTextFile("javascript.txt");
this.Page.RegisterClientScriptBlock("PleaseWaitButtonScript", sScript);
}
سلسلة خاصة GetEmbeddedTextFile (سلسلة sTextFile)
{
// وظيفة عامة لاسترداد المحتويات
// لمورد ملف نصي مضمن كسلسلة
// سنحصل على التجميعة المنفذة ونشتقها
// مساحة الاسم باستخدام النوع الأول في التجميع
التجميع a = Assembly.GetExecutingAssembly();
String sNamespace = a.GetTypes()[0].Namespace;
// مع التجميع ومساحة الاسم، سنحصل على
// المورد المضمن كدفق
الدفق s = a.GetManifestResourceStream (
string.Format("{0}.{1}"، sNamespace، sTextFile)
);
// قراءة محتويات الدفق في سلسلة
StreamReader sr = StreamReader(s) الجديد;
String sContents = sr.ReadToEnd()
;
s.Close();
return sContents;
}
يحتوي المورد المضمن javascript.txt على الأسلوب من جانب العميل PleaseWait() الذي يتم تنفيذه في معالج Javascript onclick للزر. يستدعي هذا الرمز أيضًا طريقة HideDiv() من جانب العميل لإخفاء حاوية الزر <div>، ثم يقوم بتجميع المعلومات أو الصورة في علامة <div> الفارغة مسبقًا عن طريق تعيين سمة InternalHTML. تقوم الوظيفة المساعدة GetDiv() بإرجاع كائن <div> بالمعرف عن طريق التحقق من document.getElementById وdocument.all وdocument.layers، مما يضمن التوافق مع المتصفحات المختلفة. فيما يلي الكود الكامل لملف javascript.txt:
<لغة البرمجة = "جافا سكريبت">
الدالة GetDiv(sDiv)
{
فارديف.
إذا (document.getElementById)
div = document.getElementById(sDiv);
وإلا إذا (document.all)
div = eval("window." + sDiv);
وإلا إذا (document.layers)
div = document.layers[sDiv];
آخر
div = null
;
}
الدالة HideDiv(sDiv)
{
d = GetDiv(sDiv);
إذا (د)
{
إذا (document.layers) d.visibility = "hide";
else d.style.visibility = "hidden";
}
}
الدالة PleaseWait(sDivButton, sDivMessage, sInnerHtml)
{
HideDiv(sDivButton);
var d = GetDiv(sDivMessage);
إذا (د) d.innerHTML = sInnerHtml؛
}
</script>
الرابط الأصلي: http://www.codeproject.com/aspnet/PleaseWaitButton.asp
تنزيل المشروع المصدر - 7 كيلو بايت
تنزيل المشروع التجريبي - 30 كيلو بايت
http://www.cnblogs.com/jeffamy/archive/2006/08/20/481952.html