Knockout JS 与 Ratchet 和 Push.js 配合得很好,直到我添加数据转换

2024-04-28

我正在使用 Ratchet.js/push.js 库为移动 Web 应用程序创建 UI。在这个库中,链接是通过将要加载的文件“推送”到“.content”DOM 元素中而不是加载整个页面来处理的。但是,push.js 在加载页面时不会加载它找到的任何脚本 - 这会禁用我的 Knockout.js 代码。

我在 StackOverflow 上找到了一个效果很好的解决方案 - 只需为推送事件添加一个事件侦听器。我修改了它,以便它可以跨多个页面加载任何脚本,因此它可以与外部脚本文件一起使用:

window.addEventListener('push', function () {
  var scriptsList = document.querySelectorAll('script.js-custom');  // Add a "js-custom" class to your script tag
  for (var i = 0; i < scriptsList.length; ++i) {
      // Handle scripts in separate files by assigning the script file name to its id.
      // We save it in a variable because the ".done" callback is asynchronous.
      scriptName = scriptsList[i].id;  // IMPORTANT: Only one loadable script per page!
      $.getScript("/path info here/" + scriptName)
        .done(function (script, textStatus) {
            eval(script);
        })
         ... error handling ...
  }
});

在目标 HTML 页面中,脚本被赋予了 class 和 id 标签,因此它们可以与上述内容一起使用:

    <script src="Challenge.js" class="js-custom" id="challenge.js"></script>

另请注意,Knockout 绑定必须发生在特定命名的 DOM 元素上,这样淘汰才不会混淆:

ko.cleanNode($("#ChallengePage")[0]);
ko.applyBindings(challengeFn,  $("#ChallengePage")[0]);

我们使用 cleanNode 来避免“已绑定”错误。

好的!所以这一切都很有效,我希望那些正在为此苦苦挣扎的人发现它很有用。

但是,当链接发生转换时:

<a href="challenge.html" data-transition="slide-in">....

然后它会因“无法读取未定义的属性‘nodeType’”而中断。我原以为这可能只是等待转换完成的问题,但即使我将脚本的 eval 替换为:

scriptContents = script;
setTimeout(function () { eval(scriptContents); }, 1000);

这没有帮助。

任何建议或帮助将不胜感激!如果我不能使用转换,我真的不需要“推送”页面,所以我希望有人能拥有使这一切顺利进行的最后一把钥匙!

更新:发生错误是因为使用转换时的“document.querySelectorAll”调用使用current文档而不是被推送的文档。另外,使用“webkitTransitionEnd”作为我的事件也可以,但这并不能解决文档问题。因此,我可以完成这项工作,但仅限于一次转换 - 现在我没有办法加载文档。理想情况下,我正在寻找一种无论链接是否使用转换都有效的解决方案。


Ratchet 和 Knockout 的组合可能会在未来几个月内流行,所以我希望其他人找到这个解决方案。

要组合 Ratchet.js 和 Knockout.js 库,只需处理 Ratchet.js(通过 Push.js)将尝试管理页面转换的事实。在转换期间,目标页面上的 JavaScript(包括 Knockout)将不会运行,除非您专门执行此操作。这就是该解决方案的作用:即使 Ratchet 正在管理页面转换,它也可以加载并运行 Knockout JavaScript 代码。

在我的解决方案中,我们always将 JavaScript 放在单独的文件中,并实施内容安全策略,禁止任何 JS 代码在页面上运行。这只是良好的安全卫生,有助于减少 XSS 攻击的攻击面。因此,下面的解决方案 1) 假设 JS 位于单独的文件中,2) 假设 HTML 和 JS 文件具有完全相同的名称和路径 - 除了扩展名之外(有点像将 .js 文件视为 ASP)。 NET HTML 文件的代码隐藏)。

在您的“根”页面(启动与移动网络应用程序上其他页面的所有交互的页面)上,放置以下函数。每当 Ratchet 加载相应的 .html 文件时,它将加载适当的 .js 文件:

window.addEventListener('push', function (params) {
    var targetPage = params.target.document.baseURI.replace(".html", ".js");
    $.getScript(targetPage)
        .done(function (script, textStatus) {
            eval(script);
        })
        .fail(function (jqxhr, settings, exception) {
            alert("Error loading script: " + exception);
        });
});

请注意,您必须将 Knockout 绑定应用到 HTML 页面中的命名且唯一的 div(通常是位于 Ratchet .content div 正下方的 div)。这只是因为每个页面加载都必须将其 Knockout 绑定应用于正在加载的 HTML。

ko.cleanNode($("#DivPageName")[0]);
ko.applyBindings(KnockoutFn, $("#DivPageName")[0]);

