Как получить текущий монитор окна в js

Я сохраняю положение окна, когда оно закрыто:

const savePositionToStorage = (position) => {
    localStorage.setItem('windowPosition', position);
    console.info('Position saved:', position);
}

const getPositionFromStorage = () => {
    const position = localStorage.getItem('windowPosition');
    return position ? position :  "top=0,left=0,width=800,height=1000";
}

и откройте такое окно:

const handleExpandClick = (id) => {
    const windowFeatures = getPositionFromStorage();

    const pdfWindow = window.open(
        `http://127.0.0.1:8000/transactions/matching_evidence/${id}#toolbar=0,view=FitH`,
        "pdf",
        windowFeatures,
    );

    pdfWindow.onload = () => {
        pdfWindow.onbeforeunload = () => {
            savePositionToStorage(`top=${pdfWindow.screenY},left=${pdfWindow.screenX},height=${pdfWindow.innerHeight},width=${pdfWindow.innerWidth}`)
        }
    }

}

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

Есть ли способ заархивировать то, что я хочу?

Chrome будет браузером, который используют пользователи.

Ваш код работает нормально, если предположить, что веб-сайт поддерживает политику CORS. Вы уверены, что включили это?

Jake 26.07.2024 06:57

@Джейк, это тоже сохраняет положение второго монитора? Как я могу проверить, разрешена ли политика Cors?

user3793935 26.07.2024 07:00

После const pdfWindow = window.open(...) напишите pdfWindow.window.onload. Если выдает ошибку, значит, политика cors не разрешена.

Jake 26.07.2024 07:02

const pdfWindow = window.open( http://127.0.0.1:8000/transactions/matching_evidence/${id}#t‌​oolbar=0,view=FitH, "pdf", windowFeatures, ); pdfWindow.window.onload Вот так? Там нет ошибки

user3793935 26.07.2024 07:04

После const pdfWindow... сделайте window.pdfwindow = pdfwindow. После запуска handleExpandClick() попробуйте x.onload. Если вы видите An attempt was made to break through the security policy of the user agent., значит, CORS не включен. Извините, ранее было неправильно.

Jake 26.07.2024 07:12

Я сделал это так: window.pdfwindow = pdfWindow window.pdfwindow.onload = () => { console.info("tes"); } Журнал распечатывается, ошибок нет. Спасибо, что нашли время попытаться помочь ;)

user3793935 26.07.2024 07:18

Предоставляет ли ScreenDetails достаточно информации? Экспериментальная функция Chrome/WebKit доступна только в безопасном контексте, поэтому ее использование может быть затруднено.

l3l_aze 26.07.2024 07:45

@l3l_aze выдает следующую ошибку: DOMException: для запроса разрешения требуется временная активация. Но я не могу найти, что мне нужно сделать, чтобы предоставить разрешения.

user3793935 26.07.2024 08:29

Это означает, что действие, вызывающее запрос разрешения, должно выполняться посредством взаимодействия с пользователем и не может быть автоматизировано. Временная активация на MDN.

l3l_aze 26.07.2024 09:20
Поведение ключевого слова "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) для оценки ваших знаний,...
2
9
90
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я сам задавался этим вопросом. К сожалению, не существует прямого способа надежно определить монитор, на котором в последний раз закрывалось окно, с помощью JavaScript. Браузеры не предоставляют API для получения информации монитора для окна.

Вот почему это сложно:

  • Проблемы безопасности: доступ к информации о мониторах может быть использован в злонамеренных целях, поэтому браузеры ограничивают этот доступ.
  • Межплатформенные проблемы. Каждая операционная система и браузер по-разному обрабатывают настройки нескольких мониторов. Решение, которое работает в Chrome в Windows, может не работать в macOS или Linux.

Обходные пути

Вот несколько альтернативных подходов, которые следует рассмотреть:

1. Ручная регулировка:

  • Вы можете предложить пользователю настроить положение окна вручную при первом его открытии на новом мониторе.
  • Предоставьте элементы пользовательского интерфейса во всплывающем окне, чтобы пользователь мог вручную перемещать положение и размер окна, а также сохранять эти изменения.

2. (Частичное) Решение с использованием screen.availHeight/Width:

  • Вы можете использовать screen.availHeight и screen.availWidth, чтобы получить доступное пространство на экране, что может дать вам представление о разрешении монитора.
  • Однако это не скажет вам точный монитор, и пользователю может потребоваться настроить окно, если доступное пространство экрана меняется на разных мониторах.

Пример (частичное решение):

