enable href-container-script through addEventListener rather than using event script attrs

This commit is contained in:
James Fenn
2023-10-20 23:14:24 -04:00
parent 08d00ba2cc
commit bad27e817f
2 changed files with 23 additions and 13 deletions

View File

@@ -87,5 +87,10 @@ lang ??= "en";
</head> </head>
<body> <body>
<slot /> <slot />
<script>
import { enableHrefContainers } from "utils/href-container-script";
window.addEventListener("load", enableHrefContainers);
</script>
</body> </body>
</html> </html>

View File

@@ -35,7 +35,7 @@ function isNestedElement(e: MouseEvent) {
return false; return false;
} }
globalThis.handleHrefContainerMouseDown = (e: MouseEvent) => { const handleHrefContainerMouseDown = (e: MouseEvent) => {
const isMiddleClick = e.button === 1; const isMiddleClick = e.button === 1;
if (!isMiddleClick) return; if (!isMiddleClick) return;
if (e.defaultPrevented) return; if (e.defaultPrevented) return;
@@ -44,17 +44,17 @@ globalThis.handleHrefContainerMouseDown = (e: MouseEvent) => {
}; };
// implement the AuxClick event using MouseUp (only on browsers that don't support auxclick; i.e. safari) // implement the AuxClick event using MouseUp (only on browsers that don't support auxclick; i.e. safari)
globalThis.handleHrefContainerMouseUp = (e: MouseEvent) => { const handleHrefContainerMouseUp = (e: MouseEvent) => {
// if auxclick is supported, do nothing // if auxclick is supported, do nothing
if ("onauxclick" in e.currentTarget) return; if ("onauxclick" in e.currentTarget) return;
// otherwise, pass mouseup events to auxclick // otherwise, pass mouseup events to auxclick
globalThis.handleHrefContainerAuxClick(e); handleHrefContainerAuxClick(e);
}; };
// Handle middle click button - should open a new tab (cannot be detected via "click" event) // Handle middle click button - should open a new tab (cannot be detected via "click" event)
// - prefer the "auxclick" event for this, since it ensures that mousedown/mouseup both occur within the same element // - prefer the "auxclick" event for this, since it ensures that mousedown/mouseup both occur within the same element
// otherwise, using "mouseup" would activate on mouseup even when dragging between elements, which should not trigger a click // otherwise, using "mouseup" would activate on mouseup even when dragging between elements, which should not trigger a click
globalThis.handleHrefContainerAuxClick = (e: MouseEvent) => { const handleHrefContainerAuxClick = (e: MouseEvent) => {
const href = (e.currentTarget as HTMLElement).dataset.href; const href = (e.currentTarget as HTMLElement).dataset.href;
// only handle middle click events // only handle middle click events
@@ -68,7 +68,7 @@ globalThis.handleHrefContainerAuxClick = (e: MouseEvent) => {
return false; return false;
}; };
globalThis.handleHrefContainerClick = (e: MouseEvent) => { const handleHrefContainerClick = (e: MouseEvent) => {
const href = (e.currentTarget as HTMLElement).dataset.href; const href = (e.currentTarget as HTMLElement).dataset.href;
if (e.defaultPrevented) return; if (e.defaultPrevented) return;
@@ -98,6 +98,15 @@ globalThis.handleHrefContainerClick = (e: MouseEvent) => {
window.location.href = href; window.location.href = href;
}; };
export function enableHrefContainers() {
document.querySelectorAll<HTMLElement>("[data-href]").forEach((el) => {
el.addEventListener("mousedown", handleHrefContainerMouseDown);
el.addEventListener("mouseup", handleHrefContainerMouseUp);
el.addEventListener("auxclick", handleHrefContainerAuxClick);
el.addEventListener("click", handleHrefContainerClick);
});
}
export function getHrefContainerProps(href: string) { export function getHrefContainerProps(href: string) {
// hack to detect whether the function is in an Astro or Preact environment, // hack to detect whether the function is in an Astro or Preact environment,
// assuming that Preact is only used outside of a node environment // assuming that Preact is only used outside of a node environment
@@ -108,19 +117,15 @@ export function getHrefContainerProps(href: string) {
) { ) {
// if running in NodeJS (Astro), return string props // if running in NodeJS (Astro), return string props
return { return {
onmousedown: "handleHrefContainerMouseDown(event)",
onmouseup: "handleHrefContainerMouseUp(event)",
onauxclick: "handleHrefContainerAuxClick(event)",
onclick: "handleHrefContainerClick(event)",
"data-href": href, "data-href": href,
}; };
} else { } else {
// otherwise, need to return client-side functions // otherwise, need to return client-side functions
return { return {
onMouseDown: globalThis.handleHrefContainerMouseDown, onMouseDown: handleHrefContainerMouseDown,
onMouseUp: globalThis.handleHrefContainerMouseUp, onMouseUp: handleHrefContainerMouseUp,
onAuxClick: globalThis.handleHrefContainerAuxClick, onAuxClick: handleHrefContainerAuxClick,
onClick: globalThis.handleHrefContainerClick, onClick: handleHrefContainerClick,
"data-href": href, "data-href": href,
}; };
} }