Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

event.preventDefault() not working when clicks <a> elements #2791

Closed
xuchaoqian opened this issue Oct 23, 2021 · 7 comments
Closed

event.preventDefault() not working when clicks <a> elements #2791

xuchaoqian opened this issue Oct 23, 2021 · 7 comments

Comments

@xuchaoqian
Copy link
Contributor

xuchaoqian commented Oct 23, 2021

Describe the bug

We want to capture all click events on < a > elements, and then open link in new tauri window or custom tab(just like chrome tab), instead of opening link in the default browser.

It works fine in the default browser, but gets unexpected result in tauri windows: event.preventDefault() does NOT work anymore, tauri always open it in the default browser.

To Reproduce

Steps to reproduce the behavior:

Code sample as following(See it online: https://jsfiddle.net/uvrt0ajd/5/):

<a href="http://stackoverflow.com/q/8614438/1366033" 
   onclick="event.preventDefault()" 
   target="_blank">click</a>
<a href="http://stackoverflow.com/q/8614438/1366033" target="_blank" >click2</a>
<a href="http://stackoverflow.com/q/8614438/1366033" target="_blank" >click3</a>
<script>
  const links = document.links;
  for (let i = 0, n = links.length; i < n; i++) {
    links[i].onclick = function (event) {
      event.preventDefault();
      return false;
    };
  }
</script>

Expected behavior

Should NOT open the link in the default browser.

Platform and Versions (required):

Operating System - Mac OS, version 11.6.0 X64

Node.js environment
  Node.js - 14.18.1
  @tauri-apps/cli - 1.0.0-beta.10
  @tauri-apps/api - 1.0.0-beta.8

Global packages
  npm - 6.14.15
  yarn - 1.22.17

Rust environment
  rustc - 1.56.0
  cargo - 1.56.0

App directory structure
/bin
/node_modules
/webpack
/public
/src-tauri
/build
/.git
/.vscode
/src

App
  tauri.rs - 1.0.0-beta.8
  build-type - bundle
  CSP - default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'
  distDir - ../build
  devPath - http://localhost:9091
  framework - React
  bundler - Webpack
@xuchaoqian xuchaoqian changed the title event.preventDefault() not working when click <a> elements event.preventDefault() not working when clicks on <a> elements Oct 23, 2021
@xuchaoqian xuchaoqian changed the title event.preventDefault() not working when clicks on <a> elements event.preventDefault() not working when clicks <a> elements Oct 23, 2021
@amrbashir
Copy link
Member

amrbashir commented Oct 30, 2021

Can you change your snippet to

document.addEventListener('click', (e) => { 
  if (e.target.matches('a') {
    e.preventDefault();
    e.preventImmediatePropagation(); // might not be necessary
  }
})

please re-open if the issue persists.

@amrbashir
Copy link
Member

Also check #1657

@xuchaoqian
Copy link
Contributor Author

xuchaoqian commented Oct 30, 2021

Thank you for your response.

It does not work, too.

Can you change your snippet to

document.addEventListener('click', (e) => { 
  if (e.target.matches('a') {
    e.preventDefault();
    e.preventImmediatePropagation(); // might not be necessary
  }
})

please re-open if the issue persists.

But I got a workaround. Just change the target attribute of link to "_tab" or any other names not in the standard set: _self, _parent, _top, _blank.

    const links = document.links;
    for (let i = 0, n = links.length; i < n; i++) {
      const link = links[i];
      link.setAttribute("target", "_tab");
      link.onclick = function (event) {
        event.preventDefault();
        return false;
      };
    }

This workaround is suitable for our own sites, but does NOT work for third-party's site. It will be better to support capturing & handling all events from html document directly.

@amrbashir
Copy link
Member

I had a typo in that snippet, apologies.
we are capturing all clicks on <a> here so you might need to also add e.stopPropagation(), anyhow you should subscribe to the other issue and discuss it further there.

@xuchaoqian
Copy link
Contributor Author

Thank you so much. I will discuss this feature/bug in the other issue.

I had a typo in that snippet, apologies. we are capturing all clicks on <a> here so you might need to also add e.stopPropagation(), anyhow you should subscribe to the other issue and discuss it further there.

FYI:
I corrected that typo actually, but it still does not work. According to your advice, I have changed my code, as following:

    const links = document.links;
    for (let i = 0, n = links.length; i < n; i++) {
      const link = links[i];
      link.setAttribute("target", "_tab");
      link.onclick = function (event) {
        event.preventDefault();
        event.stopPropagation();
        return false;
      };
    }

@amrbashir
Copy link
Member

Alright, thanks for reporting back. Further discussion should be in #1657

@PierXuY
Copy link

PierXuY commented May 15, 2024

function setupLinks(node) {
    if (node.nodeName.toLowerCase() === 'a' && node.getAttribute("target") === "_blank") {
        console.log('Found <a> tag:', node);
        node.onclick = function (event) {
            event.preventDefault();
            event.stopPropagation();
            window.open(node.href, "_blank")
            return false;
        };

    }

    if (node.childNodes.length > 0) {
        node.childNodes.forEach((childNode) => {
            setupLinks(childNode);
        });
    }
}

const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
            setupLinks(node);
        });
    });
});

const target = window.document;
const config = { childList: true, subtree: true };
observer.observe(target, config);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants