当点击网页上的任何链接或提交按钮时如何在 JavaScript 中检测
Posted
技术标签:
【中文标题】当点击网页上的任何链接或提交按钮时如何在 JavaScript 中检测【英文标题】:How to detect in JavaScript when any link or submit button is clicked on a webpage 【发布时间】:2022-01-20 19:30:39 【问题描述】:我有一个显示远程资产数据(例如气象站数据)的网页,它每 5 秒向我们的服务器执行一次后台 XMLHttpRequest(),并在收到来自远程资产的新数据时重新加载页面。多年来,这一切都运行良好。
该页面还有许多链接和提交按钮,可用于转到其他页面或向服务器提交命令(然后服务器向资产发送命令)。我遇到的问题是服务器随后执行的一些命令涉及对第 3 方 Web 服务的调用,其中一些有时可能需要长达 30 秒才能返回或超时。但与此同时,如果有新数据从资产中进来,后台 JS 函数会重新加载页面,从而中断并取消用户发起的新 http 请求。
我可以通过向每个链接添加 onclick 或 onsubmit 标记并提交按钮来调用一个函数来禁用计时器来解决这个问题,但由于页面上可能有几十个链接,我希望可能有一个更简单的链接,更优雅的方式,一个简单的函数可以告诉我用户是否点击了某个东西,从而启动了一个新的活动 http 会话。
我通过从 html 头部执行 setTimeout('myCheckServerFunction("'+url+'")',5000);
来启用我的脚本。如果服务器告诉它有新数据,它会执行setTimeout(function()location.reload();,5000);
因此,如果用户单击了任何链接或按钮,因此如果新的 http 会话处于活动状态,我想禁用 JS 计时器并防止任何重新加载。有没有这样的功能?例如。像“window.isNewHttpRequestActive()”这样的东西?或者也许有一种方法可以检查 window.location 是否发生了变化? (不确定在新的 http 请求完成之前是否会更新。)
否则我可能会在每个链接上附加一个 addEventListener() 并在页面上提交按钮,但我是 php 开发人员而不是 JS,所以如果有人可以推荐解析 DOM 的最佳方法并将侦听器附加到每个链接和提交按钮也可以。
我确实尝试寻找“冒泡”到更高层的事件,例如。 body 元素,它会捕捉链接点击,但也会捕捉任何点击,即使只是点击任何空白区域,所以不确定它的效果如何,因为我仍然需要过滤该事件以确定它是否真的来自链接或按钮。谢谢。
【问题讨论】:
请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案。 【参考方案1】:监听 body 上的所有点击事件不一定是个坏主意。
编辑:正如 gre_gor 在评论中指出的那样,它可能是。如果其他元素位于链接或按钮内部,则点击的感知目标并不总是链接或按钮。
所以要避免使用我原来使用event.target.tagName
的方法。
以下代码将在文档的每个 a
元素上为 click
添加一个事件侦听器,如果设置了计时器,您可以取消它:
for (let element of document.getElementsByTagName("a")
element.addEventListener("click", (event) =>
if (relocationTimeout !== undefined)
clearTimeout(relocationTimeout);
relocationTimeout = undefined;
);
由您来调整循环中的选择器以满足您的需求。
当然不要忘记在设置时将超时引用存储在变量中:
let relocationTimeout = setTimeout(function()location.reload();,5000)
【讨论】:
如果您单击其中的另一个元素,这将不起作用。例如<a href="#"><span>text</span></a>
.
这对于作为一些测试的起点很有帮助,但是它不适用于按钮,因为这些按钮是作为来自“输入”元素的事件而 getElementsByTagName() 似乎不是能够区分不同的输入类型,例如文本框与提交按钮。因此,如果有人单击文本框,我会收到一个事件,但我只想知道是否有人单击了实际导致 http 请求的内容。谢谢
就指令而言,这可能是冗长而复杂的事情,但将document.getElementsByTagName("a")
替换为[].slice.call(document.getElementsByTagName("input")).filter(element => element.type === "/*input type here*/")
可以让您指定所需的输入标签类型。但此时最好手动为每个需要检查的元素指定一个特定的类,然后使用它。
您仍然可以收听所有点击事件。如果事件冒泡到a
/button
/input[type=submit]
,您只需要向上移动 DOM 树即可。或者只是做event.target.matches("a, a *, button, button *, input[type=submit]")
。
@gre_gor event.target.matches 很有帮助,因为它现在可以捕获对链接和按钮的所有点击。唯一的缺点是我有一些没有href(非活动链接)的标签,所以如果我点击其中一个标签,即使它们没有发起http请求,我仍然会收到一个事件。作为一个临时解决方案,我现在正在做的是使用 document.body.addEventListener() 获取事件以获取所有点击和提交事件(从正文 onload 调用),然后如果 target.matches 正如你所描述的那样,我只需重置我的计时器到 45 秒。这为任何新的 http 请求提供了足够的时间来完成。 ...以上是关于当点击网页上的任何链接或提交按钮时如何在 JavaScript 中检测的主要内容,如果未能解决你的问题,请参考以下文章