如何在动态更改的选择上捕获事件

How to capture events on dynamically changed selects

我有一个脚本可以创建一个 span 来假设一个 select 标签,然后隐藏 select。这允许更简单的 CSS 样式,因为相对于坚定的 select 标签,我可以更容易地设置 span 的样式。有了跨度,我有一个下拉列表,它是 ul 标签,问题是,当我 select 一个“假 select” 上的值并使用 javascript 来制作它隐藏的“真实”值select,onchange不被触发。这样做的目的是帮助 'none-techies' 想要样式化 select 的人,因此我想捕获他们添加到 select 的任何事件,例如 onchangeonfocus,以及 onreset

例如,在下面的代码中,如果您手动 select 选项,则会触发 onchange 事件,而 timeout 函数不会触发事件

    <script>
        var select = document.getElementsByTagName('select')[0];

        function changed() {
            var select = document.getElementsByTagName('select')[0];
            select.value = 'that is optionification fam!';
        }

        setTimeout(changed, 1000);
    </script>
    <select onchange="alert('Object has changed!')">
        <option value="">Select an Option</option>
        <option>this is option</option>
        <option>that is optionification fam!</option>
        <option>these are options</option>
        <option>those a options</option>
        <option>I like options</option>
        <option>I don't like options</option>
        <option>this is an option</option>
    </select>

更新:

来自 W3C:

Events that are generated by the user agent, either as a result of user interaction, or as a direct result of changes to the DOM, are trusted by the user agent with privileges that are not afforded to events generated by script through the DocumentEvent.createEvent("Event") method, modified using the Event.initEvent() method, or dispatched via the EventTarget.dispatchEvent() method. The isTrusted attribute of trusted events has a value of true, while untrusted events have a isTrusted attribute value of false.

Most untrusted events should not trigger default actions, with the exception of click or DOMActivate events. These events trigger the default action of an activation trigger (see Activation triggers and behaviors for more details); these untrusted events have an isTrusted attribute value of false, but still initiate any default actions for backwards compatibility. All other untrusted events must behave as if the Event.preventDefault() method had been called on that event.

由于 isTrusted 也是一个只读属性,任何脚本更改都是 'set-in-stone-untrusted'...因此就是问题所在!

任何人都可以想出一个变通办法,我可以在哪里

注意,起初<script>select没有定义。使用 windowload 事件来定义 select 元素。一种解决方法是使用链接到 window load 事件中定义的 select 变量的 Document.createEvent() with "MouseEvents" as parameter, MouseEvent.initMouseEvent() (deprecated) with "change" as first parameter, true, true, window as next three parameters, EventTarget.dispatchEvent()change 事件分派到 <select> 元素。

另见

<script>
  function changed() {
    var select = document.getElementsByTagName("select")[0];
    select.value = "that is optionification fam!";
    alert("Object has changed!");
  }

  window.onload = function() {
    let evt = document.createEvent("MouseEvents");
    const select = document.getElementsByTagName("select")[0];
    evt.initMouseEvent("change", true, true, window);
    setTimeout(function() {
      select.dispatchEvent(evt);
    }, 3000);
  }
</script>
<select onchange="changed()">
  <option value="">Select an Option</option>
  <option>this is option</option>
  <option>that is optionification fam!</option>
  <option>these are options</option>
  <option>those a options</option>
  <option>I like options</option>
  <option>I don't like options</option>
  <option>this is an option</option>
</select>

使用 chrome 支持的 CustomEvent、firefox 6+、ie9+、opera 11+、safari 5.1+ (533.3); EventTarget.dispatchEvent().

<script>
  function changed() {
    var select = document.getElementsByTagName("select")[0];
    select.value = "that is optionification fam!";
    alert("Object has changed!");
  }

  window.onload = function() {
    let evt = new CustomEvent("change");
    const select = document.getElementsByTagName("select")[0];
    setTimeout(function() {
      select.dispatchEvent(evt);
    }, 3000);
  }
</script>
<select onchange="changed()">
  <option value="">Select an Option</option>
  <option>this is option</option>
  <option>that is optionification fam!</option>
  <option>these are options</option>
  <option>those a options</option>
  <option>I like options</option>
  <option>I don't like options</option>
  <option>this is an option</option>
</select>