Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Ошибка работы скрипта (https://javascript.ru/forum/dom-window/75020-oshibka-raboty-skripta.html)

DVV 26.08.2018 16:55

Ошибка работы скрипта
 
Скрипт отправки формы на сервер через Ajax должен выводить три картинки в зависимости от ситуации: ожидание ответа сервера, успешная отправка, сбой. Однако и на локальном сервере и на хостинге при отправке формы он выдает все время только одну картинку, первую (ожидание ответа). При этом, если картинки заменить текстовыми сообщениями, то все работает нормально и после отправки формы появляется сообщение об успешной операции.

let message = new Object();


let form = document.getElementsByClassName('main-form')[0],
	input = form.getElementsByTagName('input'),
	statusMessage = document.createElement('div');

	form.addEventListener('submit', function(event) {
		event.preventDefault();
		form.appendChild(statusMessage);

		// AJAX
		let request = new XMLHttpRequest();
			request.open("POST", 'server.php')
			request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

		let formData = new FormData(form);
			request.send(formData);

		request.onreadystatechange = function() {
			if (request.readyState < 4) {
				//Добавляем картинку при ожидании отправки формы
				statusMessage.classList.add('form-awaiting');
			} else if (request.readyState === 4) {
				if (request.status == 200 && request.status < 300) {
					//Добавляем картинку при удачной отправке формы
					statusMessage.classList.add('form-success');				
				}
				else {
				//Добавляем картинку при неудачной отправке формы
				statusMessage.classList.add('form-failure');
				}
			}
		};
		//Очистка инпутов
		for (let i = 0; i < input.length; i++) {
			input[i].value = '';
		}
	});

//Оправка данных с формы в разделе "Контакты"
let contactForm = document.getElementById('form'),
	contactFormInput = contactForm.getElementsByTagName('input');

	contactForm.addEventListener('submit', function(event) {
		event.preventDefault();
		contactForm.appendChild(statusMessage);

	// AJAX
	let request = new XMLHttpRequest();
			request.open("POST", 'server.php')
			request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

	let contactFormData = new FormData(contactForm);
		request.send(contactForm);	

		request.onreadystatechange = function() {
			if (request.readyState < 4) {
			//Добавляем картинку при ожидании отправки формы
				statusMessage.classList.add('form-awaiting__contact-form');
			} else if (request.readyState === 4) {
				if (request.status == 200 && request.status < 300) {
					//Добавляем картинку при удачной отправке формы
					statusMessage.classList.add('form-success__contact-form');	
				}
				else {
				//Добавляем картинку при неудачной отправке формы
				statusMessage.classList.add('form-failure__contact-form');
				}
			}
		};
		//Очистка инпутов
		for (let i = 0; i < contactFormInput.length; i++) {
			contactFormInput[i].value = '';
		}
	});

Aetae 26.08.2018 17:12

DVV, поменяй в css порядок следования классов form-[x]__contact-form :)

Ну или добавь при readyState === 4:
statusMessage.classList.remove('form-awaiting__contact-form');

DVV 26.08.2018 17:49

Не помогло:cray:

Dilettante_Pro 27.08.2018 12:05

