Greasy Fork is available in English.
页面侧边抽屉组件
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/516282/1479802/Drawer_gz%E9%A1%B5%E9%9D%A2%E4%BE%A7%E8%BE%B9%E6%8A%BD%E5%B1%89%E7%BB%84%E4%BB%B6.js
// ==UserScript==
// @name Drawer_gz页面侧边抽屉组件
// @namespace http://tampermonkey.net/
// @license Apache-2.0
// @version 0.2
// @author byhgz
// @description 页面侧边抽屉组件
// @noframes
// ==/UserScript==
/**
* 页面侧边抽屉组件对象
* 需要new一个实例对象,按需传入配置对象
* showDrawer()方法可以切换抽屉显示或隐藏
* show()方法可以设置面板显示或隐藏
* setTitle()方法可以设置标题
* titleShow()方法可以设置标题是否显示
* setBodyHtml()方法可以设置面板内容html
* @param config {object} 配置对象
* @param config.show {boolean} 是否显示,默认false
* @param config.direction {string} 方向,默认right
* @param config.width {string} 宽度,默认500px
* @param config.height {string} 高度,默认500px
* @param config.backgroundColor {string} 面板背景色,默认#ffffff
* @param config.bodyHtml {string} 面板内容html
* @param config.title {string} 标题,默认null
* @param config.zIndex {string|number} 层级,默认1500
* @param config.border {string} 边框,格式为粗细度 样式 颜色,详情可参考css中的border属性,默认1px solid red
* @returns {Drawer_gz} 实例对象
* @version 0.1
* @author hgz
* @constructor
*/
function Drawer_gz(config) {
const __data = {
outerDiv: null,
titleHeaderEl: null,
titleEl: null,
};
config = {
...{
show: false,
direction: 'right',
width: '500px',
height: '500px',
backgroundColor: '#ffffff',
bodyHtml: '',
title: null,
border: "1px solid red",
zIndex: "1500",
}, ...config
}
/**
* 判断当前是否显示
* @returns {boolean}
*/
this.isShow = () => {
return config.show;
};
/**
* 设置面板显示或隐藏
* @param bool
*/
this.show = (bool) => {
config.show = bool;
setDivShowAndHideStyle();
}
//设置标题
this.setTitle = (title) => {
if (title.trim() === "") {
throw new Error("要设置的标题不能为空");
}
if (__data.titleHeaderEl.style.display === "none") {
__data.titleHeaderEl.style.display = "flex";
}
__data.titleEl.textContent = title;
}
//设置标题是否显示
this.titleShow = (bool) => {
if (bool) {
if (__data.titleEl.textContent.trim() === "") {
throw new Error("标题为空");
}
__data.titleHeaderEl.style.display = "flex";
} else {
__data.titleHeaderEl.style.display = "none";
}
}
//设置面板内容html
this.setBodyHtml = (html) => {
panel.innerHTML = html;
}
/**
* 插入html到面板指定位置
* position:插入的位置,可以是以下值之一:
* 'beforebegin':在元素自身之前。
* 'afterbegin':在元素的第一个子节点之前。
* 'beforeend':在元素的最后一个子节点之后。
* 'afterend':在元素自身之后。
* @param html {string} 要插入的html
* @param position {string} 插入位置 beforebegin afterbegin beforeend afterend
*/
this.insertAdjacentHTML = (html, position = "beforeend") => {
panel.insertAdjacentHTML(position, html);
}
//设置层级
this.setZIndex = (zIndex) => {
config.zIndex = zIndex;
__data.outerDiv.style.zIndex = zIndex;
}
//验证direction参数
const validateDirection = (direction) => {
if (!["top", "bottom", "left", "right"].includes(direction)) {
const message = "方向只能是top、bottom、left、right";
alert(message);
throw new Error(message);
}
}
validateDirection(config.direction);
//todo: 待后续实现手动切换方向功能
// const setDirection = (direction) => {
// validateDirection(direction);
// config.direction = direction;
// debugger;
// setDivShowAndHideStyle();
// }
const setDivShowAndHideStyle = () => {
const div = __data.outerDiv;
if (config.direction === "left" || config.direction === "right" || config.direction === "top") div.style.top = "0";
if (config.direction === "left" || config.direction === "top" || config.direction === "bottom") div.style.left = "0";
if (config.direction === "right" || config.direction === "top" || config.direction === "bottom") div.style.right = "0";
if (config.direction === "right") div.style.left = "";
if (config.direction === "bottom") div.style.bottom = "0";
if (config.direction === "top" || config.direction === "bottom") {
div.style.width = "100vw";
} else {
div.style.height = "100vh";
}
if (this.isShow()) {
if (config.direction === "left" || config.direction === "right") {
div.style.transform = 'translateX(0)';
}
if (config.direction === "top" || config.direction === "bottom") {
div.style.transform = 'translateY(0)';
}
} else {
if (config.direction === "left") {
div.style.transform = 'translateX(-100%)';
}
if (config.direction === "right") {
div.style.transform = 'translateX(100%)';
}
if (config.direction === "top") {
div.style.transform = 'translateY(-100%)';
}
if (config.direction === "bottom") {
div.style.transform = 'translateY(100%)';
}
}
}
const setPanelShowAndHideStyle = (externalPanel, panel) => {
if (config.direction === "left" || config.direction === "right") {
panel.style.width = config.width;
panel.style.height = "100vh";
} else {
panel.style.height = config.height;
}
}
const addTitleHeaderElement = (panel) => {
const el = document.createElement('div');
if (config.title) {
el.style.display = "flex";
} else {
el.style.display = "none";
}
__data.titleHeaderEl = el;
el.style.height = "40px";
el.style.alignItems = "center";
el.style.padding = "20px 20px 0"
const span = document.createElement("span");
span.textContent = config.title;
__data.titleEl = span;
el.appendChild(span);
panel.appendChild(el);
}
const documentFragment = document.createDocumentFragment();
//外层
__data.outerDiv = document.createElement('div');
__data.outerDiv.style.position = 'fixed';
__data.outerDiv.style.transition = 'transform 0.5s';
__data.outerDiv.style.zIndex = config.zIndex;
setDivShowAndHideStyle();
this.showDrawer = () => {
if (this.isShow()) {
this.show(false);
} else {
this.show(true);
}
setDivShowAndHideStyle();
}
const externalPanel = document.createElement('div');
const panel = document.createElement('div');
externalPanel.style.backgroundColor = config.backgroundColor;
externalPanel.style.border = config.border;
panel.innerHTML = config.bodyHtml;
addTitleHeaderElement(externalPanel);
panel.style.overflowY = 'auto';
setPanelShowAndHideStyle(externalPanel, panel);
documentFragment.appendChild(__data.outerDiv);
__data.outerDiv.appendChild(externalPanel);
externalPanel.appendChild(panel);
document.body.appendChild(documentFragment);
return this;
}