2017-09-26 86 views
2

当用户单击链接或提交表单时,我希望触发并忘记请求,且延迟时间很短。这里有一个简单的代码,我使用的是:在Chrome中延迟提交表单

element.addEventListener(eventType, function(event) { 
    if (event.retriggered) { 
    return true; 
    } 

    let target = event.target; 
    let newEvent = new event.constructor(event.type, event); 
    newEvent.retriggered = true; 

    setTimeout(() => { 
    target.dispatchEvent(newEvent); 
    }, 250); 

    // fire and forget the request 
    makeRequest(); 

    event.preventDefault(); 
    return false; 
}); 

这工作正常click事件和它工作得很好submit事件在Firefox,但无法在Chrome。我创建了一个fiddle here。在Firefox中,如果您单击该按钮,则可以看到浏览器发出GET请求,但在Chrome中不会发生这种情况。根据我的测试,两个浏览器中的原始和新事件看起来都一样,并且dispatchEvent返回true。尽管如此,实际提交并未在Chrome中触发,因此我想知道Chrome会停止提交作为安全措施,还是我错过了某些内容?

回答

1

您正在调度的事件与您要复制的事件至少有一点不同。您的活动将事件的isTrusted属性设置为false。也许这就是Chrome不提交表单的原因。

我所知道的是你如何才能得到你想要的结果,对于表单,稍微不同的代码。我已经基于你的Fiddle中的代码,所以它现在只处理表单提交。

let 
 
    form = document.getElementById('form'); 
 

 
form.addEventListener('submit', function(event) { 
 
    setTimeout(() => { 
 
    form.submit(); 
 
    }, 250); 
 

 
    event.preventDefault(); 
 
});
<form id="form" method="get" action="/echo/html/"> 
 
    <button type="submit">Go</button> 
 
</form>

而是派遣自己提交的事件,你可以调用窗体的方法submit()。这将提交表单,但不会导致任何提交处理程序被解雇(根据this MDN文章)。它可以节省您在处理程序中的检查,以确定提交是否应该延迟。

你可以调整它也与锚工作。

let 
 
    form = document.getElementById('form'), 
 
    anchor = document.getElementById('anchor'); 
 

 
function onDelayNavigationEvent(event) { 
 
    const 
 
    target = event.target; 
 
    
 
    if (target.hasAttribute('is-delayed')) { 
 
    return true; 
 
    } 
 
    
 
    setTimeout(() => { 
 
    if (target.tagName.toLowerCase() === 'form') { 
 
     target.submit(); 
 
    } else { 
 
     target.click(); 
 
    } 
 
    }, 2000); 
 
    
 
    target.setAttribute('is-delayed', true); 
 
    event.preventDefault(); 
 
} 
 

 
function delayNavigation(element, eventName) { 
 
    element.addEventListener(eventName, onDelayNavigationEvent); 
 
} 
 

 
delayNavigation(form, 'submit'); 
 
delayNavigation(anchor, 'click');
<form id="form" method="get" action="/echo/html/"> 
 
    <button type="submit">Go</button> 
 
</form> 
 

 
<a id="anchor" href="//stackoverflow.com">Stack Overflow</a>

+0

这样的作品,谢谢。我所期待的,不包括特殊情况下的解决方案,但它似乎是Chrome的安全功能防止触发表单提交程序的事件。 –

+0

你可以尝试'目标[event.type]();'如果你真的不喜欢的'form'元素的检查。 – Thijs