Check the page for anchor links that point to external websites and then display a “warning” modal that asks the user if they are sure they wish to proceed.
The modal will only display if the anchor link’s href
value both:
- contains ‘http’
- and is not equal to the
window.location.host
value.
JavaScript
const externalLinks = () => {
// set current website as a string, ex: 'www.alxwntr.com'
const currentDomain = window.location.host
// modal elements
const externalLinkModal = document.querySelector('.external-link-modal')
const externalLinkCancel = document.querySelector('.external-link-cancel')
const externalLinkProceed = document.querySelector('.external-link-proceed')
if (externalLinkModal && externalLinkCancel && externalLinkProceed) {
document.querySelectorAll('#site-content a').forEach((element) => {
element.addEventListener('click', (event) => {
// get the href value of the link that the user has clicked
let linkHref = element.getAttribute('href')
// if the link's href value contains 'http' (absolute URL) and
// if the link's href value is not the 'currentDomain'
if (linkHref.includes('http') && !linkHref.includes(currentDomain)) {
event.preventDefault()
externalLinkProceed.setAttribute('href', linkHref) // set the "Proceed" link to the URL
externalLinkModal.showModal()
externalLinkCancel.addEventListener('click', () => {
externalLinkModal.close()
})
externalLinkProceed.addEventListener('click', () => {
externalLinkModal.close()
})
}
})
})
}
}
externalLinks()
HTML
<main id="site-content">
<p>This is a <a href="#">internal relative link</a> and this is an <a href="https://www.google.com/" target="_blank">external absolute link</a>.</p>
</main>
<dialog class="external-link-modal">
<div class="modal-heading">
<h2>You are now leaving the website.</h2>
</div>
<div class="modal-content">
<p>Are you sure that you wish to proceed?</p>
</div>
<div class="modal-interactions">
<button class="external-link-cancel">Cancel</button>
<a href="#" class="external-link-proceed" target="_blank">Proceed</button>
</div>
</dialog>
CSS
body {
font-family: 'Josefin Sans', sans-serif;
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
}
main {
width: min(100%, 700px);
margin-inline: auto;
padding: 1em;
text-align: center;
p {
margin: 0;
}
}
a {
color: blue;
&:hover,
&:focus {
color: rebeccapurple;
text-decoration: none;
}
}
// **************************************************
// External Link Modal
// **************************************************
.external-link-modal {
max-width: 60ch;
padding: 0;
border: 0;
border-radius: 1em;
box-shadow: 0 0 1em rgba(0, 0, 0, 0.5);
@media (max-width: 500px) {
max-width: 90vw;
}
&::backdrop {
background-color: rgba(0, 0, 0, 0.4);
padding-inline: 1em;
}
.modal-heading {
padding: 1.5em 2.5em;
background-color: #30969d;
h2 {
margin: 0;
color: #fff;
font-size: 1.5rem;
line-height: 1.5;
text-align: center;
}
}
.modal-content {
padding: 1.5em;
margin-block: 1.5em;
background-color: #fff;
p {
margin: 0;
text-align: center;
}
}
.modal-interactions {
padding: 1.5em;
background-color: #F4F4F4;
display: flex;
justify-content: center;
gap: 1em;
button,
a {
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
padding: 0.5em 1em 0.3em 1em;
background-color: #30969d;
border: 0;
border-radius: 3px;
color: #fff;
font-family: 'Josefin Sans', sans-serif;
font-size: 1.1rem;
line-height: 1.5;
text-decoration: none;
cursor: pointer;
transition: all 0.3s;
&:hover {
background-color: #163e51;
color: #fff;
}
}
}
}