Ratchet教程:自动化部署与组件概览

发布于 周文彬1986

今天是关于Ratchet教程中的第三篇。在正式表这篇文章之前,首先要非常感谢好友@文彬提供这么优秀的教程。下面我们跟随文彬的教程往下了解。

ratchet是一个移动框架,可以用来快速搭建移动项目。本文将介绍grunt服务器搭建,ratchet组件的使用。

如果您从未接触过Grunt相关知识,可以先了解一下Grunt相关的技术。——@大漠

项目文件

ratchet的项目文件如下

ratchet/
├── css/
│   ├── ratchet.css
│   ├── ratchet.min.css
│   ├── ratchet-theme-android.css
│   ├── ratchet-theme-android.min.css
│   ├── ratchet-theme-ios.css
│   ├── ratchet-theme-ios.min.css
├── js/
│   ├── ratchet.js
│   └── ratchet.min.js
└── fonts/
    ├── ratchicons.eot
    ├── ratchicons.svg
    ├── ratchicons.ttf
    └── ratchicons.woff

css文件包含android和ios皮肤文件。

有关于更详细的介绍,可以阅读《Ratchet教程》中的第一篇《Ratchet教程——安装》。

搭建服务器

任何一种服务器都可以访问ratchet项目,有很多一键安装包,比如xampp。这里介绍一下最近非常热的nodejs来搭建一个服务器,并配置自动刷新插件。

  • 安装nodejs
  • 安装gruntjsnpm install -g grunt-cli
  • 初始化package.json: 在项目根目录下,命令行执行npm init,一路回车。
  • 安装依赖模块: 在项目根目录下,命令行执行npm install --save-dev grunt matchdep grunt-contrib-connect grunt-contrib-watch connect-livereload grunt-open
  • 根目录新建Gruntfile.js文件,修改src:'src/app/'为你的源码目录,配置信息如下,然后在项目根目录下执行grunt server,就可以开启一个服务器了。
/**
 * 自动化脚本定义
 */
module.exports = function (grunt) {
  'use strict';

  //load all grunt tasks
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  //define tasks
  grunt.registerTask('server', ['connect:server', 'open:server', 'watch:server']);

  //env cfg
  var pkg = grunt.file.readJSON('package.json');
  var cfg = {
    src: 'src/app/',
    // Change 'localhost' to '0.0.0.0' to access the server from outside.
    serverHost: '0.0.0.0',
    serverPort: 9000,
    livereload: 35729
  };  

  //grunt config
  grunt.initConfig({
    //======== 配置相关 ========
    pkg: pkg,
    cfg: cfg,

    //======== 开发相关 ========
   //开启服务
    connect: {
      options: {
        port: cfg.serverPort,
        hostname: cfg.serverHost,
        middleware: function(connect, options) {
          return [
            require('connect-livereload')({
              port: cfg.livereload
            }),
            // Serve static files.
            connect.static(options.base),
            // Make empty directories browsable.
            // connect.directory(options.base),
          ];
        }
      },
      server: {
        options: {
          // keepalive: true,
          base: cfg.src,
        }
      }
    },

    //打开浏览器
    open: {
      server: {
        url: 'http://localhost:' + cfg.serverPort
      }
    },

    //监控文件变化
    watch: {
      options: {
          livereload: true,
          spawn: false    // 此属性在只检测改变的文件情况下必须
      },
      server: {
        files: [cfg.src + '/**'],
        // tasks: [''],
      },
    }
  });
};

初始化html

在项目的根目录下新建一个index.html文件,复制以下代码。

<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">

<!-- Makes your prototype chrome-less once bookmarked to your phone's home screen -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">

<!-- Include the compiled Ratchet CSS -->
<link rel="stylesheet" href="css/ratchet.css">

<!-- Include the compiled Ratchet JS -->
<script src="js/ratchet.js"></script>



<!-- Make sure all your bars are the first things in your <body> -->
<header class="bar bar-nav">
    <h1 class="title">Ratchet</h1>
</header>