В режиме симуляции запроса все работает...
<style>
.form-awaiting {
   background-image: url(http://javascript.ru/cat/list/project.jpg);
}
.form-success {
   background-image: url(http://javascript.ru/cat/list/donkey.gif);
}
.form-failure {
   background-image: url(http://javascript.ru/cat/list/js.gif);
}
</style>
<div class="main-form">
   <input type="text">
</div>
<script>
let form = document.querySelector('.main-form'),
	request = form.querySelector('input'),
	statusMessage = document.createElement('div'),
         i = 0;
         statusMessage.style="width:50px;height:50px;";
         form.appendChild(statusMessage);


		request.onchange = function() {
                         var classList = statusMessage.classList;
                         while (classList.length > 0) {
                              classList.remove(classList.item(0));
                         }
			if (request.value == "1") {
			//Добавляем картинку при ожидании отправки формы
				statusMessage.classList.add('form-awaiting');
			} else if (request.value == "2") {
				
					//Добавляем картинку при удачной отправке формы
					statusMessage.classList.add('form-success');	
				}
				else {
				//Добавляем картинку при неудачной отправке формы
				statusMessage.classList.add('form-failure');
				
			}
		};
function send(){
   setTimeout(function(){
      i = Math.round(Math.random() * 2) + 1;

          request.value = i;
          var event = new Event('change');
          request.dispatchEvent(event);
          send();

   },2000)
}
send();
</script>


Непринципиальный момент, но у вас лишнее условие
if (request.status == 200 && request.status < 300)

Уж если равно 200, то что еще нужно?

Aetae 27.08.2018 12:34

Dilettante_Pro, onreadystatechange вызывается несколько раз по мере обработки запроса.
DVV, что значит не помогло? Смотрим, сейчас у тебя примерно так:
<style>
#statusMessage{
  width:100px;
  height:100px;
}
.form-success:after {
   content:"form-success"
}
.form-failure:after {
   content:"form-failure"
}
.form-awaiting:after {
   content:"form-awaiting" 
}
</style>


<div id="statusMessage">result: </div>

<script>
let request = new XMLHttpRequest();
request.open("GET", location.href)
request.send(null);
request.onreadystatechange = function() {
  if (request.readyState < 4) {
    //Добавляем картинку при ожидании отправки формы
    statusMessage.classList.add('form-awaiting');
  } else if (request.readyState === 4) {
    if (request.status == 200) {
      statusMessage.classList.add('form-success');               
    }
    else {
      statusMessage.classList.add('form-failure');
    }
  }
};
</script>
Меняешь классы местами, и внезапно работает:
<style>
#statusMessage{
  width:100px;
  height:100px;
}
.form-awaiting:after {
   content:"form-awaiting" 
}
.form-success:after {
   content:"form-success"
}
.form-failure:after {
   content:"form-failure"
}
</style>


<div id="statusMessage">result: </div>

<script>
let request = new XMLHttpRequest();
request.open("GET", location.href)
request.send(null);
request.onreadystatechange = function() {
  if (request.readyState < 4) {
    //Добавляем картинку при ожидании отправки формы
    statusMessage.classList.add('form-awaiting');
  } else if (request.readyState === 4) {
    if (request.status == 200) {
      statusMessage.classList.add('form-success');               
    }
    else {
      statusMessage.classList.add('form-failure');
    }
  }
};
</script>
чудесно, неправда ли?

Или второй предложенный вариант:
<style>
#statusMessage{
  width:100px;
  height:100px;
}
.form-success:after {
   content:"form-success"
}
.form-failure:after {
   content:"form-failure"
}
.form-awaiting:after {
   content:"form-awaiting" 
}
</style>


<div id="statusMessage">result: </div>

<script>
let request = new XMLHttpRequest();
request.open("GET", location.href)
request.send(null);
request.onreadystatechange = function() {
  if (request.readyState < 4) {
    //Добавляем картинку при ожидании отправки формы
    statusMessage.classList.add('form-awaiting');
  } else if (request.readyState === 4) {
    statusMessage.classList.remove('form-awaiting');
    if (request.status == 200) {
      statusMessage.classList.add('form-success');               
    }
    else {
      statusMessage.classList.add('form-failure');
    }
  }
};
</script>

Dilettante_Pro 27.08.2018 13:49

Цитата:

Сообщение от Aetae
onreadystatechange вызывается несколько раз по мере обработки запроса.

У меня в симуляции request.onchange вызывалось 3 раза.

Переделал на бесконечный цикл со случайным параметром и добавил очистку classList.

DVV 27.08.2018 14:10

Супер! Теперь заработало. Я, правда, немного код под себя подправил, но теперь все как часы работает. Спасибо))


Часовой пояс GMT +3, время: 10:51.