【问题标题】:Should I use an iframe rather than ajax?我应该使用 iframe 而不是 ajax 吗?
【发布时间】:2016-02-02 09:24:39
【问题描述】:

我们正在构建一个带有音频播放器的 Drupal 站点,该播放器在您浏览页面时会一直播放(类似于 soundcloud)。

目前我们正在使用 AJAX 加载被点击的<a> 的站点,并将 HTML 注入页面并使用 history.js 来操纵位置。

但有一个主要缺点:

由于新加载的页面上可能有不同的 CSS 和 JS,我们必须将当前的脚本、样式和链接元素与 AJAX 响应文本(丑陋的 regex)进行比较,然后只添加新的,但不存在的元素。通过这样做,加载另一个页面不会在执行脚本后删除/删除/撤消。这可能会成为一个性能问题(而 regex 无论如何都是针对标记的)。

使用 iframe 可以解决这个问题和其他问题:

当您第一次点击网站上的链接时,页面内容会被替换为 iframe,它只会加载页面。音频播放器位于原始 DOM 中,即在 iframe 之外。 iframe 内的点击链接也可以在历史 API 中被捕获和使用。

所以,虽然我从没想过我会这样想:我认为在这里使用 iframe 可能是更好的选择,不是吗?

PS:我的主要问题是我无法控制网站上不同的页面有不同的脚本,样式真的没问题。如果网站范围内只有一个巨大的静态 JS 和 CSS,我没有问题。

更新

iframe 解决方案工作正常,iOS 除外。 Iframes 简直是天方夜谭。不过,我认为我们将使用 iframe 解决方案。

【问题讨论】:

  • 你可以有一个“reset.css”文件来清理所有以前加载的css——但是你需要确切地知道每个页面将以css的方式应用什么,听起来你无法控制。如果通过links 加载,也可以卸载 css,但同样取决于您加载 css 的方式,请看这里:stackoverflow.com/questions/1598899/unload-css-from-webpage
  • css 没问题。如果您删除样式或链接元素,则 css 将被撤消。如果您附加新的,样式会更新。但脚本的行为不同
  • 为什么需要不同的css/js文件?你不能连接/缩小它们并服务一次吗?这样,当更改页面时,您只需要正确处理不同的状态(绑定事件,取消绑定它们......)。
  • 您是否使用 pjax(或类似的,例如 github.com/defunkt/jquery-pjax)来处理这些请求?
  • @luchaos nope,常见的 jquery ajax

标签: jquery ajax iframe drupal html5-history


【解决方案1】:

我会说...保持简单,愚蠢。 选择 iframe 解决方案,我知道它会扼杀你的一部分灵魂,但它是解决问题的最简单方法,代表了未来遇到问题的最低变化。

亲吻。