<!-- Wrap all non-bar HTML in the .content div (this is actually what scrolls) -->
<div class="content">
    <p class="content-padded">Thanks for downloading Ratchet...</p>
    <div class="card">
        <ul class="table-view">
            <li class="table-view-cell">
                <a class="push-right" href="http://goratchet.com">
                    <strong>Ratchet documentation</strong>
                </a>
            </li>
            <li class="table-view-cell">
                <a class="push-right" href="https://github.com/twbs/ratchet/">
                    <strong>Ratchet on Github</strong>
                </a>
            </li>
            <li class="table-view-cell">
                <a class="push-right" href="https://groups.google.com/forum/#!forum/goratchet">
                    <strong>Ratchet Google group</strong>
                </a>
            </li>
            <li class="table-view-cell">
                <a class="push-right" href="https://twitter.com/goratchet">
                    <strong>Ratchet on Twitter</strong>
                </a>
            </li>
        </ul>
    </div>
</div>

就能看到如下的效果,是不是很快就入门了。

Ratchet教程:自动化部署与组件概览

仿真

Ratchet教程:自动化部署与组件概览

chrome浏览器要开启仿真的效果,才能看到js效果。

ratchet组件

组件在官网有很全的展示,这里简单的翻译下,并自己把代码尝试了一遍。

标题栏

<header class="bar bar-nav">
    <h1 class="title">Title</h1>
</header>

Ratchet教程:自动化部署与组件概览

带按钮的标题栏

<header class="bar bar-nav">
    <button class="btn pull-left">Left</button>
    <button class="btn pull-right">Right</button>
    <h1 class="title">Title</h1>
</header>

使用pull-left和pull-right实现左右浮动,button样式下面会有介绍。

Ratchet教程:自动化部署与组件概览

带图标的标题栏

<header class="bar bar-nav">
    <a class="icon icon-left-nav pull-left"></a>
    <a class="icon icon-compose pull-right"></a>
    <h1 class="title">Title</h1>
</header>   

图标样式下面会有介绍。

Ratchet教程:自动化部署与组件概览

带按钮和图标的标题栏

<header class="bar bar-nav">
    <button class="btn btn-link btn-nav pull-left">
        <span class="icon icon-left-nav"></span>
        Left
    </button>
    <button class="btn btn-link btn-nav pull-right">
        Right
        <span class="icon icon-right-nav"></span>
    </button>
    <h1 class="title">Title</h1>
</header>

在botton里面包含icon,.btn-link去掉边框效果,.btn-nav让按钮更接近边框。
Ratchet教程:自动化部署与组件概览

带切换效果的标题栏

<header class="bar bar-nav">
    <button class="btn pull-left">Left</button>
    <button class="btn pull-right">Right</button>
    <div class="segmented-control">
        <a class="control-item active">One</a>
        <a class="control-item">Two</a>
        <a class="control-item">Three</a>
    </div>
</header>

切换的效果会在下面介绍。

Ratchet教程:自动化部署与组件概览

底部标签卡

<nav class="bar bar-tab">
    <a class="tab-item active" href="#">
        <span class="icon icon-home"></span>
        <span class="tab-label">Home</span>
    </a>
    <a class="tab-item" href="#">
        <span class="icon icon-person"></span>
        <span class="tab-label">Profile</span>
    </a>
    <a class="tab-item" href="#">
        <span class="icon icon-star-filled"></span>
        <span class="tab-label">Favorites</span>
    </a>
    <a class="tab-item" href="#">
        <span class="icon icon-search"></span>
        <span class="tab-label">Search</span>
    </a>
    <a class="tab-item" href="#">
        <span class="icon icon-gear"></span>
        <span class="tab-label">Settings</span>
    </a>
</nav>  

使用.bar-tab来使菜单固定在底部,官方文档有错。注意:可以用push.js来切换页面,push.js后面会介绍。

Ratchet教程:自动化部署与组件概览

底部标签卡(纯文字)

<nav class="bar bar-tab">
    <a class="tab-item active" href="#">Label</a>
    <a class="tab-item" href="#">Label</a>
    <a class="tab-item" href="#">Label</a>
</nav>

如果只要显示文字,去掉icon,只要保留文字就可以了,文字可以垂直居中。注意:可以用push.js来切换页面,push.js后面会介绍。

Ratchet教程:自动化部署与组件概览

标准栏

<!-- Segmented control in standard bar fixed to top -->
<nav class="bar bar-standard">
    <div class="segmented-control">
        <a class="control-item active">Thing one</a>
        <a class="control-item">Thing two</a>
        <a class="control-item">Thing three</a>
    </div>