更新:我发现当页面从历史堆栈中推送和弹出时,这个解决方案有时会变得“混乱”。我决定不使用它,尽管它看起来大约有 97%。如果有人有任何改进可以使其完全可靠,我洗耳恭听!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Knockout JS 与 Ratchet 和 Push.js 配合得很好,直到我添加数据转换 的相关文章

  • 如何使用 JavaScript 压缩文件?

    有没有办法使用 JavaScript 来压缩文件 例如 在雅虎邮件中 当您选择下载电子邮件中的所有附件时 它会被压缩并下载到单个 zip 文件中 JavaScript 能够做到这一点吗 如果是这样 请提供一个编码示例 我发现这个图书馆叫js
  • 如何使用javascript将视频文件转换为字符串?

    我在 signalR 工作 我想通过将视频文件拆分为不同部分来将视频文件从一个客户端发送到另一个客户端 我已经通过分割图像源数据发送图像并在另一个客户端上接收该图像 document getElementById fileUpload ad
  • AngularJS 服务并承诺最佳实践

    我有一个 AngularJS 应用程序services 调用 http资源并返回promise我在控制器中解决了这个问题 这是我正在做的事情的示例 app service Blog function http q var deferred
  • 如何将 vue3-openlayers 插件添加到 nuxt

    我有以下 main ts 文件Vue3 https v3 vuejs org import createApp from vue import App from App vue How to do this in nuxt3 import
  • 如何使用 javascript 将我的域名字母大写?

    假设我的域名是www hello com 如何使用 jQuery JavaScript 使浏览器的 URL 栏看起来像 www HELLO com 您无法更改浏览器地址栏中显示的内容 这是一项基本的安全功能 您可以使您的域名全部大写 并将页
  • 单击 btn 而不触发 div 单击未按预期工作

    代码沙盒 https codesandbox io s currying breeze depdc9 file package json https codesandbox io s currying breeze depdc9 file
  • 2 个 SVG 路径的交集

    我需要检查两个 SVG Path 元素是否相交 检查边界框与 getBBox 太不准确了 我目前正在做的是迭代两条路径 getTotalLength 然后检查是否有两个点 getPointAtLength 是平等的 下面是一个片段 但正如您
  • 如何使用css网格制作一个垄断板?

    I want to create a monopoly board like There are following features in the board 角是方形的 比其他盒子大 每行的文本都面向特定的角度 我的基本 html 结构
  • 复合组件和 CSS

    I have newcss css formdiv width 30 margin 150 auto 和复合组件
  • 如何让导航栏在向下滚动页面时改变颜色?

    我希望导航栏是透明的 但是当您向下滚动页面时 它会变为红色 div class nav div class container div class logo a href img src RepublicSquare logo svg st
  • 如何在 Node.js 中打开 Windows-1255 编码文件?

    我有一个 Windows 1255 希伯来语 编码的文件 我希望能够在 Node js 中访问它 我尝试使用打开文件fs readFile 它给了我一个Buffer我无能为力 我尝试将编码设置为Windows 1255 但这没有被识别 我还
  • 使用 jQuery 获取 JSON Facebook Graph API 用户信息

    我正在尝试使用图形 API 来获取有关用户的一些基本信息 无需用户授权 只需获取公共详细信息 我正在尝试使用 jQuery 和 getJSON 来获取数据并解析它 但我很难弄清楚如何访问我想要的键值对 我想要有类似的东西 var fburl
  • 跟踪预防阻止了对 https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js 存储的访问

    大约一年半前 我使用 OfficeJS API 编写了一个 Excel 加载项 它一直工作到大约两周前 Excel 似乎已经进行了更新 现在我可以右键单击任务窗格并查看开发工具 而以前我无法做到这一点 并且必须运行外部 MS Edge 开发
  • 鼠标输入时反应显示按钮

    我有一个反应组件 它包含如下方法 mouseEnter console log this is mouse enter render var album list const albums this props if albums user
  • 如何从代码隐藏中向我的 div 添加点击事件?

    如何从代码隐藏中向我的 div 添加点击事件 当我点击 div 时 会出现一个消息框 其中显示 您想删除它吗 并在框中显示 是 或 否 全部来自后面的代码 while reader Read System Web UI HtmlContro
  • 指定 body CSS 宽度安全吗?

    现在通常满足于以一定的尺寸居中 div Blah div 不使用包装器进行对齐和大小并直接将其应用到body tag 像这样 Blah 尺寸是
  • 反转比例函数

    这对我来说很有趣 看下面的D3代码 var scale d3 scale linear domain 100 500 range 10 350 scale 100 Returns 10 scale 300 Returns 180 scale
  • 数组长度未定义[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我试图按如
  • 如何在控制台中隐藏日志消息的来源?

    当将消息输出到控制台时 还会显示源代码 在 Chrome 开发者工具中 它位于右侧 console log Foo Source Foo test js 1 Output 但是 在某些网站上 会显示消息without正在显示的源 例如Fac
  • 如何将函数导入到Vue组件中?

    我正在尝试将单个函数导入到我的 Vue 组件中 我为我的函数创建了一个单独的 js 文件 randomId js exports randomId gt My function 在我的 Vue 组件中 我导入了 Random js let

随机推荐