高效日历控件的实现

在Web开发中,日期选择器是一个常见的需求。然而,大多数日期选择器在弹出新窗口和初始化时耗时较长,这导致用户体验不佳,用户可能会选择手动输入日期,从而增加了出错的可能性。本文将介绍如何利用Microsoft的calendar.htc文件,以更高效的方式实现日历控件

  • 完全封装的日期选择器/日历。
  • 快速加载。
  • 不受弹出窗口拦截器的影响(当从脚本打开时)。
  • 快速应用开发(RAD)。
  • 可以针对HTML控件或ASP.NETWeb控件。

实现步骤

首先,需要声明命名空间,这是为了确保日历元素有一个唯一的限定符。HTML元素有一个xmlns属性,它声明了astutemedia命名空间。设置这个属性允许在文档中使用astutemedia前缀。接下来,使用import指令将日历元素导入到命名空间中。

<html xmlns:astutemedia> <head> <?import namespace="astutemedia" implementation="CalendarPopup.htc"> </head>

import指令是实现主要文档中元素行为的关键。当浏览器开始处理import指令时,它会等待HTC文件的内容完全下载完成后再继续。这种指令的处理方式是行为同步绑定到自定义元素的原因。

使用CalendarPopup.htc元素行为ASP.NET服务器控件类似,但所有处理都是在客户端完成的。从下面的代码片段中可以看到,Calendar1有一个target属性,它引用了一个文本框,该文本框将被选中的日期填充。第二个元素没有提供target,但通过selectedDate事件属性从onDateSelected事件中获取选定的日期。

<input class="FormTextBox" id="Date1" type="text" maxlength="10" name="Date1"> <astutemedia:calendar id="Calendar1" target="Date1"> </astutemedia:calendar> <astutemedia:calendar id="Calendar2" onDateSelected="alert(window.event.selectedDate)"> </astutemedia:calendar>

创建行为的解决方案包括四个文件:

  • Calendar.gif - 这是行为渲染的日历图标。
  • Calendar.htc - 这是Microsoft的日历行为。
  • Calendar.htm - 这是封装在HTML文件中的弹出窗口的主体。
  • CalendarPopup.htc - 这是主要行为。

Calendar.htc行为有一个小改动,允许双击日期来选择它。这是通过添加一个名为OnCalendarDblClick的自定义事件实现的。

<public:event id="onCalendarDblClick" name="oncalendardblclick">

当日历的内部表格被双击时,这个事件会被调用。引用innerTableElem并将DblClick函数附加到ondblclick事件上。

window.document.all.innerTableElem.attachEvent("ondblclick", DblClick);

DblClick函数...

function DblClick() { var oEvent = createEventObject(); onCalendarDblClick.fire(oEvent); }

在Calendar.htm文件中使用这个事件。在OnCalendarDblClick事件上,调用一个名为CloseCalendar的函数,该函数暴露了选定日期的值。

oncalendardblclick="CloseCalendar()"

这个函数是严格必要的,因为可以直接从CalendarPopup.htc调用Unload函数。但添加这个函数可以提高可读性。

function CloseCalendar() { var val = Calendar.value; var id = parent.document.body.children[0].ParentId; parent.parent.document.getElementById(id).Unload(val); }

CalendarPopup.htc包含了主要功能。它将日历作为自定义元素暴露出来,并以弹出窗口的形式生成日期选择器。首先声明组件。

<public:component tagname="Calendar"> <public:defaults viewLinkContent="true" /> <public:property name="Version" value="Calendar 1.0" /> <public:property name="Target" value="" /> <public:event id="onDateSelected" name="ondateselected"> <public:method name="Unload" /> <public:attach event="oncontentready" onevent="Init()" /> </public:component>

从上面的代码示例中可以看到,暴露了一个Target属性,并给它一个默认属性为空字符串。还暴露了一个名为onDateSelected的事件,当弹出窗口卸载时会被调用。Unload方法由Calendar.htm文件中的CloseCalendar函数调用。然后将“Init”函数附加到持有页面(想要使用行为的页面)上的一个事件上,该事件是onContentReady,当持有页面上的内容完全加载时,该事件会被触发。

function Init() { // Check to see if there is a target element. if (Target != null && Target != "") { // Add a double click to the target elem, to show the calendar winDoc.getElementById(Target).attachEvent("ondblclick", ShowPopup); } // Create a popup object popup = win.createPopup(); popupBody = popup.document.body; // Add the scriptlet to the popups body. popupBody.innerHTML = ""; }

Unload函数触发onDateSelected事件,如果存在目标,则用选定的日期值填充它。然后隐藏弹出窗口

function Unload(val) { // Create a new event. var e = createEventObject(); // Expose the selected value with the event. e.selectedDate = val; // Fire the event. onDateSelected.fire(e); if (Target != null && Target != "") { // Find the target in the parent document and set the value. winDoc.getElementById(Target).value = val; } // Hide the popup. popup.hide(); }

最后一个函数是ShowPopup函数;这个函数在日历图标被点击或目标元素被双击时显示弹出窗口。它将弹出窗口定位在点击/双击发生的位置22像素处。它还确保它不会与浏览器窗口的边界冲突。

function ShowPopup() { var wEvent = win.event; var winDocBody = winDoc.body; var popupWidth = 320; var popupHeight = 250; // Set the x and y from where the mouse clicks. x = wEvent.x + 22; y = wEvent.y - 22; // Check to see if the popup goes out of bounds. if (x + popupWidth > winDocBody.clientWidth) x = wEvent.x - (popupWidth + winDocBody.scrollLeft + 22); else x += winDocBody.scrollLeft; if (y + popupHeight > winDocBody.offsetHeight) y = wEvent.y - (popupHeight + winDocBody.scrollTop + 22); else y += winDocBody.scrollTop; popupBody.style.border = "1px solid #333333"; // Show the popup. popup.show(40, -80, popupWidth, popupHeight, document.body); } <body id="TheBody"> <img src="Calendar.gif" width="16" height="15" style="cursor:hand" onclick="ShowPopup()" title="Click to show calendar" align="absMiddle"> </body>
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485