отключить обновление страницы при нажатии по кнопке, но не менять свойства самой кнопки

у меня есть простая кнопка, которая по нажатию должна отправлять форму, не обновляя страницу и открывать другое окно. но как только я ставлю "type=button", он игнорирует обязательные поля и сразу выполняет JS код по нажатию и не важно, заполнены поля или нет.

можно ли как то сделать, чтобы кнопка срабатывала только в том случае, когда все поля заполнены, но при этом не обновить страницу?

ссылка на пример CodePen: https://codepen.io/Joker_03/pen/KKmPVma

let but = document.getElementById('1');
but.onclick = function () {
  document.querySelector('.one-overflow').style.display = "none";
  document.querySelector('.two-overflow').style.display = "block";
}
.one-overflow, .two-overflow {
  width: 100%;
  height: 100%;
}

.one-in, .two-in {
  display: flex;
  width: 250px;
  margin: 10px auto;
}

.two-overflow {
  display: none;
}

.one-in input {
  margin-bottom: 10px;
}

.two-in {
  text-align: center;
  background: red;
   align-items: center;
}

p {
  margin: 0 auto;
  height: 100px;
}
<div class="one-overflow">
  <div class="one-in">
    <form action="get">
      <input type="text" name="" id="name" placeholder="ваше имя" required>             
      <input type="tel" name="" id="tel" placeholder="номер телефона" required>
      <button id="1">отправить</button>
    </form>
  </div>
</div>

<div class="two-overflow">
  <div class="two-in">
    <p>спасибо за заказ</p>
  </div>
</div>


Ответы (2 шт):

Автор решения: yar85

как только я ставлю "type=button", он игнорирует обязательные поля и сразу выполняет JS код по нажатию и не важно, заполнены поля или нет.

Так и должно быть, ведь ты слушаешь событие click кнопки (которому в принципе безралична форма): атрибуты валидации учитываются только при попытке отправки формы - следовательно, надо прослушивать событие отправки формы (submit), а не событие клика. Для того чтобы не позволить браузеру отправить форму при сабмите, следует в обработчике вызвать метод события preventDefault.

const form = document.getElementById('foo');
form.addEventListener('submit', evt => {
  evt.preventDefault();                    // предотвращение отправки формы браузером
  document.querySelector('.one-overflow').style.display = 'none';
  const query = ['name', 'tel'].map(       // формирование строки запроса (query string)
    fld => `${fld}=${encodeURIComponent(form[fld].value)}`
  ).join('&');
  fetch(`${evt.target.action}?${query}`, { // отправка запроса (request'а)
    method: form.method,
  }).then(() => {                          // обработка завершения отправки (безусловная, результат запроса не учитывается)
    document.querySelector('.two-overflow').style.display = 'block';
  })
});
.one-overflow, .two-overflow { width: 100%; height: 100%; }
.one-in, .two-in { display: flex; width: 250px; margin: 10px auto; }
.two-overflow { display: none; }
.one-in input { margin-bottom: 10px; }
.two-in { text-align: center; background: red; align-items: center; }
p { margin: 0 auto; height: 100px; }
<div class="one-overflow">
  <div class="one-in">
    <form id="foo" action="https://httpbin.org/get">
      <input name="name" placeholder="ваше имя" required>             
      <input type="tel" name="tel" placeholder="номер телефона" required>
      <button>отправить</button>
    </form>
  </div>
</div>

<div class="two-overflow">
  <div class="two-in">
    <p>спасибо за заказ</p>
  </div>
</div>

→ Ссылка
Автор решения: Pilaton

required не дает отправить форму с пустыми полями, поэтому с отправкой формы всё норм.
Проблему срабатывания JS же, решить можно простой проверкой value у полей.

let but = document.getElementById('1');

but.onclick = function() {

  let inputs = Array.from(document.querySelectorAll('input'));

  let inputsValueTrue = inputs.every((input) => input.value)

  if (inputsValueTrue) {
    document.querySelector('.one-overflow').style.display = "none";
    document.querySelector('.two-overflow').style.display = "block";
  }

}
.one-overflow,
.two-overflow {
  width: 100%;
  height: 100%;
}

.one-in,
.two-in {
  display: flex;
  width: 250px;
  margin: 10px auto;
}

.two-overflow {
  display: none;
}

.one-in input {
  margin-bottom: 10px;
}

.two-in {
  text-align: center;
  background: red;
  align-items: center;
}

p {
  margin: 0 auto;
  height: 100px;
}
<div class="one-overflow">
  <div class="one-in">
    <form action="get">
      <input type="text" name="" id="name" placeholder="ваше имя" required>
      <input type="tel" name="" id="tel" placeholder="номер телефона" required>
      <button type="submit" id="1">отправить</button>
    </form>
  </div>
</div>

<div class="two-overflow">
  <div class="two-in">
    <p>спасибо за заказ</p>
  </div>
</div>

→ Ссылка