代码之家  ›  专栏  ›  技术社区  ›  rap-2-h

防止违约后实际执行违约

  •  -1
  • rap-2-h  · 技术社区  · 7 年前

    我要阻止链接的默认行为( a ) 默认行为,比如在新窗口中打开链接。

    以下是一些HTML代码:

    <a href="somewhere" target="_blank" id="mylink">
    

    JS代码:

    document.getElementById('mylink').addEventListener('click', function (e) {
        e.preventDefault();
        axios.post('options', new FormData(document.querySelector('#myform')))
             .then(function(){ 
                 // Here I want to do what the link should have done!
             });
    });
    

    我知道我可以这样做:

    window.open(e.target.href);
    

    但这不是一个选项,因为浏览器认为这是一个弹出窗口。我不想在JS中重写一些东西,只需照常考虑链接:这个链接必须执行其默认行为(这是被阻止的)。

    有办法吗?

    3 回复  |  直到 6 年前
        1
  •  0
  •   Taha Paksu    7 年前

    以下是一些想法:

    var openingPopup = false;
    document.getElementById('mylink').addEventListener('click', function (e) {
        if(!openingPopup){
            e.preventDefault();
            axios.post('options', new FormData(document.querySelector('#myform')))
                .then(function(){ 
                    // make sure this would not run twice
                    openingPopup = true;
                    document.getElementById('mylink').click();
                });
        }else{
            // skipping this only for one time
            openingPopup = false; 
        }
    });
    

    这种方式,

    1. 您运行一次弹出窗口打开器单击处理程序,
    2. 然后阻止其他人,
    3. 再次手动触发Click事件,
    4. 这一次什么也不做,只允许别人跑。
        2
  •  0
  •   Doug    7 年前

    根据@electox qui mortem的建议链接,完成预处理后,可以删除事件侦听器并再次调用click。

    (相关MDN链接: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener )

    const anchor = document.getElementById('anchor');
    
    anchor.addEventListener('click', test);
    
    function test(e){
      e.preventDefault();
      alert('test');
      if( true ){
        console.log( this );
        this.removeEventListener('click', test);
        this.click();
      }
    }
    <a id="anchor" href="https://www.google.com">Test</a>

    它在代码测试工具(如jfiddle和codepen)中的性能不稳定——您必须在实际应用程序中测试它,以确保它是否适合您的用例。

    我只有很好的结果 removeEventListener 当引用外部函数作为“listener”函数时。在这种情况下 test()

        3
  •  0
  •   dgopsq    7 年前

    以一种更“本机”的方式,您可以创建一个新的“click”事件,它是不可取消的,并针对同一个元素触发它。

    var anchor = document.querySelector('#target');
    
    function triggerClick(target) {
      var newClick = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: false
      });
      
      target.dispatchEvent(newClick);
    }
    
    anchor.addEventListener('click', function(e) {
      e.preventDefault();
      
      if(e.defaultPrevented) {
        alert('Prevented!');
        triggerClick(anchor);
      }
      else {
        alert('Not prevented');
      }
    });
    <a href="https://google.com" target="_blank" id="target">Click me!</a>

    钥匙在这里 cancelable: false 在函数中创建的新事件中 triggerClick(target) ,它绕过了 e.preventDefault() .

    在stackoverflow的嵌入式示例中,它不起作用,但是 here's a JSFiddle !