웹브라우저에서 새창(팝업창)을 열기 위해서 가장 간단히 사용할 수 있는 방법이 바로 자바스크립트 window 객체의 open() 함수를 사용하는 것을 말합니다.
mutate(`test/`).then((data) => {
window.open(FORM_LINK, '_blank')
}
위 코드를 사용했을 경우 사파리 브라우저에서 테스트 했을 때 팝업이 열리지 않는 현상이 발생하였습니다.
팝업이 열리지 않는 이유는 사파리 브라우저에서 팝업 차단을 막고 있으므로 발생하는 현상이였습니다.
차단이 되는 이유는 대부분의 브라우저는 사용자 인터랙션에 직접적으로 연결되지 않은 window.open() 호출을 차단합니다.
Window: open() method mdn 에서 확인해보면 사파리에서는 click이벤트 발생한지 1000ms이후에 window.open메서드가 호출되면 팝업차단 됩니다. 비동기 로직이 1000ms이내에 완료된다면 window.open메서드가 정상적으로 동작하게 될 것입니다.
즉 mutate()나 then()과 같은 메소드는 비동기 처리 방식을 사용합니다. 이러한 비동기 함수가 실행되는 동안에 window.open() 메서드가 호출되면, 해당 함수의 실행 시간이 브라우저의 window.open 메서드 호출 시간을 초과할 경우 팝업 차단될 수 있습니다.
어떤 비동기 작업 후에 window.open()을 호출하려고 하면 그 사이의 지연 때문에 브라우저가 이를 사용자가 직접 클릭한 것이 아닌 스크립트에 의해 자동으로 생성된 팝업으로 인식하고 차단할 수 있습니다.
export default function App() {
const openNaverSitePromise = () => {
return new Promise((res) => {
window.open("https://www.naver.com", "_blank");
res(true);
});
};
const handleButtonPromise = () => {
openNaverSitePromise().then(() => {
window.open("https://www.naver.com", "_blank");
});
};
return (
<div className="App">
<button onClick={handleButtonPromise}>네이버 바로가기 Promise</button>
</div>
);
}
위 코드에서는 Promise에서 따로 setTimeout이 없기 때문에 해당 팝업이 잘 열리는 것을 확인할 수 있습니다.
const openNaverSiteSetTimeout = () => {
return new Promise((res) => {
setTimeout(() => {
window.open("https://www.naver.com", "_blank");
res(true);
}, 2000); // 여기서 시간을 줍니다.
});
};
const handleButtonClickSettimeOut = () => {
openNaverSiteSetTimeout().then(() => {
window.open("https://www.naver.com", "_blank");
});
};
위 코드에서는 Promise에서 따로 setTimeout을 2000ms를 주었습니다. 아래 영상에서 보시는 것과 같이 해당 팝업이 차단되어 열리지 않는 것을 확인할 수 있습니다.
mdn에서는 window.open()을 사용하는 것은 여러 가지 이유로 지양하라고 나와있습니다.
현대의 브라우저들은 팝업 차단 기능을 제공합니다. 따라서 window.open()으로 생성된 팝업창이 사용자에게 보여지지 않을 수 있습니다.
많은 사용자들이 탭 기능을 제공하는 브라우저를 사용하며, 대부분의 경우 새 창을 열기보다는 새 탭을 열기를 선호합니다.
사용자들은 브라우저 내장 기능이나 확장 프로그램을 통해 링크를 클릭했을 때 새 창에서 열릴지, 같은 창에서 열릴지, 새 탭에서 열릴지, 같은 탭에서 열릴지, 아니면 백그라운드에서 열릴지 등 선택할 수 있습니다. window.open()으로 특정 방식으로 강제로 연다면 이러한 사용자 설정과 습관을 무시하게 되므로 혼란스럽게 할 수 있습니다.
팝업창에는 메뉴 툴바가 없고, 새 탭은 브라우저 윈도우의 사용자 인터페이스를 그대로 활용하므로 인터페이스가 일관되게 유지됩니다. 따라서 많은 사용자들이 탭 방식의 브라우징을 선호합니다.
따라서 가능한 경우에는 태그와 같은 HTML 요소를 사용하여 링크를 제공하고, 필요한 경우에만 신중하게 window.open() 메서드를 사용하는 것이 좋을 거 같습니다.
[참고]