HTML元素,自定义客户端事件

时间:2009-09-09 13:58:06

标签: asp.net javascript javascript-events html

我有一个复合控件,它会发出看起来像这样的HTML

<span id="myControl">
   <select id="myControl_select">
      <option value=""></option>
      <option value="1">Item 1</option>
      <option value="2">Item 2</option>
   </select>
</span>

我希望父级控件在包含的下拉列表onchange事件触发时触发事件。由于这是一个复合控件,我必须允许此控件的使用者能够分配事件处理程序(我希望通过一个名为onvaluechanged或其他东西的html属性)


编辑以纳入bobince的建议。唯一的问题是参数参数未被传递。它目前是“未定义的”。

<script>
    window.onload = function() {
        var objSelect = document.getElementById('myControl_select')

        if (objSelect.attachEvent)
            objSelect.attachEvent("onchange", myControl_ddlOnChange);
        else if (objSelect.addEventListener)
            objSelect.addEventListener("onchange", myControl_ddlOnChange, false);
    }   

    function myControl_ddlOnChange()   
    {
        //fire span on value changed event   
        var target= document.getElementById('mycontrol');
        var handler= target.getAttribute('onvaluechanged');

        var args = { text : 'Hi!', index : 0 } 

        if (handler)    
            new Function(handler).call(target, args);
    }

    function myControl_ValueChanged()
    {
        alert(arguments[0]);
    }
</script>

<span id="myControl" onvaluechanged="myControl_ValueChanged();">
   <select id="myControl_select">
      <option value=""></option>
      <option value="1">Item 1</option>
      <option value="2">Item 2</option>
   </select>
</span>

1 个答案:

答案 0 :(得分:2)

不要使用attachEvent,它只是IE浏览器。您可以破解在IE上使用attachEvent或在其他浏览器上使用addEventListener的解决方案,或者使用已经为您执行此操作的框架,但出于您的目的,普通事件处理程序属性应该足够了:

document.getElementById('myControl_select').onchange= myControl_ddlOnChange;

开始添加自己的自定义HTML onsomething属性并不是一个好主意。除了无效之外,浏览器不会像将onclick HTML属性转换为onclick JavaScript属性那样神奇。您必须手动执行此操作,如下所示:

var target= document.getElementById('myControl');
var handler= target.getAttribute('onvaluechanged');
if (handler)
    new Function(handler).call(target);

让调用者自己使用JavaScript函数写入'onclick'通常会更好。 HTML事件处理程序属性非常糟糕,通常应该避免使用。

ETA评论:

没有传递参数的原因是因为你的事件处理程序:

onvaluechanged="myControl_ValueChanged();"

不会传递任何参数。你可以说:

onvaluechanged="myControl_ValueChanged(arguments[0]);"

或者,传递任意数量的参数:

onvaluechanged="myControl_ValueChanged.apply(this, arguments);"

但实际上,这远离了事件处理程序通常的工作方式,因为它们没有参数(*)。更容易坚持使用JavaScript并说:

var control= document.getElementById('myControl');

// to register
//
control.onvaluechanged= myControl_ddlOnChange;

// to call
//
control.onvaluechanged(/* any arguments; 'this' inside ddlOnChange is the control */);

而不是这个好奇的功能。

其他次要命中:addEventListener采用'change'而不是'onchange'; getElementById('myControl')中的大写C.

(*:除了“事件”参数,非IE中除外)

相关问题