【讨论】:

  • 我们目前正在测试 iframe 方法及其华丽。唯一真正的缺点是 iOS,它在 iframe 和错误方面存在巨大问题:(
【解决方案2】:

我看不出你不应该使用 iframe 的理由。我认为使用 iframe 在您的网站中嵌入页面很好。这就是 iframe 的用途。

iframe 过去不利于 SEO,但如今,网络爬虫通常可以在您的网站和 iframe 内容之间移动。

使用 iframe 将比使用“丑陋的正则表达式”更容易和更简单。为什么不保持简单,对吧? KISS principle

【讨论】:

  • 如果您的目标是保留单个内容区域,那么这将起作用。
  • 我们目前正在测试 iframe 方法及其华丽。唯一真正的缺点是 iOS,它在 iframe 和错误方面存在巨大问题。我认为 SEO 不会成为问题,因为 iframe 只会在您单击链接(通过 JS)时生成。
【解决方案3】:

你可以尝试做一些奇怪的事情。

首先,您可以将window 对象与新对象进行比较并删除所有额外属性(here's an example)。 documentHTMLElementArray.prototype 对象和其他对象也可以做同样的事情,这些对象可能通过脚本进行扩展。这样一来,您将消除大部分已定义的内容,而垃圾收集器会在某个时候将其丢弃。

其次,您希望删除所有事件侦听器。这可以通过重新定义 addEventListener 等 (refer to this question for example) 来实现。

第三,您不应该忘记间隔和超时,可以使用与前一种方法相同的方法(包装 setTimeout 等)(found it here)来处理。

当然会留下很多东西,这取决于页面中运行的脚本。因此,当用户在未播放歌曲时单击链接时,您可以刷新页面(可能在曲目之间进行转换)。看?有很多工作要做,而这可能一无所获。所以在所有这些理论之后,我会使用 iframe。因为,您知道,例如:如果您网站的某些脚本包装了任何 js 函数(就像我们在第二和第三中所做的那样),那么 ajaxing 会堆积对该函数的包装调用,这真的很糟糕。

【讨论】:

  • 暗示这也很有趣,这样的解决方案非常复杂,无疑会在未来引起问题。虽然他们的例子表明这是值得冒险的......在这种情况下,有一个更容易的解决方案。
  • @FlipVernooij 这正是我建议不要在答案中使用这种方法的原因。
【解决方案4】:

如你所说,

使用 iframe 可以解决这个问题和其他问题: 当您第一次单击站点上的链接时,页面内容将被替换为仅加载页面的 iframe。音频播放器位于原始 dom 中,即。 e.在 iframe 之外。点击 iframe 内的链接也可以在 history api 中被捕获和使用。

你可以用 ajax 做类似的事情。将所有需要替换的内容放在一个容器中,然后根据ajax响应替换该容器的内容。不要触摸该容器之外的内容。我认为这也将解决您的性能问题。

【讨论】:

  • "由于新加载的页面可能有不同的css和js,我们必须将当前的脚本、样式和链接元素与ajax响应文本(丑陋的正则表达式)进行比较,然后只添加新的,但不存在的元素。这样做,加载另一个页面不会删除/删除/撤消一旦执行的脚本。这可能会成为一个性能问题(尽管正则表达式反对标记是无论如何)。“
  • 但是最好在 iframe 本身中加载带有 css 和 js 元素的整个页面。
  • 我认为您还没有理解任何问题。通过 AJAX 加载内容没什么大不了的,但是 JS 和 CSS 呢?请再仔细阅读我的问题。
  • 详细地说,我假设您的用户以某种方式上传声音文件,您需要将这些文件保存在数据库中,您如何与数据库通信?您需要一个服务器端来执行此操作,前端 js 不能与 db 对话?如果您的内容都是静态的,您仍然可以利用服务器端来更轻松地添加内容
  • 好的,我明白了你的问题,但我想以更深层次的方式提供帮助,因为 iframe 不能完全解决你的问题,你需要始终拥有一个可靠的架构,以便将来验证你的应用程序,你想谈谈吗在skype什么的?如果你愿意,我很乐意提供帮助。
【解决方案5】:

如果您不介意,我想问您几个问题并在您回复时编辑此回复。 原因是我相信你在开始这个项目时做出了一些不方便的架构决定。根据您的描述,我假设您在单击标签时正在加载静态 html 页面,如果没有,您的后端技术是什么?

理想情况下,您应该将逻辑分为前端和后端,并将前端分为模型、视图和控制器,不一定通过使用框架或这样做(或 MVVM,如 Angular 那样)一些快速建议关于您如何加载数据,不要直接注入 html,使用您的后端技术将 json 或 xml 发送到前端,然后解析它以在位于前端的模板上显示您的 html,而不是发送您的 dom ,这样做会不必要地缓慢和昂贵。当你有后端时,尝试在黑盒环境中构建你的持久层,并通过一个简单的 API 调用操纵器方法,这样它会更干净,执行得更快,更可靠。同样,当您构建移动原生应用程序时,您只需重新使用您的 API 层。

css 和 js 上的正则表达式比较听起来完全是一个糟糕的 hack,我同意,使用 iframe 会更合适,但同样,我需要更多信息来讨论您的整体设置,并希望在更广泛的方面为您提供帮助看法。

更新:

我理解为什么这些页面可能有不同的 css,但我认为你的音乐播放器 js 应该是同一个来源,并附有不同的媒体 ID。假设这个设置,在你的drupal数据库中,我假设它是MySql,为你的“音乐播放器”页面制作一个自定义表,除了标准的id索引条目以及created_at、modified_at等,还有一个字段用于你的可播放源。

在您创建实际播放器的 Drupal 前端模板上,从您的数据库中写入此源 ID。这样,您的音乐页面就有了一页。对于 CSS,将所有内容保存在一个文件中,也许使用 SASS 或 LESS 之类的东西来编译您的 css 文件,以使所有内容更加有序。

总而言之,让你的 drupal 端,php 用嵌入式 JS 编写你的 html 页面,并通过 PHP 变量将 ID 从 DB 传递到前端,因为 PHP 渲染发生在服务器端,当 DOM 加载时连同您的 JS,页面 ID 将出现。希望这会有所帮助,如果您还有其他问题,请告诉我。

【讨论】:

  • 感谢您的意见,但我不太明白您想说什么。即使我会使用主干或角度,我仍然会面临依赖于页面的脚本和样式的问题。你的问题到底是什么? :) 临时投票
  • 嘿,谢谢,我问的是你的后端,即 js 和 css 在哪里运行,在一个简单的 apache/nginx/jetty 上,无论是 web 服务器还是伴随着后端语言,如 php、java 或 nodejs,据此,我将建议以更好的方式组织您的内容服务部分,这样您就不会遇到仅使用 iframe 的问题。
  • 正如我所写,我们使用 Drupal,所以使用 PHP。尽管如此,语言并不能阻止我的问题,不同的页面可能有不同的脚本
  • 感谢您的宝贵时间,但您根本不明白问题出在哪里 :) 没关系
  • 不客气,感谢投反对票,这是我应得的,因为至少我试图提供帮助。
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 2011-03-02
  • 2010-09-28
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多