物实社区交互式教程 - 开发讨论

@故事里的人 感谢贡献,我今天稍微折腾了一下怎么在 Discourse 里部署 driver.js 的问题。

编辑教程

以下是代码仓库(欢迎提交 pull request):

请注意所用的 driver.js 库已经升级到 1.0.1,0.9.x 和 1.0.x 有挺大的区别,所以还是用了新的以免后续有坑。这里是文档:https://driverjs.com/docs/basic-usage

测试教程

如何在 Discourse 环境下测试教程呢?我找到了一个比较简单的方法,使用 Discourse 自带的主题测试网站(需要注册 Discourse 官方论坛):https://discourse.theme-creator.io/

成功登录之后,访问 https://discourse.theme-creator.io/my/themes,点击 Install,选择 From a git repository,然后输入 Git 库的地址(如果你想测试你修改后的版本,请 fork 之后输入你的地址),例如:https://github.com/NetLogo-Mobile/Forum-Tutorial-Component.git

点击进入你的这个新主题,滚动到底部,点击 Preview 就可以啦。
image

如果你(或者我们)更新了主题,可以通过顶部的检查更新实现:
image

开发和测试你的教程

教程的本质是一种在特定页面触发的“一连串的步骤”。我们使用 driver.js 的格式撰写。例如下列教程:

[{
  "element": "#current-user",
  "popover": {
    "title": locale("messages.title"),
    "description": locale("messages.description"),
    "position": "left",
    "hopeElement": "#current-user.active",
    "nextClick" : "#current-user"
  }
}]

这里需要注意,教程的文本部分需要储存在 /locale/ 目录下的 yml 文件中,使用 Discourse 自带的本地化机制。

有时,你可能希望不需要在 Theme Creator 中更新 Git 再刷新页面来测试教程。这时,你可以在控制台中运行例如下述的调试脚本:

testTutorial([{
  "element": "#current-user",
  "popover": {
    "title": locale("messages.title"),
    "description": locale("messages.description"),
    "position": "left",
    "hopeElement": "#current-user.active",
    "nextClick" : "#current-user"
  }
}])

就会立刻运行配置中描述的教程脚本了。在完成测试之后,请记得保存到对应的文件中:/assets/physics-lab-forum.js

改了一下超链接,要用反引号引起来,要不然会被解析为超链接然后显示为网页标题

有时候URL更新但不会请求新的页面,而loadTutorial是在每次请求页面之后触发的,我想到了一个方法,但是由于重写了全部的点击链接 事件,不知道会不会有风险 :neutral_face:

代码还没提交到github,打算先问问。@John-Chen

export default apiInitializer("1.13.0", (api) => {
  loadTutorial(api);
  //If you change the URL by clicking the <a> tag, prevent default, then use history.pushState() instead
  //To loadTutorial when update content based on the URL without refreshing the page
  document.addEventListener('click', function(event) {
  const target = event.target;
  if (target.tagName.toLowerCase() === 'a') {
      event.preventDefault();
      const href = target.getAttribute('href');
      history.pushState({}, '', href);
      loadTutorial(api);
    }
  });
});

诶?好像直接用disxourse的api就行

嗯嗯

目前还有啥问题捏

有时候导航会在dom元素加载完成之前显示,不知道怎么解决

不能用DOMContentLoaded,因为有时候他路由(是这么叫吧,就是URL地址)变化是不会重新加载DOM事件的,我不知道怎么解决。

我是延迟200毫秒再开启导航,不过有时候依然会出现导航比页面先显示(导航由于找不到目标元素会全屏居中)

hmmmm 我查一下啊

试试这个帖子里的说法

我看了那个话题,似乎是在说将JS代码插入到body后面使他在最后加载,我没有尝试不过我推测这无法解决问题

为了在路由切换的时候能够检测导航,在最新的pull request里面(目前还没有被合并)我给切换路由绑定了开启导航的事件,也就是说,路由切换的时候JS代码已经进入任务队列了,更改代码位置应当是无效的

这个帖子顶楼有一个方案,那个方案是绑定header区域加载事件的

got it!等我试试

啊我没学过Ember啊。。按着文档试了一下,我的ember.run里面没有scheduleOnce啊似乎?哪里出问题了?

import loadScript from "discourse/lib/load-script";
import { apiInitializer } from "discourse/lib/api";
import Ember from 'ember';

// 这里没变

 // Register the initializer
export default apiInitializer("1.13.0", (api) => {
  const { run } = Ember; 
  const router = api.container.lookup('router:main');

  // Add route change listener
  router.one('didTransition', () => {
    run.scheduleOnce('afterRender', () => {
      loadTutorial(api);
    });
  });

  // Load tutorial on page load
  if (document.readyState === 'complete') {
    run.scheduleOnce('afterRender', () => {
      loadTutorial(api);
    });
  } else {
    document.addEventListener('DOMContentLoaded', () => {
      run.scheduleOnce('afterRender', () => {
        loadTutorial(api);
      });
    });
  }
  
});
    api.onPageChange((url) => {
        if (url === '/' || url === '/latest' || url === '/top') {
            randBackground();
        }
    });

要不试试这个,ember感觉是个外来依赖,不用好了

感谢。顺便注册了api.onLoad()事件解决了 导航在页面加载完成之前开启 的问题

目前已经没啥问题了,只需要编写配置文件就行

哦天,测试时还有一个问题:按照文档Driver.js 来显示关闭按钮,但是在手机端这是无效的(包括文档给的例子)

似乎是库本身的一个bug了?(即使是bug)应该也可以通过其他方式实现关闭(e.g 在介绍内容右下角手动写入按钮并且绑定事件)我觉得这会比较麻烦,似乎不值得去修了

以及:是否需要加一些样式美化?(默认CSS有些普通?)如果需要,这得麻烦紫大亲自来了,我的设计能力糟糕透顶。。

嗯,设计问题我们有设计师朋友,可以上线之后找个时间问问

按钮的问题我不确定这条是不是相关啊,这条说的只是你不能调整按钮的 innerHTML

啊不清楚了,也没搜到其他相关内容,依我看就不管这个关闭的问题了吧,应该不是很重要

测试时的一个小问题:如果在https://discourse.theme-creator.io/ 预览,只有登录状态才能成功预览插件,也就是说针对未登录用户的部分是无法测试的。。

1 个赞