填写表单的脚本执行速度比onchange()显示表单选项的速度快

Script to fill out form executes faster than onchange() can show options for form

本文关键字:表单 显示 选项 onchange 速度快 速度 脚本 执行      更新时间:2023-09-26

我正在使用Javascript bookmarklet自动填写页面上的表单。给出的一些选项是下拉选择,根据使用onchange((选择的内容显示不同的选项。我有类似的代码:

/* Gets first drop down and sets value to first in list */
var dropDown1 = document.getElementById("dropDown1Name");
dropDown1.value = "option1InDropDown";
dropDown1.onchange();
/* Sets value of second drop down to option that is available when first option in first drop down is selected */
var dropDown2 = document.getElementById("dropDown2Name");
dropDown2.value = "optionRevealedByDropDown1Change";

然而,这并不起作用,因为当我将onchange((设置为值时,它不会填充第二个下拉列表。脚本执行完毕时,dropDown2中没有设置任何值。我尝试了几种方法让代码"等待",但一直未能找到正确的解决方案。欢迎提出任何建议。

将第一个<select>input事件绑定,该事件与change类似,只是它会立即触发。为了将第一个<select>的值与第二个<select>的选项和值同步,请在事件处理程序中使用selectedIndex属性。

摘录

var s1 = document.getElementById('s1');
var s2 = document.getElementById('s2');
s1.addEventListener('input', function(e) {
  var idx = this.selectedIndex;
  var data = idx.value;
  s2.selectedIndex = idx;
}, false);
label {
  margin-left: 6ex;
}
<fieldset>
  <legend>Binding Input Event</legend>
  <select id='s1'>
    <option>---</option>
    <option value='1'>1</option>
    <option value='2'>2</option>
    <option value='3'>3</option>
  </select>
  <select id='s2'>
    <option>---</option>
    <option value='A'>A</option>
    <option value='B'>B</option>
    <option value='C'>C</option>
  </select>

</fieldset>

正如评论中已经指出的,问题的一部分是change事件的错误触发。问题的另一部分可能是,第二个下拉列表的选项可能只有在接收到某个异步操作(例如使用XMLHttpRequest(的结果后才会填充。在这种情况下,即使change事件被正确触发,您的代码仍然需要等待填充下拉列表,然后再设置其值。如果下拉列表中填充了值(例如使用setIntervalsetTimeout(,则一种方法可能基于定期检查。更优雅的方法可以使用MutationObserver来等待用值填充下拉列表。看看这个片段:

var sel1 = document.querySelector('#sel'),
  sel2 = document.querySelector('#sel2');
// Onchange code
sel1.addEventListener('change', function() {
  sel2.disabled = false;
  // emulate async request for dropdown options
  setTimeout(function populateSecondSelect() {
    ['', 'dynamic1', 'dynamic2'].forEach(function(val) {
      var opt = document.createElement('option');
      opt.setAttribute('value', val);
      opt.textContent = val || '-';
      sel2.appendChild(opt);
    });
  }, 2000);
});
// Code to trigger events (based on http://stackoverflow.com/a/2490876/2671392)
function triggerEvent(type, element) {
  var event; // The custom event that will be created
  if (!!window.Event) {
    event = new Event(type);
  } else if (document.createEvent) {
    event = document.createEvent("HTMLEvents");
    event.initEvent(type, true, true);
  } else {
    event = document.createEventObject();
    event.eventType = type;
  }
  event.eventName = type;
  if (document.createEvent) {
    element.dispatchEvent(event);
  } else {
    element.fireEvent("on" + event.eventType, event);
  }
}
document.querySelector('#btn').addEventListener('click', function() {
  sel1.value = sel1.value === '1' ? '2' : '1';
  // trigger change event
  triggerEvent('change', sel1);
  // set MutationObserver for second dropdown
  var observer = new MutationObserver(function(mutations) {
    sel2.value = 'dynamic2';
    observer.disconnect();
  });
  // only observe changes in the list of children
  var observerConfig = {
    childList: true
  };
  observer.observe(sel2, observerConfig);
});
<div>
  <input type="button" id="btn" value="Select values" />
  <select id="sel">
    <option value="" selected>-</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
  </select>
  <select id="sel2" disabled>
  </select>
</div>

但请注意,MutationObserver在较旧的浏览器中不可用。