</nav>

<!-- Block button in standard bar fixed below top bar -->
<div class="bar bar-standard bar-header-secondary">
    <button class="btn btn-block">Block level button</button>
</div>

<!-- Block button in standard bar fixed above the footer -->
<div class="bar bar-standard bar-footer-secondary">
    <button class="btn btn-block">Block level button</button>
</div>

<!-- Icons in standard bar fixed to the bottom of the screen -->
<div class="bar bar-standard bar-footer">
    <a class="icon icon-compose pull-left"></a>
    <a class="icon icon-gear pull-right"></a>
</div>

标准栏是固定在四个位置的元件,.bar-header-secondary在顶栏的下面,.bar-footer-secondary在底栏.bar-footer上面

Ratchet教程:自动化部署与组件概览

排版

<div class="content-padded">
    <h1>h1. Heading</h1>
    <h2>h2. Heading</h2>
    <h3>h3. Heading</h3>
    <h4>h4. Heading</h4>
    <h5>h5. Heading</h5>
    <h6>h6. Heading</h6>
    <p>Lorem ipsum dolor sit ...</p>
</div>

添加.content-padded来增加一些间隙。

Ratchet教程:自动化部署与组件概览

列表

<ul class="table-view">
    <li class="table-view-cell">Item 1</li>
    <li class="table-view-cell">Item 2</li>
    <li class="table-view-divider">Divider</li>
    <li class="table-view-cell">Item 3</li>
</ul>

table-view-divider来划分列表,显示成灰色。

Ratchet教程:自动化部署与组件概览

带箭头的列表

<ul class="table-view">
    <li class="table-view-cell">
        <a class="navigate-right">Item 1</a>  
    </li>
    <li class="table-view-cell">
        <a class="navigate-right">Item 2</a>
    </li>
    <li class="table-view-cell">
        <a class="navigate-right">Item 3</a>   
    </li>
</ul>

navigate-left显示左边箭头,navigate-left显示右边箭头。android主题不显示箭头,具体可以看这里

Ratchet教程:自动化部署与组件概览

带消息提示的列表

<ul class="table-view">
    <li class="table-view-cell">Item 1 <span class="badge">4</span></li>
    <li class="table-view-cell">Item 2 <span class="badge">1</span></li>
    <li class="table-view-cell">Item 3 <span class="badge">5</span></li>
</ul>

添加一个.badgespan元素,消息气泡的样式后面会介绍。
Ratchet教程:自动化部署与组件概览

带消息提示和箭头的列表

<ul class="table-view">
    <li class="table-view-cell">
        <a class="navigate-right">
            <span class="badge">5</span>
            Item 1
        </a>
    </li>
    <li class="table-view-cell">
        <a class="navigate-right">
            <span class="badge">5</span>
            Item 2
        </a>
    </li>
    <li class="table-view-cell">
        <a class="navigate-right">
            <span class="badge">5</span>
            Item 3
        </a>
    </li>
</ul>

前面两个的组合。

Ratchet教程:自动化部署与组件概览

带图片的列表

    <ul class="table-view">
          <li class="table-view-cell media">
            <a class="navigate-right">
                  <img class="media-object pull-left" src="http://placehold.it/42x42">
                  <div class="media-body">
                    Item 1
                    <p>Lorem ipsu...</p>
                  </div>
            </a>
          </li>
          <li class="table-view-cell media">
            <a class="navigate-right">
                  <img class="media-object pull-left" src="http://placehold.it/42x42">
                  <div class="media-body">
                    Item 1
                    <p>Lorem ipsum...</p>
                  </div>
            </a> 
          </li>
          <li class="table-view-cell media">
            <a class="navigate-right">
                  <img class="media-object pull-left" src="http://placehold.it/42x42">
                  <div class="media-body">
                    Item 1
                    <p>Lorem ipsum dolor ...</p>
                  </div>
            </a> 
        </li>
    </ul>

图片左浮动,内容放media-body里面触发BFC。

Ratchet教程:自动化部署与组件概览

带图标的列表

