Mit dem for(;;) habe ich keine Probleme. Gewaltige Probleme bekommt dein Browser aber mit dem on im on im on. Jeder Change auf frm_appointmentstart registriert einen weiteren change-Handler auf frm_appointmentend. Nach 20 Changes auf start hast du 20 Change-Handler auf end. Und jeder von denen registriert einen weiteren Change-Handler auf pausestart. Wenn Du also 20 Handler auf end hast und 20 mal das change-Event auf end ausgelöst wurde, fliegen da 400 change-Handler auf pausestart herum.
Diese Registrierungen müssten wohl eher nacheinander als ineinander erfolgen.
Sodann würde ich Dir empfehlen, deinen Code gründlich aufzuräumen.
- Erzeuge die Zugriffsvariablen für die frm_-Elemente direkt in der ready-Function statt in den on Handlern. Ich habe mich zwar vor einiger Zeit dagegen ausgesprochen, aber solange keiner am DOM rumfummelt und diese Elemente rausschmeißt, wird das funktionieren.
- index und length solltest du dagegen in den on-Handlern belassen. Und du kannst die anderen Zugriffsvariablen dafür benutzen, also z.B. var index = start.selectedIndex;
- Statt das disabled-Attribut mit $('#id1').attr('disabled', 'disabled') zu setzen kannst Du, wenn Du ohnehin eine Referenz auf das Element mit der ID in einer Variablen hast, direkt auf das DOM Property zugreifen und frm_id1.disabled = trueschreiben. Analoges gilt für Property-Modifikationen mit .prop():p_start.selectedIndex = 0ist doch viel schöner als dieser jQuery-Klumpen.
- Lagere die Schleife, die die Options disabled, in eine eigene Funktion aus. Die Funktionsdeklaration kannst Du an den Anfang oder das Ende deines Ready-Handlers stellen. Nur nicht in die change-Handler hinein (sonst musst Du sie dreimal schreiben und das ist nicht Sinn der Sache).
D.h. skelettartig sähe dein Ready-Handler dann so aus:
// kurzform von $(document).ready(function(){ ... })
$(function() {
   function enableOptions(element, enable, from, to) {
      for (var i=from; i<=to; i++) {
         element.options[i].disabled = enable;
      } 
   }
   var start=document.getElementById("frm_appointmentstart"),
   var end = ..., p_start = ..., p_end = ...;
   end.disabled = true;
   p_start.disabled = true;
   p_end.disabled = true;
   // jQuery versteht auch DOM Referenzen.
   // Vermeidet die Wiederholung der ID und ist einen Tick schneller.
   $(start).on("change", function() {
      var index = start.selectedIndex;
      var length = start.length;
      end.disabled = false;
      $('select').not(this).prop('selectedIndex',0);   // hm, der muss vermutlich bleiben
      enableOptions(end, false, 1, index);
      enableOptions(p_start, false, 1, index);
   });
   $(end).on("change", function() {
      var index = ...
      p_start.disabled = false;
      p_start.selectedIndex = 0;
      disableOptions(p_start, false, index, length-1);
      disableOptions(p_end, false, index, length-1);
   });
   $(p_start).on("change", function() {
      // analog
   });
   $("#add-appointment-type-reset-btn").on('click', function() {
      // start, end, p_start, p_end sind schon da
      // length hier ermitteln
      // disable und selectedIndex=0 
      $('input').val('');  // nicht each(function(){...})
      $('select').prop('selectedIndex', 0); // nicht each(function(){...})
// oder $('select').each(function() { this.selectedIndex = 0; });
// oder $('select').each((i,x) => x.selectedIndex = 0);
      // jetzt noch 4x enableOptions(xxx, false, 1, length-1) aufrufen
   });
});
Hinweis zu dem each((i,x)=>x.selectedIndex=0) - das ist eine Arrow-Function, eine Kurzschreibweise für function(i,x) { x.selectedIndex=0; }.
Gruß Rolf
 nicht angemeldet
 nicht angemeldet Rolf b
 Rolf b Matthias Apsel
 Matthias Apsel Der Martin
 Der Martin