【问题标题】:Intercepting click events across Shadow DOM barrier跨 Shadow DOM 屏障拦截点击事件
【发布时间】:2014-09-08 05:47:46
【问题描述】:

在我的应用程序中,我拦截对链接的点击并将它们转换为 AJAX 调用,以实现单页应用程序。在 jQuery 中,这看起来像这样:

$('#main').on('click', 'a[href]', function(e) {
  if (e.which == 2 || e.metaKey) return; // don't capture new tab clicks
  /* stuff */
});

不过,最近我开始使用自定义元素和 Shadow DOM。上面的代码不适用于影子树中的a 标签,因为点击事件会重新定位到影子主机。

是否可以使上述代码工作以拦截影子树中发生的点击事件?如果没有,继续实现此功能的最佳做法是什么?

注意:我正在使用 Polymer Platform 来填充 Web 组件(虽然不是完整的 Polymer)。

【问题讨论】:

标签: javascript single-page-application polymer shadow-dom


【解决方案1】:

在 Polymer ≥0.4.0 中,您可以使用 /deep/ 组合器:

$('#main').on('click', '* /deep/ a[href]', function() {
  if (e.which == 2 || e.metaKey) return; // don't capture new tab clicks
  /* stuff */
});

注意:应谨慎使用此技术,因为它可能会在所有组件的实现中混为一谈,包括 Web 平台的某些部分,例如 <video> 标签。

【讨论】:

  • 主要问题是您在每个<a> 标签上注册了一个点击处理程序,而不是使用事件委托。它会起作用,但它可能效率不高。
  • 好点。从简短的探索来看,jQuery 并没有像我预期的那样在 /deep/ 上窒息,所以也许你也可以通过委托来使用惯用的 jquery 方式。
  • 我认为这可能没问题,因为我会检查 URL 以确保它是 HTTP(S),而不是片段引用等。所以它不应该破坏
  • 我已经对其进行了更新,以更接近原始问题,并且可以跨原生和非原生 shadow dom 实现工作。
  • 这在 window.ShadowDOMPolyfill 为真(即在 Polymer Platform 中)时不起作用
【解决方案2】:

您可能希望从一开始就以这种方式设计它,而不是围绕现有结构进行修改以使其像单页应用一样运行。这将使您充分利用 Web Component 的强大功能。这是一个使用 Polymer 的单页应用程序的 demo(和 source)。即使你不想使用 Polymer,你也可以自己使用 flatiron-director 来完成同样的事情。

【讨论】:

  • 这就是我“从一开始就这样设计”成为 SPA 的方式?大部分页面(包括自定义元素)都是用户生成的内容,所以我无法控制标记。该演示在 Firefox 中不适合我。
  • 好点。如果是用户生成的内容,您可能会被 Peter 的回答所困扰。
【解决方案3】:

您可能希望使用core-ajax 来处理您的ajax 调用和某种形式的inter-components communication 来更新您的自定义元素。

【讨论】:

  • 这不是关于聚合物的问题。它是关于 ShadowDOM/Web 组件,由 Polymer Platform 填充。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-20
  • 1970-01-01
相关资源
最近更新 更多