<ul class="table-view">
    <li class="table-view-cell media">
        <a class="navigate-right">
            <span class="media-object pull-left icon icon-trash"></span>
            <div class="media-body">Item 1</div>
        </a>
    </li>
    <li class="table-view-cell media">
        <a class="navigate-right">
            <span class="media-object pull-left icon icon-gear"></span>
            <div class="media-body">Item 2</div>
        </a>
    </li>
    <li class="table-view-cell media">
        <a class="navigate-right">
            <span class="media-object pull-left icon icon-pages"></span>
            <div class="media-body">Item 3</div>
        </a>
    </li>
</ul>

用法和图片一样

Ratchet教程:自动化部署与组件概览

带按钮的列表

<ul class="table-view">
    <li class="table-view-cell">Item 1 <button class="btn">Button</button></li>
    <li class="table-view-cell">Item 2 <button class="btn btn-primary">Button</button></li>
    <li class="table-view-cell">Item 3 <button class="btn btn-positive">Button</button></li>
    <li class="table-view-cell">Item 4 <button class="btn btn-negative">Button</button></li>
</ul>

放入.btn元素,会自动定位到右边。

Ratchet教程:自动化部署与组件概览

带开关按钮的列表

<ul class="table-view">
    <li class="table-view-cell">
        Item 1
        <div class="toggle">
            <div class="toggle-handle"></div>
        </div>
    </li>
    <li class="table-view-cell">
        Item 2
        <div class="toggle active">
            <div class="toggle-handle"></div>
        </div>
    </li>
    <li class="table-view-cell">
        Item 3
        <div class="toggle">
            <div class="toggle-handle"></div>
        </div>
    </li>
</ul>

把按钮换成开关,交互效果要在仿真才能看到。

Ratchet教程:自动化部署与组件概览

卡片式列表

<div class="card">
    <ul class="table-view">
        <li class="table-view-cell">Item 1</li>             <li class="table-view-cell">Item 2</li>
        <li class="table-view-cell table-view-divider">Divider</li>
        <li class="table-view-cell">Item 3</li>
        <li class="table-view-cell">Item 4</li>
    </ul>
</div>

外面包一层card,设置间隙,还有边框和圆角。

Ratchet教程:自动化部署与组件概览

按钮

<button class="btn">Button</button>
<button class="btn btn-primary">Button</button>
<button class="btn btn-positive">Button</button>
<button class="btn btn-negative">Button</button>
<button class="btn btn-link">Button</button>

<button class="btn btn-outlined">Button</button>
<button class="btn btn-primary btn-outlined">Button</button>
<button class="btn btn-positive btn-outlined">Button</button>
<button class="btn btn-negative btn-outlined">Button</button>

按钮的效果,btn-primary显示为蓝色,btn-positive显示为绿色,btn-negative显示为红色,btn-link显示为链接的样子。添加btn-outlined会变成只有边框,没有背景色。

Ratchet教程:自动化部署与组件概览

带图标的按钮

<button class="btn">
    <span class="icon icon-search"></span>
    Button
</button>
<button class="btn btn-primary">
    <span class="icon icon-search"></span>
    Button
</button>
<button class="btn btn-positive">
    <span class="icon icon-search"></span>
    Button
</button>
<button class="btn btn-negative">
    <span class="icon icon-search"></span>
    Button
</button>
<button class="btn btn-link">
    <span class="icon icon-left"></span>
    Button
</button>

在按钮里面放入相应的icon

Ratchet教程:自动化部署与组件概览

带提示的按钮

<button class="btn">Badge button <span class="badge">1</span></button>
<button class="btn btn-primary">Badge button <span class="badge badge-primary">1</span></button>
<button class="btn btn-positive">Badge button <span class="badge badge-positive">1</span></button>
<button class="btn btn-negative">Badge button <span class="badge badge-negative">1</span></button>

<button class="btn btn-outlined">Badge button <span class="badge badge-inverted">1</span></button>
<button class="btn btn-outlined btn-primary">Badge button <span class="badge badge-primary badge-inverted">1</span></button>
<button class="btn btn-outlined btn-positive">Badge button <span class="badge badge-positive badge-inverted">1</span></button>
<button class="btn btn-outlined btn-negative">Badge button <span class="badge badge-negative badge-inverted">1</span></button>

在按钮里面放入相应的badge

Ratchet教程:自动化部署与组件概览

