IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 【20211202】CmsWing代码分析 - src/controller/home/detail.js(三) -> 正文阅读

[JavaScript知识库]【20211202】CmsWing代码分析 - src/controller/home/detail.js(三)

2021SC@SDUSC

从这一篇开始,我们将要和对应的html文件一起分析,通过调用JavaScript文件的方式来推测更多使用的细节。

view/home/ceshi_hooks.html

这里是钩子。钩子是什么?https://www.jianshu.com/p/3382cc765b39介绍了钩子函数的使用方式。Hook技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。当然,这篇文章说的是Java程序里的Hook技术,但在JavaScript中也可以如此看待。

在这个Html文档中,让我们看看测试的钩子是如何运转的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--带 $hook_type 参数的 视图钩子调用,HOOK+@钩子名+@$hook_type-->
{{HOOK@adminArticleEdit@1|safe}} <hr>
<!--带 $hook_key 参数 视图钩子调用, HOOKS+@钩子名[$hook_key]-->
{{HOOKS@adminArticleEdit['aaaa']|safe}}<hr>
{{HOOKS@adminArticleEdit['bbbb']|safe}}<hr>
<!--带 $hook_type 和 $hook.key 参数 视图钩子调用, HOOKS+@钩子名[$hook_type]+@$hook_type-->
{{HOOKS@adminArticleEdit@2['bbbb']|safe}}<br>
<!--默认调用 HOOK+@钩子名-->
{{HOOK@adminArticleEdit|safe}}

</body>
</html>

前面是Html文档惯有的写作模式,不必多说。body一块让我们重点看一看。这里是写了一些示例的钩子调用,包括带$hook_type参数的视图钩子调用,带$hook_type$hook.key参数视图钩子调用,带$hook_type$hook.key 参数视图钩子调用,默认调用。

src/controller/home/detail.js

下面再让我们回头去看src/controller/home/detail.js。这里存放了一些钩子相关的函数。

this.assign('info', info);
// 文档内容底部钩子钩子
await this.hook('documentDetailAfter', info);
// 视频播放器钩子
await this.hook('videoPlayer', info);
// 加载页面头部底部钩子
const editor = !think.isEmpty(info.editor) ? info.editor : await this.model('cmswing/model').get_model(info.model_id, 'editor');
const field_group = await this.model('cmswing/model').get_model(info.model_id, 'field_group');
const fields = await this.model('cmswing/attribute').get_model_attribute(info.model_id, true);
const fg = parse_config_attr(field_group);
const farr = [];
for (const key in fg) {
  for (const f of fields[key]) {
    if (f.type === 'editor') {
      farr.push(f);
      // 添加编辑器钩子
      if (editor === '0') {
        await this.hook('pageHeader', f.name, f.value, {$hook_key: f.name});
        await this.hook('pageFooter', f.name, f.value, {$hook_key: f.name});
        await this.hook('pageContent', f.name, info[f.name], {$hook_key: f.name});
      } else {
        await this.hook('pageHeader', f.name, f.value, {$hook_key: f.name, $hook_type: editor});
        await this.hook('pageFooter', f.name, f.value, {$hook_key: f.name, $hook_type: editor});
        await this.hook('pageContent', f.name, info[f.name], {$hook_key: f.name, $hook_type: editor});
      }
    };
  };
};

文档内容底部钩子,视频播放器钩子和加载页面头部底部钩子,总之全是钩子。

接下来又是我们熟悉的浏览器差分:

    // 判断浏览客户端
    if (this.isMobile) {
      // 手机模版
      if (!think.isEmpty(info.template) && info.template != 0) {
        temp = info.template; // todo 已设置详情模板
      } else if (!think.isEmpty(cate.template_m_detail)) {
        temp = cate.template_m_detail; // 分类已经设置模板
      } else {
        temp = model;
      }
      // console.log(temp);
      // 内容分页
      // if (!think.isEmpty(info.content)) {
      //   info.content = info.content.split('_ueditor_page_break_tag_');
      // }
      return this.display(this.mtpl(temp));
    } else {
      if (!think.isEmpty(info.template) && info.template != 0) {
        temp = info.template; // 已设置详情模板
      } else if (!think.isEmpty(cate.template_detail)) {
        temp = cate.template_detail; // 分类已经设置模板
      } else {
        temp = model;
      }
      // console.log(temp);
      // console.log(info);
      // 内容分页
      // if (!think.isEmpty(info.content)) {
      //   info.content = info.content.split('_ueditor_page_break_tag_');
      // }
      return this.display(`home/detail_${temp}`);
    }
  }

最后是关于下载的一段代码,很长但是并没有很复杂。

  /**
     * 下载
     */
  async downloadgetidAction() {
    const id = decodeURIComponent(this.get('id')).split('||');
    const db = this.model('document_download');
    const info = await db.find(id[0]);
    // console.log(info);
    const file_id = info.file_id;
    // console.log(file_id);
    let dlink;
    if (Number(id[1]) === 1) {
      // console.log(location);
      const d = await get_file(file_id);
      if (Number(d.type) === 2) {
        // 七牛下载
        // dlink = await get_file(file_id,"savename",true);
        const qiniu = this.extService('qiniu', 'attachment');
        dlink = await qiniu.download(d.savename);
      } else {
        // 本地下载
        dlink = `/home/detail/download?id=${d.id}#${d.name}`;
      }
      // console.log(dlink);
      // 访问统计
      await db.where({id: info.id}).increment('download');
      // return this.redirect(dlink);
      this.assign('durl', dlink);
      if (this.isMobile) {
        // 手机模版
        return this.display(`home/mobile/detail_downloadgetid`);
      } else {
        return this.display();
      }
    } else if (id[1] == 2) {
      dlink = id[2];
      await db.where({id: info.id}).increment('download');
      return this.redirect(dlink);
    } else if (id[1] == 3) {
      // 返回网盘提取码
      const pan = info.panurl.split('\r\n');
      for (const v of pan) {
        const varr = v.split('|');
        console.log(varr[1]);
        if (!think.isEmpty(varr[2]) && think._.trim(id[2]) == think._.trim(varr[1])) {
          this.assign({
            title: varr[0],
            durl: varr[1],
            sn: varr[2]
          });
        }
      }
      await db.where({id: info.id}).increment('download');
      if (this.isMobile) {
        // 手机模版
        return this.display(`home/mobile/detail_downloadgetid`);
      } else {
        return this.display();
      }
    }
  }

其中包含一些判定和分流工作,不再赘述。最后依旧是和下载相关的代码——

  // 下载文件
  async downloadAction() {
    const file = await get_file(this.get('id'));
    const filePath = `${think.ROOT_PATH}/www${file.savename}`;
    const userAgent = this.userAgent.toLowerCase();
    let hfilename = '';
    if (userAgent.indexOf('msie') >= 0 || userAgent.indexOf('chrome') >= 0) {
      hfilename = `=${encodeURIComponent(file.name)}`;
    } else if (userAgent.indexOf('firefox') >= 0) {
      hfilename = `*="utf8''${encodeURIComponent(file.name)}"`;
    } else {
      hfilename = `=${Buffer.from(file.name).toString('binary')}`;
    }
    this.ctx.set('Content-Disposition', `attachment; filename${hfilename}`);
    return this.download(filePath);
  }
};

总结

src/controller/home/detail.js为我们展现了首页的详情需要的各种函数,从功能上来讲可能并不复杂,却要做到面面俱到。从这当中也可以看到,从一个框架到真正实现一个页面的展示中间需要多少距离。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-03 12:57:17  更:2021-12-03 12:59:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:14:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码