我正在尝试在项目中修改一个名为YetAnotherForum.net的开源论坛,他们有一个名为Yaf:ThemeButton的自定义用户控件。现在它在此代码中使用onclick方法呈现为锚点
ThemeButton.cs
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace YAF.Controls
{
/// <summary>
/// The theme button.
/// </summary>
public class ThemeButton : BaseControl, IPostBackEventHandler
{
/// <summary>
/// The _click event.
/// </summary>
protected static object _clickEvent = new object();
/// <summary>
/// The _command event.
/// </summary>
protected static object _commandEvent = new object();
/// <summary>
/// The _attribute collection.
/// </summary>
protected AttributeCollection _attributeCollection;
/// <summary>
/// The _localized label.
/// </summary>
protected LocalizedLabel _localizedLabel = new LocalizedLabel();
/// <summary>
/// The _theme image.
/// </summary>
protected ThemeImage _themeImage = new ThemeImage();
/// <summary>
/// Initializes a new instance of the <see cref="ThemeButton"/> class.
/// </summary>
public ThemeButton()
: base()
{
Load += new EventHandler(ThemeButton_Load);
this._attributeCollection = new AttributeCollection(ViewState);
}
/// <summary>
/// ThemePage for the optional button image
/// </summary>
public string ImageThemePage
{
get
{
return this._themeImage.ThemePage;
}
set
{
this._themeImage.ThemePage = value;
}
}
/// <summary>
/// ThemeTag for the optional button image
/// </summary>
public string ImageThemeTag
{
get
{
return this._themeImage.ThemeTag;
}
set
{
this._themeImage.ThemeTag = value;
}
}
/// <summary>
/// Localized Page for the optional button text
/// </summary>
public string TextLocalizedPage
{
get
{
return this._localizedLabel.LocalizedPage;
}
set
{
this._localizedLabel.LocalizedPage = value;
}
}
/// <summary>
/// Localized Tag for the optional button text
/// </summary>
public string TextLocalizedTag
{
get
{
return this._localizedLabel.LocalizedTag;
}
set
{
this._localizedLabel.LocalizedTag = value;
}
}
/// <summary>
/// Defaults to "yafcssbutton"
/// </summary>
public string CssClass
{
get
{
return (ViewState["CssClass"] != null) ? ViewState["CssClass"] as string : "yafcssbutton";
}
set
{
ViewState["CssClass"] = value;
}
}
/// <summary>
/// Setting the link property will make this control non-postback.
/// </summary>
public string NavigateUrl
{
get
{
return (ViewState["NavigateUrl"] != null) ? ViewState["NavigateUrl"] as string : string.Empty;
}
set
{
ViewState["NavigateUrl"] = value;
}
}
/// <summary>
/// Localized Page for the optional link description (title)
/// </summary>
public string TitleLocalizedPage
{
get
{
return (ViewState["TitleLocalizedPage"] != null) ? ViewState["TitleLocalizedPage"] as string : "BUTTON";
}
set
{
ViewState["TitleLocalizedPage"] = value;
}
}
/// <summary>
/// Localized Tag for the optional link description (title)
/// </summary>
public string TitleLocalizedTag
{
get
{
return (ViewState["TitleLocalizedTag"] != null) ? ViewState["TitleLocalizedTag"] as string : string.Empty;
}
set
{
ViewState["TitleLocalizedTag"] = value;
}
}
/// <summary>
/// Non-localized Title for optional link description
/// </summary>
public string TitleNonLocalized
{
get
{
return (ViewState["TitleNonLocalized"] != null) ? ViewState["TitleNonLocalized"] as string : string.Empty;
}
set
{
ViewState["TitleNonLocalized"] = value;
}
}
/// <summary>
/// Gets Attributes.
/// </summary>
public AttributeCollection Attributes
{
get
{
return this._attributeCollection;
}
}
/// <summary>
/// Gets or sets CommandName.
/// </summary>
public string CommandName
{
get
{
if (ViewState["commandName"] != null)
{
return ViewState["commandName"].ToString();
}
return null;
}
set
{
ViewState["commandName"] = value;
}
}
/// <summary>
/// Gets or sets CommandArgument.
/// </summary>
public string CommandArgument
{
get
{
if (ViewState["commandArgument"] != null)
{
return ViewState["commandArgument"].ToString();
}
return null;
}
set
{
ViewState["commandArgument"] = value;
}
}
#region IPostBackEventHandler Members
/// <summary>
/// The i post back event handler. raise post back event.
/// </summary>
/// <param name="eventArgument">
/// The event argument.
/// </param>
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
OnCommand(new CommandEventArgs(CommandName, CommandArgument));
OnClick(EventArgs.Empty);
}
#endregion
/// <summary>
/// Setup the controls before render
/// </summary>
/// <param name="sender">
/// </param>
/// <param name="e">
/// </param>
private void ThemeButton_Load(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(this._themeImage.ThemeTag))
{
// add the theme image...
Controls.Add(this._themeImage);
}
// render the text if available
if (!String.IsNullOrEmpty(this._localizedLabel.LocalizedTag))
{
Controls.Add(this._localizedLabel);
}
}
/// <summary>
/// The render.
/// </summary>
/// <param name="output">
/// The output.
/// </param>
protected override void Render(HtmlTextWriter output)
{
// get the title...
string title = GetLocalizedTitle();
output.BeginRender();
output.WriteBeginTag("a");
output.WriteAttribute("id", ClientID);
if (!String.IsNullOrEmpty(CssClass))
{
output.WriteAttribute("class", CssClass);
}
if (!String.IsNullOrEmpty(title))
{
output.WriteAttribute("title", title);
}
else if (!String.IsNullOrEmpty(TitleNonLocalized))
{
output.WriteAttribute("title", TitleNonLocalized);
}
if (!String.IsNullOrEmpty(NavigateUrl))
{
output.WriteAttribute("href", NavigateUrl.Replace("&", "&"));
}
else
{
// string.Format("javascript:__doPostBack('{0}','{1}')",this.ClientID,""));
output.WriteAttribute("href", Page.ClientScript.GetPostBackClientHyperlink(this, string.Empty));
}
bool wroteOnClick = false;
// handle additional attributes (if any)
if (this._attributeCollection.Count > 0)
{
// add attributes...
foreach (string key in this._attributeCollection.Keys)
{
// get the attribute and write it...
if (key.ToLower() == "onclick")
{
// special handling... add to it...
output.WriteAttribute(key, string.Format("{0};{1}", this._attributeCollection[key], "this.blur();this.display='none';"));
wroteOnClick = true;
}
else if (key.ToLower().StartsWith("on") || key.ToLower() == "rel" || key.ToLower() == "target")
{
// only write javascript attributes -- and a few other attributes...
output.WriteAttribute(key, this._attributeCollection[key]);
}
}
}
// IE fix
if (!wroteOnClick)
{
output.WriteAttribute("onclick", "this.blur();this.style.display='none';");
}
output.Write(HtmlTextWriter.TagRightChar);
output.WriteBeginTag("span");
output.Write(HtmlTextWriter.TagRightChar);
// render the optional controls (if any)
base.Render(output);
output.WriteEndTag("span");
output.WriteEndTag("a");
output.EndRender();
}
/// <summary>
/// The get localized title.
/// </summary>
/// <returns>
/// The get localized title.
/// </returns>
protected string GetLocalizedTitle()
{
if (Site != null && Site.DesignMode == true && !String.IsNullOrEmpty(TitleLocalizedTag))
{
return String.Format("[TITLE:{0}]", TitleLocalizedTag);
}
else if (!String.IsNullOrEmpty(TitleLocalizedPage) && !String.IsNullOrEmpty(TitleLocalizedTag))
{
return PageContext.Localization.GetText(TitleLocalizedPage, TitleLocalizedTag);
}
else if (!String.IsNullOrEmpty(TitleLocalizedTag))
{
return PageContext.Localization.GetText(TitleLocalizedTag);
}
return null;
}
/// <summary>
/// The on click.
/// </summary>
/// <param name="e">
/// The e.
/// </param>
protected virtual void OnClick(EventArgs e)
{
var handler = (EventHandler) Events[_clickEvent];
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// The on command.
/// </summary>
/// <param name="e">
/// The e.
/// </param>
protected virtual void OnCommand(CommandEventArgs e)
{
var handler = (CommandEventHandler) Events[_commandEvent];
if (handler != null)
{
handler(this, e);
}
RaiseBubbleEvent(this, e);
}
/// <summary>
/// The click.
/// </summary>
public event EventHandler Click
{
add
{
Events.AddHandler(_clickEvent, value);
}
remove
{
Events.RemoveHandler(_clickEvent, value);
}
}
/// <summary>
/// The command.
/// </summary>
public event CommandEventHandler Command
{
add
{
Events.AddHandler(_commandEvent, value);
}
remove
{
Events.RemoveHandler(_commandEvent, value);
}
}
}
}
现在这只是cs文件,它在实际网站的.ascx页面中这样处理
<YAF:ThemeButton ID="Save" runat="server" CssClass="yafcssbigbutton leftItem" TextLocalizedTag="SAVE"
OnClick="Save_Click" />
现在给它一个OnClick代码隐藏函数,它可以像这样执行一些服务器端函数
protected void Save_Click(object sender, EventArgs e)
{
//some serverside code here
}
现在我遇到一个问题,即用户可以多次单击并多次触发该服务器端功能。我已经在代码中添加了.cs代码中的额外onclick =“this.style.display ='none'”,但这是一个丑陋的修复我想知道是否有人会更好地禁用ThemeButton客户端??如果我需要提供更多的例子或进一步解释问题,请给我任何反馈意见。
答案 0 :(得分:1)
你可以这样做:
function disableClick(domNode) {
// replace onclick event handler with a "return false"
domNode.onclick = function() { return false; }
// have a CSS class 'button-disabled' to set the text colour or whatever
domNode.className = "button-disabled";
}
...
<a href="..." onclick="whatever; disableClick(this); return true;">click me</a>
也就是说,将onclick处理程序设置为只返回false的函数。这假设<YAF:ThemeButton>
控件呈现为&lt; a&gt;标签...
答案 1 :(得分:0)
我会尝试在按钮标记中放置一个OnClientClick。
<YAF:ThemeButton ID="Save" runat="server" CssClass="yafcssbigbutton leftItem" TextLocalizedTag="SAVE" OnClick="Save_Click" OnClientClick="this.disabled = true;" />
这应该在点击后禁用按钮。页面从postBack重新加载后,该按钮将再次启用。虽然这是YAF的自定义控件,但它可能来自标准的asp:button控件,它具有OnClienClick属性。
更多信息:MSDN