块级按钮

<button class="btn btn-block">Block button</button>
<button class="btn btn-primary btn-block">Block button</button>
<button class="btn btn-positive btn-block">Block button</button>
<button class="btn btn-negative btn-block">Block button</button>

<button class="btn btn-block btn-outlined">Block button</button>
<button class="btn btn-primary btn-block btn-outlined">Block button</button>
<button class="btn btn-positive btn-block btn-outlined">Block button</button>
<button class="btn btn-negative btn-block btn-outlined">Block button</button>

添加btn-block,按钮会整行显示。

Ratchet教程:自动化部署与组件概览

标签卡切换

<div class="segmented-control">
    <a class="control-item active" href="#item1mobile">Thing one</a>
    <a class="control-item" href="#item2mobile">Thing two</a>
    <a class="control-item" href="#item3mobile">Thing three</a>
</div>
<div class="card">
    <span id="item1mobile" class="control-content active">Item 1</span>
    <span id="item2mobile" class="control-content">Item 2</span>
    <span id="item3mobile" class="control-content">Item 3</span>
</div>

control-content为切换的面板,需要添加对应的id,跟上面的锚点对应。

Ratchet教程:自动化部署与组件概览

提示按钮

<span class="badge">1</span>
<span class="badge badge-primary">2</span>
<span class="badge badge-positive">3</span>
<span class="badge badge-negative">4</span>

<span class="badge badge-inverted">1</span>
<span class="badge badge-primary badge-inverted">2</span>
<span class="badge badge-positive badge-inverted">3</span>
<span class="badge badge-negative badge-inverted">4</span>

添加badge-inverted,没有背景色。

Ratchet教程:自动化部署与组件概览

表单

<form>
    <input placeholder="Full name">
    <input placeholder="Search">
    <textarea rows="5"></textarea>
    <button class="btn btn-positive btn-block">Choose existing</button>
</form>

表单元素整行显示。

Ratchet教程:自动化部署与组件概览

输入框组

<form class="input-group">
    <input placeholder="Full name">
    <input placeholder="Email">
    <input placeholder="Username">
</form>

添加input-group,表单元素之间没有空隙。

Ratchet教程:自动化部署与组件概览

带label标签的输入框组

<form class="input-group">
    <div class="input-row">
        <label>Full name</label>
        <input placeholder="Mister Ratchet">
    </div>
    <div class="input-row">
        <label>Email</label>
        <input placeholder="ratchetframework@gmail.com">
    </div>
    <div class="input-row">
        <label>Username</label>
        <input placeholder="goRatchet">
    </div>
</form>

input-row包裹label和表单元素,一行显示。

Ratchet教程:自动化部署与组件概览

按钮切换

<div class="toggle active">
    <div class="toggle-handle"></div>
</div>
<div class="toggle">
    <div class="toggle-handle"></div>
</div>

切换按钮,默认选中添加active,切换效果需要仿真才能看到
// Only needed if you want to fire a callback document .querySelector('#myToggle') .addEventListener('toggle', myFunction)

如果需要回调,添加相应的js

Ratchet教程:自动化部署与组件概览

弹出菜单

<div id="popover" class="popover">
    <header class="bar bar-nav">
        <h1 class="title">Popover title</h1>
    </header>
    <ul class="table-view">
        <li class="table-view-cell">Item1</li>
        <li class="table-view-cell">Item2</li>
        <li class="table-view-cell">Item3</li>
        <li class="table-view-cell">Item4</li>
        <li class="table-view-cell">Item5</li>
        <li class="table-view-cell">Item6</li>
        <li class="table-view-cell">Item7</li>
        <li class="table-view-cell">Item8</li>
    </ul>
</div>

<header class="bar bar-nav">
    <a href="#popover">
        <h1 class="title">
            Tap title
            <span class="icon icon-caret"></span>
        </h1>
    </a>
</header>

只能用在标题栏,锚链接要对应popover的id,官方文档有错,效果需要仿真。
Ratchet教程:自动化部署与组件概览

对话框

<a class="btn" href="#myModalexample">Open modal</a>
<div id="myModalexample" class="modal">
    <header class="bar bar-nav">
        <a class="icon icon-close pull-right" href="#myModalexample"></a>
        <h1 class="title">Modal</h1>
    </header>

    <div class="content">
        <p class="content-padded">The contents of my modal ...</p>
    </div>
