【问题标题】:How to expand an onchange event with JavaScript如何使用 JavaScript 扩展 onchange 事件
【发布时间】:2009-06-03 18:25:49
【问题描述】:

这是我在扩展元素的 JavaScript onchange 事件时遇到的一个问题。我有几个选择元素,它们有条件地将一个 onchange 事件附加到每个元素上(当它们更改为特定值时,它会隐藏/取消隐藏某些元素)。我想有条件地添加或附加到另一个 onchange 事件,以便他们设置一个全局变量,如果他们在没有修改或禁用已经附加到它们的前一个函数的情况下进行更改。有没有办法“附加”一个附加功能或在现有功能上添加更多功能?

以下是我认为的示例:

<select id="selectbox1">
    <option>...</option>
    <option>...</option>
</select>

if (<certain conditions>) {
    document.getElementById("selectbox1").onchange = function () { 
        //hides elements to reduce clutter on a web form ...
    }
}
....
if (<other conditions>) {
    document.getElementById("selectbox1").onchange = function2 () {
        //set global variable to false
    }
}

或者,我想简单地将 1-liner“将全局变量设置为 false”添加到原始函数中。

【问题讨论】:

  • 我只是不明白为什么你不能在公共事件处理程序中正确地创建条件分支,你为什么需要扩展?
  • 不是我做不到,而是有点重新设计。这个问题更多的是关于如何将附加功能附加到函数。

标签: javascript html onchange


【解决方案1】:

您可以通过简单地使用调用其他函数的复合函数来作弊。

document.getElementById("selectbox1").onchange = function() {
    function1();
    function2();
}

您还可以使用Pro JavaScript Design Patterns 一书中描述的观察者模式。我在一篇文章 (here) 中有一个使用它的示例。

//– publisher class — 
function Publisher() { 
    this.subscribers = []; 
};

Publisher.prototype.deliver = function(data) { 
    this.subscribers.forEach(function(fn) { fn(data); }); 
};

//– subscribe method to all existing objects 
Function.prototype.subscribe = function(publisher) { 
    var that = this; 
    var alreadyExists = publisher.subscribers.some(function(el) { 
        if (el === that) { 
            return; 
        } 
    });

    if (!alreadyExists) { 
        publisher.subscribers.push(this); 
    } 
    return this; 
};

【讨论】:

    【解决方案2】:

    您想查看addEventListener()attachEvent() 函数(分别适用于基于Mozilla 的浏览器和IE)。

    查看addEventListener()attachEvent() 的文档。

    var el = document.getElementById("selectbox1");
    
    try { //For IE
        el.attachEvent("onchange", function(){ code here.. });
    }
    catch(e) { //For FF, Opera, Safari etc
        el.addEventListener("change", function(){ code here.. }, false);
    }
    

    您可以为每个元素添加多个侦听器,因此事件触发时可以调用多个函数。

    【讨论】:

      【解决方案3】:

      你会使用 jQuery 吗?这将允许您非常轻松地绑定/操作/取消绑定事件。唯一的障碍是事件处理程序按照它们绑定的顺序被激活。

      if (<certain conditions>) {
         $("#selectbox1").bind("change", eventdata, function1);
      }
      
      if (<other conditions>) {
         $("#selectbox1").bind("change", eventdata, function1);
      }
      

      而且,如果您的需求很复杂,您还可以考虑触发自定义事件。例如,代替“解释”onChange,也许有一种方法可以专门触发自定义事件。请参阅 jQuery 页面上的 last example

      【讨论】:

      • 我可以使用 jQuery,但我以前从未使用过它。如果可能,暂时避免学习曲线。
      • 尝试找出所有跨浏览器以及 JS 和浏览器的各种内部结构可能需要更多的学习曲线。而且,jQuery 很容易上手,而且值得小额投资……
      • jQuery 肯定会成为我的下一个项目!我想尝试在接下来的一两个月内把它拿起来,但在今天 COB 之前我想得到一个解决方案。
      【解决方案4】:

      如果你使用 jQUery,你会得到类似的东西

      <select id="selectbox1">
          <option>...</option>
          <option>...</option>
      </select>
      
      if (<certain conditions>) {
          $("#selectbox1").change(function () { 
              //hides elements to reduce clutter on a web form ...
          });
      }
      ....
      if (<other conditions>) {
          $("#selectbox1").change(function () { 
              //set global variable to false
          });
      }
      

      这也将主要考虑浏览器的兼容性。

      【讨论】:

        【解决方案5】:

        目前有三种不同的方法来定义事件处理程序(检测到某个事件时触发的函数):传统方法、W3C 方法和 Microsoft 方法。

        传统方法

        在传统方法中,事件处理程序是通过在 Javascript 中设置元素的 onevent 属性来定义的(就像您在示例代码中所做的那样),或者通过设置 onevent HTML 标记中的 属性(例如 &lt;select onchange="..."&gt;)。虽然这是最简单的使用方法,但现在通常不赞成使用它,因为正如您所发现的那样,它相当死板——向已经附加了事件处理程序的元素添加和删除事件处理程序并不容易。同样,将 javascript 与 HTML 混合不再被认为是正确的做法,而是应该将其包含在 &lt;script&gt; 标签中或通过 &lt;script&gt; 标签加载。

        W3C / Microsoft 方法

        W3C(万维网联盟)和 Microsoft 都定义了自己的事件模型。这两种模型的工作方式基本相同,但使用不同的语法。微软模型用于Internet Explorer,W3C模型用于其他浏览器(Firefox、Opera、Safari、Chrome等)。在这两种模型中,都提供了添加事件处理程序(W3C 的 addEventListener,Microsoft 的 attachEvent)和删除事件处理程序(removeEventListener / detachEvent)的函数。这允许您动态地向元素添加和删除特定的处理程序;在您的情况下,您可以根据第一个条件添加第一个处理程序,并根据第二个条件添加第二个处理程序。这些方法的“问题”是它们有两个,因此需要使用这两种方法以确保您的事件处理程序将在所有浏览器中注册(两种模型之间也有一些细微的差异,但这些差异对于这个问题的范围并不重要)。事实上,如果你仔细观察,你会发现大量的“addEvent”函数在必要时使用了这两种方法(并且通常回退到旧浏览器的传统方法)。例如,早在 2005 年,QuirksMode 博客就举办了一场竞赛,以构建最佳的“addEvent”函数,其结果(连同获胜函数)您可以看到here

        同样,如果您使用诸如 Prototype 或 jQuery 之类的 javascript 库,它们会附带内置的事件处理函数,可以为您处理上述问题。

        【讨论】:

          【解决方案6】:

          【讨论】:

            【解决方案7】:

            我觉得我可能遗漏了有关您的问题的一些重要信息,但是这种更简单的解决方案对您不起作用吗?

            只需检查 onChange 事件内部的条件,然后根据需要执行操作。这将比动态地重新添加/删除 eventListeners 容易得多

            document.getElementById("selectbox1").onchange = function () { 
                if (<certain conditions>) {       
                 //hides elements to reduce clutter on a web form ...
                }
                if (<other conditions>) { ... }
            }
            

            【讨论】:

              猜你喜欢
              • 2023-03-10
              • 1970-01-01
              • 1970-01-01
              • 2014-09-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多