{"id":18832380,"url":"https://github.com/brainpoint/febs-ui","last_synced_at":"2025-06-28T07:35:42.900Z","repository":{"id":57234196,"uuid":"97441530","full_name":"brainpoint/febs-ui","owner":"brainpoint","description":"febs-ui is a set of common ui components","archived":false,"fork":false,"pushed_at":"2020-03-11T10:15:37.000Z","size":12100,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-29T16:51:49.413Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brainpoint.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-17T06:16:47.000Z","updated_at":"2020-03-11T10:15:39.000Z","dependencies_parsed_at":"2022-09-05T21:11:01.100Z","dependency_job_id":null,"html_url":"https://github.com/brainpoint/febs-ui","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/brainpoint/febs-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brainpoint","download_url":"https://codeload.github.com/brainpoint/febs-ui/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs-ui/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261373063,"owners_count":23148912,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T01:57:42.219Z","updated_at":"2025-06-28T07:35:42.882Z","avatar_url":"https://github.com/brainpoint.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"febs-ui 库是一些常用的ui的合集;\nfebs-ui 库依赖 febs-browser 库\n\n设计上\n\n- 可以通过修改 `febsui-icon.css`, `febsui.css` 来个性化ui样式.\n- 尽量使用js方法的方式来构建ui.\n- 默认样式为iOS样式\n\nfebs-ui 引入了febs-browser(实现了jquery的部分接口), 无需额外引入jquery;\n\n如果需要jquery, 请在febs-ui,febs之前引用\n\n可以查看 [demo](http://demo.citongs.com/febsui)\n\n# Install\n\nUse npm to install:\n\n```js\nnpm install febs-ui --save\n```\n\n# browser\n\n以下列方式使用\n\n\u003e copy directory `node_modules/febs-browser/dist/febs` to client\n\n\u003e copy directory `node_modules/febs-ui/dist/febsui` to client\n\n```html\n\u003clink rel=\"stylesheet\" type=\"text/css\" href=\"path/febsui/febsui.css\" /\u003e \u003c!-- 会自动关联 febsui-icon.css --\u003e\n\u003cscript charset='UTF-8' type=\"text/javascript\" src=\"path/febs/febs.min.js\"\u003e\u003c/script\u003e\n\u003cscript charset='UTF-8' type=\"text/javascript\" src=\"path/febsui/febsui.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\nfebsui.dialog_showToast({content:'即将开始', icon:'ok'});\n\u003c/script\u003e\n```\n\n# babel\n\n以下列方式使用\n\n```js\nimport febs from 'febs-browser'; // or 'febs'\nimport febsui from 'febs-ui';\nimport 'febs-ui/febsui.css';  // 或是在html头部引用样式.\n\n//\nfebsui.dialog_showToast({content:'即将开始', icon:'ok'});\n```\n\n# framework\n\n目前实现了如下控件.\n\n  - [jquery extend](#extend)\n  - [css](#css)\n  - [button](#button)\n  - [loading](#loading)\n  - [toast](#toast)\n  - [alert dialog](#dialog)\n  - [confirm dialog](#dialog)\n  - [edit dialog](#dialog)\n  - [custom dialog](#custom-dialog)\n  - [paging](#page)\n  - [switch](#switch)\n  - [checkbox](#checkbox)\n  - [radio](#radio)\n  - [swiper](#swiper)\n  - [popover](#popover)\n  - [actionSheet](#actionsheet)\n  - [upload](#upload)\n\n### extend\n\n引入了 如下几个jquery插件方法. (febsui无需额外使用jquery库)\n\n```js\n\n/**\n * @desc 设置为disable (对input, button等元素有效).\n */\n$('').setDisabled(isDisable);\n\n/**\n * @desc 返回当前控件是否为disable状态.\n */\n$('').isDisabled();\n/**\n * @desc 判断第一个元素是否可见.\n */\n$('').isVisible();\n/**\n * @desc 判断是否存在可见元素.\n */\n$('').hasVisible();\n\n```\n\n### initial ui\n\n对于非js调用创建的ui, 在编辑好html标签代码后, 需要调用相应的初始化方法进行控件初始化.\n\n页面加载完成`ready`事件触发后, 会自动调用一次初始化方法; 当如果在后续进行dom的修改添加新控件时, 需要手动调用初始化方法.\n\n\n\n特殊的事件处理方式.\n\n```js\n/**\n* @desc: 阻止在elem上的move或touchmove事件.\n*/\nfebsui.preventEvent(elem:any):void;\n```\n\n初始化方法列表\n\n```js\n/**\n* @desc: 对页面上所有类型的ui控件进行初始化.\n*/\nfebsui.ui_init();\n\n/**\n * @desc 初始化页面上所有swiper控件\n *       默认在页面加载完成时会调用一次; 加入新的swiper控件时需调用一次.\n */\nfebsui.ui_swiper_init(elem?:any);\n\n/**\n * @desc 初始化页面上所有switch控件\n *       默认在页面加载完成时会调用一次; 加入新的switch控件时需调用一次.\n */\nfebsui.ui_switch_init(elem?:any);\n\n/**\n * @desc 初始化页面上所有checkbox控件 (带 febsui-checkbox 类的控件)\n *       默认在页面加载完成时会调用一次; 加入新的checkbox控件时需调用一次.\n */\nfebsui.ui_checkbox_init(elem?:any);\n\n/**\n * @desc 初始化页面上所有radio控件 (带febsui-radio类的控件)\n *       默认在页面加载完成时会调用一次; 加入新的radio控件时需调用一次.\n */\nfebsui.ui_radio_init(elem?:any);\n/**\n* @desc: 初始化popover控件.\n*        对页面上 的所有 \u003cpopover\u003e 元素进行初始化.\n*        在增加新的popover到页面后, 需要手动调用此方法.\n*/\nfebsui.ui_popover_init(elem?:any);\n\n/**\n* @desc: 初始化actionSheet控件.\n*        对页面上 的所有 \u003cactionsheet\u003e 元素进行初始化.\n*        在增加新的actionsheet到页面后, 需要手动调用此方法.\n*/\nfebsui.ui_actionSheet_init(elem?:any);\n/**\n* @desc: 初始化dialog控件.\n*        对页面上 的所有 \u003cdialog\u003e 元素进行初始化.\n*        在增加新的dialog到页面后, 需要手动调用此方法.\n*/\nfebsui.ui_dialog_init(elem?:any):void;\n/**\n* @desc: 初始化uploader控件.\n*        对页面上 的所有 \u003cuploader\u003e 元素进行初始化.\n*        在增加新的uploader到页面后, 需要手动调用此方法.\n*/\nfebsui.ui_uploader_init(elem?:any):void;\n/**\n* @desc: 用于解决ie9下不支持css:animation; 初始化\u003cdiv class=\"febsui-icon-spin1/febsui-icon-spin1-white\"\u003e控件.\n*/\nfebsui.ui_spin_init(elem?:any):void;\n/**\n* @desc: 对所有的button控件进行初始化, 保证移动端touch穿透体验.\n*/\nfebsui.ui_button_init(elem?:any):void;\n```\n\n\n调用ui初始化方法之后, 会对html元素结构进行操作后初始化事件. 如果需要手动设置初始化事件, 可以调用如下方法.\n\n```js\n\n/**\n * @desc 对元素进行事件初始化.\n * @param elem: 已经是完整的样式. \n */\nfebsui.ui_swiper_init_event(elem:selector);\n\n/**\n * @desc 对元素进行事件初始化.\n * @param elem: 已经是完整的样式. \n */\nfebsui.ui_switch_init_event(elem:selector);\n\n/**\n * @desc 对元素进行事件初始化.\n * @param elem: 已经是完整的样式. \n */\nfebsui.ui_checkbox_init_event(elem:selector);\n\n/**\n * @desc 对元素进行事件初始化.\n * @param elem: 已经是完整的样式. \n */\nfebsui.ui_radio_init_event(elem:selector);\n\n/**\n * @desc 对元素进行事件初始化.\n * @param elem: 已经是完整的样式. \n */\nfebsui.ui_button_init_event(elem:selector):void;\n```\n\n### css\n\n| 类 | 说明 |\n|----|----|\n| febsui-ellipsis | 单行文字缩略. |\n| febsui-ellipsis-multiline | 多行文字缩略. 默认4行; 修改 -webkit-line-clamp: 4; line-clamp: 4; 自定义 |\n| febsui-visible | 设置为 visibility: visible; febsui-visible与febsui-invisible 之间切换有渐变效果 |\n| febsui-invisible | 设置为 visibility: hidden; febsui-visible与febsui-invisible 之间切换有渐变效果 |\n\n\n\n### button\n\n![](doc/ui/control-button.png)\n\n```html\n  \u003cbutton \u003edefault\u003c/button\u003e\n  \u003cbutton class=\"btn-primary\"\u003eprimary\u003c/button\u003e\n  \u003cbutton class=\"btn-secondary\"\u003esecondary\u003c/button\u003e\n  \u003cbutton class=\"btn-warning\"\u003ewarning\u003c/button\u003e\n  \u003cbutton class=\"btn-danger\"\u003edanger\u003c/button\u003e\n  \u003cbutton class=\"btn-primary\" disabled=\"disabled\" onclick=\"console.log(23123);\"\u003edisabled\u003c/button\u003e\n```\n\n\n### loading\n\n已经对需要显示的信息进行了转义\n\n![](doc/ui/control-loadding.png)\n\n```js\n/**\n* @desc: 当前是否显示.\n* @return boolean.\n*/\nfebsui.loading_isVisiable()\n```\n\n```js\n/**\n* @desc: 使用延时显示加载框.\n* @param text: 提示文本.\n* @param timeout: 延时显示, 默认为0.\n* @param spinClass: 默认为 febsui-icon-spin1-white ; ie9以下浏览器使用 febsui-icon-spin3-white\n* @param spinLeft: 是否在左侧显示spin.\n* @param whiteBg: 使用白色背景\n* @return: \n*/\nfebsui.loading_show(text, timeout, spinClass, spinLeft, whiteBg)\n\n/**\n* @desc: 通过每500ms改变文本的方式显示加载框; 例如显示 3,2,1,3,2,1循环显示.\n* @param textArray: 变化的文本数组.\n* @param changeTextCB: 当前显示文本的回调. function(text).\n* @param hideCB:  隐藏加载框时的设置文本的函数. function().\n* @return: \n*/\nfebsui.loading_show_text(textArray, changeTextCB, hideCB) \n\n/**\n* @desc: 隐藏加载对话框\n* @return: \n*/\nfebsui.loading_hide()\n```\n\n使用如下代码可以创建spin动画.\n\n```html\n\u003chtml\u003e\n\n\u003cdiv class=\"febsui-icon febsui-icon-spin1\"\u003e\u003c/div\u003e\n\u003cdiv class=\"febsui-icon febsui-icon-spin1-white\"\u003e\u003c/div\u003e\n\n\u003c/html\u003e\n```\n\n### toast\n\n已经对需要显示的信息进行了转义\n\n![](doc/ui/control-toast.png)\n\n\n```js\n/**\n * @desc: 显示提示.\n * @param ctx: {\n  * ctx.title:    标题.\n  * ctx.durable:\t持续的时间 ms.\n  * ctx.icon: 前置图标.\n  * ctx.callback: function(){}\t// 对话框消失后的回调.\n  * ctx.center: 默认为false; 是否使用居中的显示方式.\n  * }\n  *  or string.\n  */\nfebsui.toast( ctx );\n/**\n* @desc 手动隐藏toast.\n*/\nfebsui.toast_hide();\n```\n\n### dialog\n\n已经对需要显示的信息进行了转义\n\n![](doc/ui/control-dialog.png)\n\n![](doc/ui/control-confirm.png)\n\n\n```js\n/**\n* @desc: 隐藏对话框\n* @param selector: 关闭指定的窗口; null则关闭所有.\n* @param finishCb: 完成时的回调.\n* @return: \n*/\nfebsui.dialog_hide(selector?: any, finishCb?:()=\u003e{}): void;\n\n/**\n * @desc: 显示警告对话框. (回调函数的上下文为当前窗口)\n * @param ctx: {\n * ctx.cssClass: 自定义的扩展样式.\n* ctx.blackBg:  使用黑色背景.\n* ctx.title:    标题.\n* ctx.content:\t内容文字.\n* ctx.contentHtml: html格式的内容 (与content二选一)\n* ctx.confirm: function(){}\t// 点击确认键的回调.\n* ctx.okText\n* }\n*  or string.\n*/\nfebsui.dialog_showAlert( ctx );\n\n/**\n * @desc: 显示确认对话框. (回调函数的上下文为当前窗口)\n * @param ctx: {\n * ctx.cssClass: 自定义的扩展样式.\n* ctx.blackBg:  使用黑色背景.\n* ctx.title:    标题.\n* ctx.content:\t内容文字.\n* ctx.contentHtml: html格式的内容 (与content二选一)\n* ctx.confirm: function(){}\t// 点击确认键的回调.\n* ctx.cancel: function(){}\t// 点击取消键的回调.\n* ctx.okText 确认按钮文字\n* ctx.cancelText: 取消按钮文字\n* }\n*/\nfebsui.dialog_showConfirm( ctx );\n\n  /**\n   * @desc: 显示文本输入确认对话框. (回调函数的上下文为当前窗口)\n   * @param ctx: {\n  * ctx.cssClass: 自定义的扩展样式.\n  * ctx.blackBg:  使用黑色背景.\n  * ctx.title:    标题.\n  * ctx.content:\t\t 内容文字.\n  * ctx.contentHtml: html格式的内容 (与content二选一)\n  * ctx.editText:\t\t 输入框文字.\n  * ctx.confirm: function(text){}\t// 点击确认键的回调.\n  * ctx.cancel:  function(){} // 点击取消键的回调.\n  * ctx.okText:\n  * ctx.cancelText:\n  * }\n  */\nfebsui.dialog_showConfirmEdit( ctx );\n```\n\n### page\n![](doc/ui/control-page.jpg)\n```js\n/**\n* @desc: 初始化page控件.\n* @param elem: 将控件插入到elem中, elem是一个jquery的对象.\n* @param curPage: 当前页\n* @param pageCount: 总页数\n* @param totalCount: 总条数\n* @param pageCallback: 页面跳转函数, function(page) {}\n* @return: \n*/\nfebsui.page_init(elem, curPage, pageCount, totalCount, pageCallback)\n\n```\n\n### custom dialog\n\n可以自行定义dialog的内容\n\n```html\n\n\u003cdiv class=\"febsui-dialog\" id=\"dialog1\" data-mask-close=\"true\"\u003e\n  \u003cdiv class=\"febsui-dialog-title\"\u003e标题\u003c/div\u003e\n  \u003cdiv class=\"febsui-dialog-content\" style=\"width: 100px; height:400px;\"\u003e\n    ...\n  \u003c/div\u003e\n  \u003cul class=\"febsui-dialog-buttons\"\u003e\n    \u003cli style=\"\"\u003e\u003cbutton class=\"febsui-dialog-cancel\"\u003e取消\u003c/button\u003e\u003c/li\u003e\n    \u003cli style=\"\"\u003e\u003cbutton class=\"febsui-dialog-ok\"\u003e确认\u003c/button\u003e\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/div\u003e\n\n```\n\n\u003e must provide a `id` attrubute\n\n\u003e 将为自定义dialog元素添加一个 `'id-'+元素id` 的类; 对自定义dialog样式设定时, 使用这个类名, 而不要使用id来定义\n\n\u003e 在页面中查找dialog可以使用 `$('.id-元素id')` 或 `$('.febsui-dialog[data-id=\"元素id\"]')` 来查找\n\n属性\n\n| 属性 | 说明 | 值 |\n|----|----|----|\n| data-mask-close | 表明点击空白处是否关闭对话框. (默认false) | 允许的值为: true, false  |\n| data-mask-zindex | dialog 的父mask层的 z-index | 默认值为 20000  |\n\n\n方法\n\n```js\n/**\n * @desc 判断是否是popover\n */\n$('.febsui-dialog').isDialog();\n/**\n * @desc 显示dialog\n */\n$('.febsui-dialog').dialogShow(cb:()=\u003e{});\n\n/**\n * @desc 隐藏dialog;\n */\n$('.febsui-dialog').dialogHide(cb:()=\u003e{});\n```\n\n\n\n### switch\n![](doc/ui/control-switch.png)\n\n示例\n\n```html\n\u003chtml\u003e\n\n\u003c!-- 默认是on状态. --\u003e\n\u003cdiv class=\"febsui-switch\"\u003e\u003c/div\u003e \n\u003cdiv class=\"febsui-switch febsui-switch-on\"\u003e\u003c/div\u003e \n\n\u003c!-- off状态. --\u003e\n\u003cdiv class=\"febsui-switch febsui-switch-off\"\u003e\u003c/div\u003e \n\n\u003c!-- disabled状态. --\u003e\n\u003cdiv class=\"febsui-switch febsui-switch-disabled\"\u003e\u003c/div\u003e \n\n\u003c/html\u003e\n```\n\n类\n\n| 类名| 说明 |\n|----|----|\n| febsui-switch-on |  此类表示switch为on状态.  |\n| febsui-switch-off |  此类表示switch为off状态.  |\n\n\n方法\n\n```js\n/**\n * @desc 判断是否是switch\n */\n$('.febsui-switch').isSwitch();\n/**\n * @desc 监听变化事件\n */\n$('.febsui-switch').switch(function(){\n  // \n});\n\nor\n\n$('.febsui-switch').on('switch', function(){});\n\n\n/**\n * @desc 手动触发事件\n */\n$('.febsui-switch').switch();\n\nor\n\n$('.febsui-switch').on('switch');\n\n/**\n * @desc 改变状态\n * @param isOn: 设置控件的状态.\n * @param trigger: 可选, 是否触发事件监听 (状态未改变不触发).\n */\n$('.febsui-switch').switchOn(isOn, trigger);\n\n/**\n * @desc 返回当前控件的状态.\n */\n$('.febsui-switch').switchIsOn();\n```\n\n\n### checkbox\n![](doc/ui/control-checkbox.png)\n\n示例\n\n```html\n\u003chtml\u003e\n\n\u003cinput id=\"checkbox1\" type=\"checkbox\" class=\"febsui-checkbox\"\u003e\n\u003clabel for=\"checkbox1\"\u003echeckbox\u003c/label\u003e\n\n\u003c/html\u003e\n\n\u003cscript\u003e\n\n//\n// 原生用法.\n//\n\n// get checked.\n$('#checkbox1')[0].checked;\n// set checked.\n$('#checkbox1')[0].checked = true;\n\n//\n// febsui 用法.\n//\n\n// get value.\n$('#checkbox1').checkboxChecked();\n// set value.\n$('#checkbox1').checkboxChecked(true);\n\n\u003c/script\u003e\n\n\u003c/html\u003e\n```\n\n方法\n\n```js\n/**\n * @desc 判断是否是checkbox\n */\n$('.febsui-checkbox').isCheckbox();\n/**\n * @desc 设置当前checkbox的checked状态.\n * @param checked: 当参数不存在时返回是否是checked状态. 否则设置checked状态.\n * @return 当获取checked状态时返回 boolean; 当设置状态时返回dom.\n */\n$('.febsui-checkbox').checkboxChecked(checked?:boolean, trigger?:boolean);\n/**\n * @desc 监听变化事件\n */\n$('.febsui-checkbox').on('change', function(){});\n\n```\n\n\n\n### radio\n\nradio 同checkbox一样使用.\n\n```html\n\u003chtml\u003e\n\n\u003cinput name=\"radio\" id=\"radio1\" type=\"radio\" value=\"male\" class=\"febsui-radio\" checked\u003e\n\u003clabel for=\"radio1\"\u003emale\u003c/label\u003e\n\n\u003cinput name=\"radio\" id=\"radio2\" type=\"radio\" value=\"female\" class=\"febsui-radio\"\u003e\n\u003clabel for=\"radio2\"\u003efemale\u003c/label\u003e\n\n\u003cscript\u003e\n\n//\n// 原生用法.\n//\n\n// get value.\n$('input[name=\"radio\"]:checked').val()\n// set value.\n$('#radio2')[0].checked = true;\n\n//\n// febsui 用法.\n//\n\n// get value.\n$('#radio1').radioGetValue();\n// set value.\n$('#radio1').radioSetValue('male'); or $('#radio1').radioChecked(true);\n\n\u003c/script\u003e\n\n\u003c/html\u003e\n```\n\n方法\n\n```js\n/**\n * @desc 判断是否是radio\n */\n$('.febsui-radio').isRadio();\n/**\n * @desc 获得radio组当前值.\n */\n$('.febsui-radio').radioGetValue();\n/**\n * @desc 设置radio组当前值.\n */\n$('.febsui-radio').radioSetValue(value:string, trigger?:boolean);\n/**\n * @desc 设置当前radio的checked状态.\n * @param checked: 当参数不存在时返回是否是checked状态. 否则设置checked状态.\n * @return 当获取checked状态时返回 boolean; 当设置状态时返回dom.\n */\n$('.febsui-radio').radioChecked(checked?:boolean, trigger?:boolean);\n/**\n * @desc 监听变化事件\n */\n$('input[name=\"radioGroup\"]').on('change', function(){});\n\n```\n\n### swiper\n\n跑马灯效果\n\n示例\n\n```html\n\u003chtml\u003e\n\n\u003cdiv class=\"febsui-swiper\" style=\"height: 80px;\" data-loop=\"true\" data-current=\"2\" data-dot-color=\"#000000\"\u003e\n  \u003cdiv class=\"febsui-swiper-page\" style=\"background-color: #ff0000;\"\u003e1\u003c/div\u003e\n  \u003cdiv class=\"febsui-swiper-page\" style=\"background-color: #00ff00;\"\u003e2\u003c/div\u003e\n  \u003cdiv class=\"febsui-swiper-page\" style=\"background-color: #ff00ff;\"\u003e3\u003c/div\u003e\n  \u003cdiv class=\"febsui-swiper-page\" style=\"background-color: #0000ff;\"\u003e4\u003c/div\u003e\n\u003c/div\u003e\n\n\u003c/html\u003e\n```\n\n\u003e 垂直模式, 默认仅将touch事件在swiper内有效, 即不会引起父控件滚动.\n\n\u003e swiper page 之间不能有margin等空隙; 需要空隙在内部的div中实现.\n\n类\n\n`febsui-swiper-vertical` : 可以设置为垂直滚动样式.\n\n属性\n\n| 属性 | 说明 | 值 |\n|----|----|----|\n| data-current | 表明当前显示的页面 | 允许的值为: 整数索引位置  |\n| data-dots |  表明是否显示当前页指示器; (默认 true) | 允许的值: true, false  |\n| data-loop |  表明是否允许循环显示. (默认 true)  | 允许的值: true, false  |\n| data-dot-color |  指示器颜色  | 例如: #ffffff  |\n| data-auto |  自动切换动画; 如果存在则会在指定时间内自动切换动画. 其他非数值值将默认为 7000; 改变此属性后, 动画速度会改变, 但不可从0(禁止)变为动画.  | 例如: 3000  |\n| data-align | 指明当前page在页面中的对齐方式, (默认 center) | 允许的值: 'center', 偏移像素数值 |\n\n\n方法\n\n```js\n/**\n * @desc 判断是否是swiper\n */\n$('.febsui-swiper').isSwiper();\n\n/**\n * @desc 设置指示器颜色.\n */\n$('.febsui-swiper').swiperDotColor(color);\n\n/**\n * @desc 设置动画速度, ms为下一次变换的间隔时间, 0则无动画.\n *      如果当前为0, 则无效.\n */\n$('.febsui-swiper').swiperSpeed(ms);\n\n/**\n * @desc 获取当前页面索引.\n */\n$('.febsui-swiper').swiperCurrent();\n\n/**\n * @desc 移动到前一页.\n * @param trigger: 是否触发事件 (默认false).\n */\n$('.febsui-swiper').swiperPre(trigger?:boolean);\n\n/**\n * @desc 移动到后一页.\n * @param trigger: 是否触发事件 (默认false).\n */\n$('.febsui-swiper').swiperNext(trigger?:boolean);\n\n/**\n * @desc 移动到指定页.\n * @param index: 页索引.\n * @param animation: 是否存在动画 (默认true).\n * @param trigger: 是否触发事件 (默认false).\n */\n$('.febsui-swiper').swiperTo(index:number, animation?:boolean, trigger?:boolean);\n\n/**\n * @desc 返回总共多少页.\n */\n$('.febsui-swiper').swiperTotal();\n```\n\n事件\n\n```js\n\n/**\n * @desc (特殊方法) 正在进行手动移动监听. 传入null方法则取消回调.\n * @param percent: 移动到下一个page的百分比; 负数表示移到到上一个page.\n */\n$('.febsui-swiper').swiperMoving(function(percent){});\n\n/**\n * @desc 监听变化事件\n */\n$('.febsui-swiper').swiper(function(){});\n\nor\n\n$('.febsui-swiper').on('swiper', function(){});\n\n/**\n * @desc 手动触发事件\n */\n$('.febsui-swiper').swiper();\n\nor\n\n$('.febsui-swiper').trigger('swiper');\n```\n\n### popover\n![](doc/ui/control-popover.png)\n\n示例\n\n```html\n\u003chtml\u003e\n\n\u003c!-- 使用 top, left 样式来指定位置 --\u003e\n\u003cdiv class=\"febsui-popover\" id=\"popover1\" style=\"top:50px; left:50px;\"\u003e\n  \u003cdiv class=\"febsui-popover-cell\"\u003ecell1\u003c/div\u003e\n  \u003cdiv class=\"febsui-popover-cell\"\u003ecell2\u003c/div\u003e\n  \u003cdiv class=\"febsui-popover-cell\"\u003ecell3\u003c/div\u003e\n\u003c/div\u003e\n\n\u003c!-- 使用 data-attach 来固定位置到指定元素 --\u003e\n\u003cdiv class=\"febsui-popover\" id=\"popover\" data-attach=\"#popoverAttach\" data-direction=\"bottom\" data-offset=\"5\"\u003e\n  \u003c!-- {{ children nodes }} --\u003e\n\u003c/div\u003e\n\u003cbutton id=\"popoverAttach\" onclick=\"$('#popover').popoverShow();\"\u003eshow\u003c/button\u003e\n\n\u003c/html\u003e\n```\n\n\u003e must provide a `id` attrubute\n\n\u003e 将为popover元素添加一个 `'id-'+元素id` 的类; 对popover样式设定时, 使用这个类名, 而不要使用id来定义\n\n\u003e 在页面中查找popover可以使用 `$('.id-元素id')` 或 `$('.febsui-popover[data-id=\"元素id\"]')` 来查找\n\n属性\n\n| 属性 | 说明 | 值 |\n|----|----|----|\n| data-direction | 表明popover的方向. (默认为auto) | 允许的值为: left, right, top, bottom, center, auto  |\n| data-offset |  表明提示位置(三角尖)的偏移像素. (auto时忽略此数值) | 允许的值: 只能为数值  |\n| data-attach |  表明显示时自动显示在此元素的指定位置.  | 例如: #btn1  |\n| data-blackBg |  是否使用黑色背景  | 允许的值: true, false  |\n\n方法\n\n```js\n/**\n * @desc 判断是否是popover\n */\n$('#popover1').isPopover();\n/**\n * @desc 显示popover\n * @param mask 是否显示掩码背景.\n * @param attachNode 附加到此节点上显示. 如果不存在, 则查询 data-attach 属性.\n */\n$('#popover1').popoverShow(mask?:boolean, attachNode?:selector);\n\n/**\n * @desc 隐藏popover; 显示后点击也会隐藏.\n */\n$('#popover1').popoverHide();\n```\n\n### actionsheet\n\n![](doc/ui/control-actionsheet.png)\n\n示例\n\n```html\n\u003chtml\u003e\n\n\u003cdiv class=\"febsui-actionsheet\" id=\"actionsheet1\"\u003e\n  \u003cdiv class=\"febsui-actionsheet-cell\"\u003ecell1\u003c/div\u003e\n  \u003cdiv class=\"febsui-actionsheet-cell\"\u003ecell2\u003c/div\u003e\n\n  \u003cdiv class=\"febsui-actionsheet-cancel\"\u003eCANCEL\u003c/div\u003e\n\u003c/div\u003e\n\n\u003c/html\u003e\n```\n\n\u003e must provide a `id` attrubute\n\n\u003e 将为actionsheet元素添加一个 `'id-'+元素id` 的类; 对actionsheet样式设定时, 使用这个类名, 而不要使用id来定义\n\n\u003e 在页面中查找actionsheet可以使用 `$('.id-元素id')` 或 `$('.febsui-actionsheet[data-id=\"元素id\"]')` 来查找\n\n类\n\n| 类名| 说明 |\n|----|----|\n| febsui-actionsheet-cell |  正常的单元格  |\n| febsui-actionsheet-cancel |  底部cancel的单元格  |\n\n属性\n\n\n| 属性名 | 说明 | 取值  |\n|----|----|-----|\n| data-blackBg |  是否使用黑色背景  | 允许的值: true, false  |\n\n方法\n\n```js\n/**\n * @desc 判断是否是actionsheet\n */\n$('#actionsheet1').isActionsheet();\n/**\n * @desc 显示actionsheet\n */\n$('#actionsheet1').actionsheetShow();\n\n/**\n * @desc 隐藏actionsheet; 显示后点击也会隐藏.\n */\n$('#actionsheet1').actionsheetHide();\n```\n\n\n### upload\n\n![](doc/ui/control-uploader.png)\n\n示例\n\n```html\n\u003chtml\u003e\n  \u003cdiv class=\"febsui-uploader\" data-api=\"/upload\" \n         data-accept=\"application/zip\" \n       data-filename=\"true\" \n          data-begin=\"onUploadBegin\"\n         data-finish=\"febsui.dialog_showAlert('upload ok')\"\n         data-progress=\"onUploadProgress\"\n         data-error=\"onUploadError\"\n         data-multiple=\"true\"\u003e上传图片\u003c/div\u003e\n  \n  \u003cscript\u003e\n    function onUploadBegin(uploaderController, filename) {\n      uploaderController.abort(); // abort uploader.\n    }\n\n    function onUploadProgress(percent) {\n      console.log(percenter);\n    }\n\n    function onUploadError(err) {\n      console.log(err);  \n    }\n  \u003c/script\u003e\n\n\u003c/html\u003e\n```\n\n或使用 `on` 方式绑定事件.\n\n```js\n\n$('.febsui-uploader').on('uploadBegin', function(event, data) {\n  console.log(data.filename); // 文件名.\n});\n$('.febsui-uploader').on('uploadProgress', function(event, data) {\n  console.log(data.progress); // 进度.\n});\n$('.febsui-uploader').on('uploadError', function(event, data) {\n  console.log(data.err); // 错误信息.\n});\n$('.febsui-uploader').on('uploadFinish', function(event, data) {\n  console.log(data.responseData); // 服务器返回的数据.\n});\n\n```\n\n属性\n\n| 属性 | 说明 | 值 |\n|----|----|----|\n| data-api | 上传文件的api地址 |   |\n| data-accept |  接受文件的类型 | (可选) MIME_type值  |\n| data-filename |  是否显示选中的文件名  | (可选) true |\n| data-begin | 上传开始的回调  | (可选) function(uploader, filename) {} |\n| data-finish | 上传成功的回调  | (可选) function(uploader, serverData) {} |\n| data-progress | 上传进度的回调  | (可选) function(uploader, percent) {} |\n| data-error | 上传错误的回调  | (可选) function(uploader, err) {}; err可能的值有:  \u003cbr\u003e febsui.uploadErr.nofile - 未选择文件\u003cbr\u003e febsui.uploadErr.sizeExceed - 文件太大\u003cbr\u003e febsui.uploadErr.crc32 - 计算本地文件hash值时错误\u003cbr\u003e febsui.uploadErr.net - ajax上传时出错\u003cbr\u003e 其他 |\n| data-maxsize | 最大的文件字节大小 | (可选) 10240 |\n| data-multiple | 是否多选 | (可选) false / true |\n| data-timeout | 发送的timeout; ms | (可选) 5000 |\n\n事件.\n\n| 事件名 | 说明 | 参数 |\n|----|----|----|\n| uploadBegin | 上传开始的回调 |  event, {filename:string}  |\n| uploadProgress |  上传进程的回调 |  event, {progress:number}  |\n| uploadError |  上传错误的回调 |  event, {err:any}  |\n| uploadFinish |  上传完成的回调 |  event, {responseData:any}  |\n\n\n\n\n方法\n\n```js\n/**\n * @desc 重设为未开始上传的样式\n */\n$('.febsui-uploader').uploaderReset();\n```\n\n\n上传控件配合 `febs` 库使用. js的使用方式为:\n\n\u003e 如果是ie9以下浏览器, 服务器返回的数据时, 需要把响应头的content-type的值设为`text/plain`或者`text/html`; 否则会出现提示保存文件. \n\n#### multipart/form-data方式上传.\n\n```js\n/**\n * Desc:\n *      upload控件使用一个接口来上传文件, 使用multpart/form-data方式传输:\n *          1. uploadUrl: 上传文件.\n * Example:\n *      前台引入:\n *          1. 在需要upload的页面上使用如下语句:\n *                \u003cform method=\"post\" role=\"form\" enctype=\"multipart/form-data\" id=\"fileForm\"\u003e\n *                  \u003cinput type=\"file\" class=\"form-control\" name=\"file\" onchange=\"febsui.upload(cfg)\" multiple\u003e\n *                  \u003cinput type=\"submit\" value=\"提交\"\u003e \u003c!-- ie9以下浏览器需要提供此元素 --\u003e\n *                \u003c/form\u003e\n *      后台:\n *          1. 在uploadUrl中调用  await require('febs').controls.upload.accept(app, conditionCB); 当满足条件时将存储, 并返回true表示成功.\n */\n\n 客户端调用如下接口上传文件.\n /** \n  * 并且 \u003cinput type=\"file\" name=\"file\"... 中, 必须存在name属性.\n  * 使用post方式上传文件.\n  * @param cfg:  object, 其中\n  *              {\n  *                data:       , // 上传到服务器的任意字符串数据.\n  *                formObj:    , // 含有enctype=\"multipart/form-data\"的form\n  *                fileObj:    , // form中的file对象\n  *                fileIndex:  , // 选中的file文件的索引; 默认为0;\n  *                uploadUrl:  , // 上传文件内容的url. 系统将自动使用 uploadUrl?crc32=\u0026size=的方式来上传.\n  *                maxFileSize:    , // 允许上传的最大文件.0表示无限制.默认为0\n  *                fileType:     , // 允许的文件类型.  如: image/gif,image/jpeg,image/x-png\n  *                beginCB:     , // 上传开始的回调. function(uploader); 调用uploader.abort() 可以停止上传.\n  *                finishCB:    , // 上传完成后的回调. function(err, fileObj, serverData, xhr=null)\n *                               //                   err:  - febsui.uploadErr.nofile      未选择文件.\n *                               //                         - febsui.uploadErr.sizeExceed  文件太大.\n *                               //                         - febsui.uploadErr.crc32       计算本地文件hash值时错误.\n *                               //                         - febsui.uploadErr.net         ajax上传时出错.\n  *                               //                   serverData: 服务器返回的数据.\n  *                progressCB:  , // 上传进度的回调. function(fileObj, percent),\n  *                headers: {     // 设置request headers\n  *                  'customHeader': 'value'\n  *                },\n  *                crossDomain: true,     // 跨域, 默认为true\n  *                withCredentials: true, // 是否附带cookie, 默认为true\n  *                checkoutCrc32: true,   // 是否上传 crc32,size,ajaxmark(防止chrome优化) 三个参数.\n  *                timeout: 5000,         // 上传超时时间.\n  *                sliceOffset: 0,       // 上传数据偏移地址. (ie9及以下不支持).\n  *                sliceLength: -1,     // 上传数据段长度 (-1表示到结尾). (ie9及以下不支持).\n  *              }\n  */\n febsui.upload(cfg);\n```\n\u003e 使用 sliceOffset, sliceLength 字段可以进行断点续传.\n\n\u003e 上传完成后, 如果需要清空文件选择框, 调用 ctx.fileObj.value=\"\"\n\n例子\n后台:\n```js\nexports.upload = async function(ctx, next)\n{\n  var r = await require('febs').controls.upload.accept(ctx, async function(data, filesize, filename, filemimeType){\n    console.log(filesize);\n    console.log(filename);\n    console.log(filemimeType);\n\n    return 'tempPath/temp.filename';\n  });\n};\n\n```\n前台:\n```js\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/febs/febs.min.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/febsui/febsui.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript type=\"text/javascript\"\u003e\nfunction upload() {\n  febsui.upload({\n    formObj:  $('#fileForm'),\n    fileObj:  $(\"#filec\"),\n    uploadUrl:  '/uploadFile',\n    finishCB: function(err, fileObj, serverData){\n      console.log(serverData);\n    },\n    progressCB: function(fileObj, percent){\n      console.log(percent);\n    })\n  });\n}\n\u003c/script\u003e\n\n\u003cform method=\"post\" role=\"form\" enctype=\"multipart/form-data\" id=\"fileForm\"\u003e\n  \u003cinput id=\"filec\" type=\"file\" name=\"file\" onchange=\"javascript:upload()\" multiple\u003e\n\u003c/form\u003e\n```\n\n#### base64方式上传.\n\n客户端调用如下接口上传文件.\n```js\n/**\n * post方式上传文件.\n * 使用文件流片段的方式. 每个片段进行验证.速度稍慢\n * @param cfg:  object, 其中\n *              {\n *                data:       , // 上传到服务器的任意字符串数据,将在发送请求时发送.\n *                fileBase64Str:  , // 文件的base64格式字符串\n *                headerUrl:  , // 上传开始前的header请求地址.\n *                uploadUrl:  , // 上传文件内容的url.\n *                chunkSize:  1024*20,  // 每次上传的块大小.默认20kb\n *                beginCB:     , // 上传开始的回调. function(uploader); 调用uploader.abort() 可以停止上传.\n *                finishCB:    , // 上传完成后的回调. function(err, serverData)\n *                               //                   err:  - febsui.uploadErr.nofile      未选择文件.\n *                               //                         - febsui.uploadErr.sizeExceed  文件太大.\n *                               //                         - febsui.uploadErr.crc32       计算本地文件hash值时错误.\n *                               //                         - febsui.uploadErr.net         ajax上传时出错.\n *                               //                   serverData: 服务器返回的数据. 至少包含一个filename\n *                progressCB:  , // 上传进度的回调. function(percent)\n *              }\n */\nfebsui.uploadBase64(cfg);\n```\n\n例子\n后台:\n```js\n// 处理上传请求.\nexports.uploadByBase64Header = async function (ctx) {\n    await febsui.uploadBase64.acceptHeader(ctx, \n      async function(data, filesize){\n          return \"/tmp/filename.jpg\";\n      }, function(data){ // set upload sessoin info.\n          ctx.session.uploadSegInfo = data;\n      });\n}\n\n// 处理上传片段.\nexports.uploadByBase64 = async function (ctx) {\n    await febsui.uploadBase64.accept(ctx, \n      async function(filename){\n          var img = sharp(filename);\n          var info = await img.metadata();\n          return febs.utils.mergeMap(errCode.OK, { width: info.width, height: info.height });\n      }, function(){  // get upload session info.\n          return ctx.session.uploadSegInfo;\n      }, function(data){ // set upload sessoin info.\n          ctx.session.uploadSegInfo = data;\n      }, function() {  // clear upload session info.\n          ctx.session.uploadSegInfo = undefined;\n      });\n}\n```\n前台:\n```js\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/febs/febs.min.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/febsui/febsui.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript type=\"text/javascript\"\u003e\n  febsui.uploadBase64({\n      data: {msg :'这是一个用户数据'},\n      fileBase64Str: base64Imagestr,\n      headerUrl: '/api/mgr/uploadimgByBase64Header',\n      uploadUrl: '/api/mgr/uploadimgByBase64',\n      finishCB: function(err, serverData) {\n        if (err) {\n          console.log('err: ');\n          console.log(err);\n          console.log(serverData);\n        }\n        else {\n          console.log('finish: ');\n          console.log(serverData);\n        }\n      },\n      progressCB: function(percent) {\n        console.log(Math.ceil(percent*100)+'%');\n      }\n    });\n\u003c/script\u003e\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrainpoint%2Ffebs-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrainpoint%2Ffebs-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrainpoint%2Ffebs-ui/lists"}