Невозможно закрыть дочернее окно внутри обратного вызова setTimeout в JavaScript

Я столкнулся с проблемой закрытия дочернего окна внутри обратного вызова setTimeout в JavaScript. Несмотря на успешное открытие дочернего окна с помощью window.open, я не могу получить доступ к переменной newChild в функции обратного вызова setTimeout.

Вот упрощенная версия кода, с которым я работаю:

import { useState } from "react";

const useButton = () => {
  const openChildWindow = () => {
    const newChild = window.open(
      "https://www.google.com/",
      "",
      "toolbar=0,status=0,width=626,height=436"
    );

    setTimeout(() => {
      newChild.close();
    }, 3000);
  };

  return {
    openChildWindow,
  };
};

Я озадачен тем, почему переменная newChild недоступна в обратном вызове setTimeout. Может ли кто-нибудь просветить меня, почему это происходит, и предложить решение этой проблемы?

Спасибо заранее за вашу помощь!

Я подозреваю, что вы можете получить к нему доступ. Какая ошибка в вашей консоли разработчика? Попробуйте что-нибудь менее безопасное, чем google.com, и вы обнаружите, что, вероятно, все в порядке.

A Haworth 06.06.2024 19:07
newChild.close(); выходит за пределы функции setTImeout, поэтому внутри нее не существует. то есть openChildWindow запускается и заканчивается до запуска setTimeout
Mark Schultheiss 06.06.2024 20:15

@MarkSchultheiss, это не мой опыт. Новое окно все еще существует и его можно закрыть, если оно готово к закрытию (чего нет у google.com, но могут быть и другие веб-сайты).

A Haworth 06.06.2024 20:29

@AHaworth Достаточно справедливо; Я тестировал фрагмент и забыл, что этот сайт блокирует их (значение null, если вы console.info(newChild) в функции перед закрытием; это также может иметь место, например, если сайт заблокирован внутри брандмауэра.

Mark Schultheiss 06.06.2024 20:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
52
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

С этим может возникнуть несколько проблем.

Однако наиболее распространенной проблемой является то, что новое открытое окно имеет другое происхождение.

Window.open после успешного открытия нового окна возвращает прокси-объект для нового окна. Мы можем использовать этот объект для управления новым окном, только если соблюдена политика одинакового происхождения (оба окна находятся в одном и том же источнике).

Я попробовал и протестировал код на странице stackoverflow. Сделанные шаги:

  1. Открыть Chrome
  2. Перейдите на stackoverflow.com.
  3. Откройте инструменты разработки и в раздел консоли добавьте код ниже:

const newChild = window.open(
      "https://stackoverflow.com/",
      "",
      "toolbar=0,status=0,width=626,height=436"
    );
    console.info("newchild value : ", newChild);
    setTimeout(() => {
        console.info(newChild.close);
      newChild.close();
    }, 3000);
  1. Откроется новое окно. и через 3 секунды он автоматически закроется

Я попытался воспроизвести описанную выше проблему и узнал, что вы вернули openChildWindow внутри компонента useButton. По сути, нет необходимости в оконном компоненте. поскольку window.open() откроет интерфейс браузера, я обновил приведенный ниже код, который вы можете скопировать и попробовать в codeSandbox.

function App() {
  const UseButton = () => {
    const newChild = window.open(
      "https://stackoverflow.com/",
      "",
      "toolbar=0,status=0,width=626,height=436",
    );

    if (newChild) {
      setTimeout(() => {
        if (!newChild.closed) {
          newChild.close();
        }
      }, 3000);
    } else {
      console.info("Failed to open child window. Pop-up blocked?");
    }
  };

  return (
    <>
      <button onClick = {UseButton}>UseButton</button>
    </>
  );
}

export default App;
Ответ принят как подходящий

Ваш код работает нормально и так. Проблема, которую вы видите, заключается в том, что https://www.google.com/ не позволяет окну закрыться.

Попробуйте свой код с другими URL-адресами и посмотрите. Два, которые я тестировал и которые работали нормально:

  1. https://stackoverflow.com/
  2. https://www.jigsawplanet.com/

Другие вопросы по теме