const handleExpandClick = (id) => {
  const storedPosition = getPositionFromStorage();
  const availableWidth = screen.availWidth;
  const availableHeight = screen.availHeight;

  // If the stored position is outside the current monitor's bounds, 
  // reposition the window closer to the center.
  let updatedPosition = storedPosition;
  if (storedPosition.left > availableWidth || storedPosition.top > availableHeight) {
    updatedPosition = `top=${availableHeight / 2},left=${availableWidth / 2},width=800,height=600`;
  }

  const pdfWindow = window.open(
    `http://127.0.0.1:8000/transactions/matching_evidence/${id}#toolbar=0,view=FitH`,
    "pdf",
    updatedPosition
  );

  // ... rest of your code
};

3. Пользовательский ввод:

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

4. Сторонние библиотеки:

  • Изучите сторонние библиотеки, которые могут предлагать возможности обнаружения монитора. Будьте осторожны с их последствиями для надежности и безопасности.

Заключение

Хотя идеального решения для автоматического определения монитора не существует, эти обходные пути могут сделать работу более удобной для пользователя.

Привет, по какой-то причине код у меня теперь работает после того, как я удалил локальное хранилище. К сожалению, я не могу объяснить, почему и как ;(

user3793935 26.07.2024 09:23

Мой ответ помог?

teplostanski 26.07.2024 09:26

Да, чтобы лучше понять причины безопасности, я проголосовал за вас. Но я не знаю, что мне отметить как ответ, так как проблема скорее всего была в локальном хранилище, я не уверен

user3793935 26.07.2024 09:32

Я нашел решение проблемы. Просто проверьте мой ответ

user3793935 26.07.2024 11:03
Ответ принят как подходящий

По какой-то причине сейчас это работает. Я удалил локальное хранилище, и когда попробовал еще раз, все сработало. Я особо ничего не менял, кроме того, что сохраняю данные в виде строкового json:

const savePositionToStorage = (position) => {
    localStorage.setItem('windowPosition', JSON.stringify(position));
    console.info('Position saved:', position);
}

const getPositionFromStorage = () => {
    const position = JSON.parse(localStorage.getItem('windowPosition'));
    return position ? position : { top: 0, left: 0, width: 800, height: 1000 };
}


// #region Click Events
const handleExpandClick = async (id) => {
    const storedPosition = getPositionFromStorage();
    const windowFeatures = `top=${storedPosition.top},left=${storedPosition.left},height=${storedPosition.height},width=${storedPosition.width}`;

    const pdfWindow = window.open(
        `http://127.0.0.1:8000/transactions/matching_evidence/${id}#toolbar=0,view=FitH`,
        "pdf",
        windowFeatures,
    );


    pdfWindow.onload = () => {
        pdfWindow.onbeforeunload = () => {
            savePositionToStorage({ "top": pdfWindow.screenY, "left": pdfWindow.screenX, "height": pdfWindow.innerHeight, "width": pdfWindow.innerWidth })
        }
    }
}
// #endregion

Я попрошу своих коллег опробовать этот код позже и сообщу, работает ли он там. Очень странно

Редактировать: Хорошо, проблема, похоже, в управлении окнами. Это должно быть установлено, чтобы разрешить. Я пока не знаю, как получить разрешения

Редактировать: Я нашел проблему сейчас. Мне просто нужно было дождаться обещания и продолжить (полный код):
Имейте в виду, что это не будет работать с FireFox. https://developer.mozilla.org/en-US/docs/Web/API/Window/getScreenDetails

// #windowLocation
const savePositionToStorage = (position) => {
    localStorage.setItem('windowPosition', JSON.stringify(position));
}

const getPositionFromStorage = () => {
    const position = JSON.parse(localStorage.getItem('windowPosition'));
    return position ? position : { top: 0, left: 0, width: 800, height: 1000 };
}

const loadWindow = (windowFeatures, id) => {
    const pdfWindow = window.open(
        `http://127.0.0.1:8000/transactions/matching_evidence/${id}#toolbar=0,view=FitH`,
        "pdf",
        windowFeatures,
    );

    pdfWindow.onload = () => {
        pdfWindow.onbeforeunload = () => {
            savePositionToStorage({ "top": pdfWindow.screenY, "left": pdfWindow.screenX, "height": pdfWindow.innerHeight, "width": pdfWindow.innerWidth })
        }
    }
}
// #endregion


// #region Click Events
const handleExpandClick = (id) => {
    const storedPosition = getPositionFromStorage();
    const windowFeatures = `top=${storedPosition.top},left=${storedPosition.left},height=${storedPosition.height},width=${storedPosition.width}`;

    // if there are multiple screens, ask the user for window Management permissions.
    // supported browser: https://developer.mozilla.org/en-US/docs/Web/API/Window/getScreenDetails
    if (window.screen.isExtended) {
        window.getScreenDetails().then(() => {
            loadWindow(windowFeatures, id);
        });
    } else {
        loadWindow(windowFeatures, id);
    }
}
// #endregion

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