</div>

锚链接对应modal的id,效果需要仿真。

Ratchet教程:自动化部署与组件概览

点击按钮之后会有一个弹出层:

Ratchet教程:自动化部署与组件概览

滑动效果

<div id="mySlider" class="slider">
    <div class="slide-group">
        <div class="slide">
            <img src="/assets/img/slide-1.jpg">
            <span class="slide-text">
                <span class="icon icon-left-nav"></span>
                Slide me
            </span>
        </div>
        <div class="slide">
            <img src="/assets/img/slide-2.jpg">
        </div>
        <div class="slide">
            <img src="/assets/img/slide-3.jpg">
        </div>
    </div>
</div>

需要回调,添加对应的js,效果需要仿真。

// Only needed if you want to fire a callback
document
.querySelector('#mySlider')
.addEventListener('slide', myFunction)  

Ratchet教程:自动化部署与组件概览

push

切换页面的时候可以用到

<!-- A one.html link -->
<a href="two.html">Two</a>

one页面有一个页面链接到two

<a href="two.html" data-transition="fade">Two</a>

可以用data-transition属性添加动画效果

<a href="http://www.google.com" data-ignore="push">Google</a><a>

 

可以用data-ignore="push"阻止链接跳转。

// Only needed if you want to fire a callback
window.addEventListener('push', myFunction);

需要回调的时候添加相应的js。

Ratchet教程:自动化部署与组件概览

点击列表后效果:

Ratchet教程:自动化部署与组件概览

图标

<div class="content-padded">
    <span class="icon icon-back"></span>
    <span class="icon icon-bars"></span>
    <span class="icon icon-caret"></span>
    <span class="icon icon-check"></span>
    <span class="icon icon-close"></span>
    <span class="icon icon-code"></span>
    <span class="icon icon-compose"></span>
    <span class="icon icon-download"></span>
    <span class="icon icon-edit"></span>
    <span class="icon icon-forward"></span>
    <span class="icon icon-gear"></span>
    <span class="icon icon-home"></span>
    <span class="icon icon-info"></span>
    <span class="icon icon-list"></span>
    <span class="icon icon-more-vertical"></span>
    <span class="icon icon-more"></span>
    <span class="icon icon-pages"></span>
    <span class="icon icon-pause"></span>
    <span class="icon icon-person"></span>
    <span class="icon icon-play"></span>
    <span class="icon icon-plus"></span>
    <span class="icon icon-refresh"></span>
    <span class="icon icon-search"></span>
    <span class="icon icon-share"></span>
    <span class="icon icon-sound"></span>
    <span class="icon icon-sound2"></span>
    <span class="icon icon-sound3"></span>
    <span class="icon icon-sound4"></span>
    <span class="icon icon-star-filled"></span>
    <span class="icon icon-star"></span>
    <span class="icon icon-stop"></span>
    <span class="icon icon-trash"></span>
    <span class="icon icon-up-nav"></span>
    <span class="icon icon-up"></span>
    <span class="icon icon-right-nav"></span>
    <span class="icon icon-right"></span>
    <span class="icon icon-down-nav"></span>
    <span class="icon icon-down"></span>
    <span class="icon icon-left-nav"></span>
    <span class="icon icon-left"></span>
</div>

Ratchet教程:自动化部署与组件概览

总结

在这一节中,主要向大家介绍了如何布署Ratchet自动化,以及罗列出Ratchet官网目前提供的组件结构以及对应的组件效果。可以说这些组件涵盖了移动项目大部分组件。当然这些组件并不能满足每一个项目,接下来的一节中,我们一起探讨每个组件的具体使用以及覆盖方式。感兴趣的同学欢迎持续观注相关更新。

在此特别感谢@文彬同学的整理,如果大家在这方面有相关的使用经验,欢迎与我们一起分享。

关于文彬

专注于前端开发技术,熟悉html,css,jquery等技术,关注信息无障碍,用户体验,喜欢写些小demo。欢迎观注我:个人博客新浪微博

如需转载,烦请注明出处:https://www.fedev.cn/mobile/ratchet-components.html

Air Jordan Horizon AJ13