您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
一个简易tabs标签页,只需创建该类的实例,按需传入配置即可在页面上创建
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/517538/1485921/DynamicTabs_gz.js
- // ==UserScript==
- // @name DynamicTabs_gz
- // @namespace http://tampermonkey.net/
- // @license Apache-2.0
- // @version 0.2
- // @author byhgz
- // @description 一个简易tabs标签页,只需创建该类的实例,按需传入配置即可在页面上创建
- // @noframes
- // ==/UserScript==
- /**
- *
- * 一个简易Tabs标签页,只需创建该类的实例,按需传入配置即可在页面上创建
- *
- * @author byhgz
- */
- class DynamicTabs_gz {
- #selector;
- #tabsConfig;
- #activeTabId;
- #options;
- #buttonContainerSelector = '[name="buttonContainer"]';
- #contentContainerSelector = '[name="contentContainer"]';
- /**
- *
- * @param selector{string} css选择器
- * @param tabsConfig {Array} 选项卡配置,参数为数组,数组每个对象为一个选项卡和对应的选项卡内容
- * @param options {Object} 其他选项,可设置自定义样式和事件处理类名
- */
- constructor(selector, tabsConfig, options = {}) {
- this.#selector = selector; // 选项卡容器的选择器
- this.#tabsConfig = tabsConfig; // 选项卡配置数组
- this.#activeTabId = tabsConfig[0].id; // 默认激活的第一个选项卡ID
- this.#options = options; // 可选配置项,如自定义样式和事件处理函数
- // 初始化选项卡
- this.#init();
- }
- // 私有初始化方法
- #init() {
- // 获取选项卡容器元素
- const tabsContainer = document.querySelector(this.#selector);
- if (!tabsContainer) {
- throw new Error(`No element found matching the selector: ${this.#selector}`);
- }
- // 添加默认样式
- this.#addDefaultStyles();
- // 创建选项卡按钮
- this.#createButtons(tabsContainer);
- // 创建选项卡内容
- this.#createContents(tabsContainer);
- }
- // 私有添加默认样式的方法
- #addDefaultStyles() {
- const defaultClasses = {
- tabButton: 'dynamic-tab-button',
- tabButtonActive: 'dynamic-tab-button-active',
- tabContent: 'dynamic-tab-content',
- tabContentActive: 'dynamic-tab-content-active'
- };
- // 合并用户提供的类名
- const classes = {...defaultClasses, ...this.#options.classes};
- // 获取用户提供的样式或默认样式
- const backgroundColor = this.#options.backgroundColor || '#ccc';
- const borderColor = this.#options.borderColor || '#ccc';
- const textColor = this.#options.textColor || 'black';
- const fontWeight = this.#options.fontWeight || 'normal';
- const activeBackgroundColor = this.#options.activeBackgroundColor || '#007BFF';
- const activeTextColor = this.#options.activeTextColor || 'white';
- const contentBorderColor = this.#options.contentBorderColor || '#ccc';
- const contentBackgroundColor = this.#options.contentBackgroundColor || '#f9f9f9';
- const defaultStyle = `
- ${this.#selector}>${this.#buttonContainerSelector}>.${classes.tabButton} {
- padding: 10px 20px;
- margin: 5px;
- cursor: pointer;
- border: 1px solid ${borderColor};
- background-color: ${backgroundColor};
- color: ${textColor};
- font-weight: ${fontWeight};
- }
- ${this.#selector}>${this.#buttonContainerSelector}>.${classes.tabButton}.${classes.tabButtonActive} {
- background-color: ${activeBackgroundColor};
- color: ${activeTextColor};
- }
- ${this.#selector}>${this.#contentContainerSelector}>.${classes.tabContent} {
- margin-top: 5px;
- padding: 20px;
- border: 1px solid ${contentBorderColor};
- background-color: ${contentBackgroundColor};
- display: none;
- }
- ${this.#selector}>${this.#contentContainerSelector}>.${classes.tabContent}.${classes.tabContentActive} {
- display: block;
- }
- ${this.#selector} {
- display: flex;
- flex-direction: column;
- }
- ${this.#selector}[data-tab-position="bottom"] > ${this.#buttonContainerSelector} {
- order: 2;
- }
- ${this.#selector}[data-tab-position="bottom"] > ${this.#contentContainerSelector} {
- order: 1;
- }
- ${this.#selector}[data-tab-position="left"] > ${this.#buttonContainerSelector},
- ${this.#selector}[data-tab-position="right"] > ${this.#buttonContainerSelector} {
- flex-direction: column;
- width: 20%;
- }
- ${this.#selector}[data-tab-position="left"] > ${this.#contentContainerSelector},
- ${this.#selector}[data-tab-position="right"] > ${this.#contentContainerSelector} {
- width: 80%;
- }
- ${this.#selector}[data-tab-position="left"] {
- flex-direction: row;
- }
- ${this.#selector}[data-tab-position="right"] {
- flex-direction: row-reverse;
- }
- `;
- // 如果提供了自定义样式,则覆盖默认样式
- const customStyle = this.#options.styles || '';
- const style = document.createElement('style');
- style.innerHTML = defaultStyle + customStyle;
- document.head.appendChild(style);
- this.setTabPosition(this.#options.tabPosition || 'top');
- }
- /**
- * 设置选项卡位置,可设置为 'top'、'bottom'、'left' 或 'right'
- * @param position {string} 选项卡位置
- */
- setTabPosition(position) {
- // 设置 tabPosition 属性
- const tabsContainer = document.querySelector(this.#selector);
- tabsContainer.setAttribute("data-tab-position", position);
- }
- // 私有创建选项卡按钮的方法
- #createButtons(tabsContainer) {
- const buttonContainer = document.createElement('div');
- // 添加name属性
- buttonContainer.setAttribute("name", "buttonContainer");
- const classes = this.#options.classes || {};
- this.#tabsConfig.forEach(tab => {
- const button = document.createElement('button');
- button.className = `${classes.tabButton || 'dynamic-tab-button'}`;
- button.textContent = tab.title;
- button.setAttribute("data-tab-id", tab.id);
- button.setAttribute("data-tab-title", tab.title);
- if (tab.id === this.#activeTabId) {
- button.classList.add(classes.tabButtonActive || 'dynamic-tab-button-active');
- }
- buttonContainer.appendChild(button);
- });
- tabsContainer.appendChild(buttonContainer);
- const butS = document.querySelector(`${this.#selector}>${this.#buttonContainerSelector}`);
- butS.addEventListener('click', (event) => {
- if (event.target.tagName !== "BUTTON") return;
- const dataTabId = event.target.getAttribute("data-tab-id");
- if (dataTabId === null) return;
- this.activateTabId(dataTabId);
- // 调用自定义的点击事件处理函数(如果存在)
- if (this.#options.onTabClick) {
- const {id,title,content} = this.#tabsConfig.find(tab => tab.id === dataTabId);
- this.#options.onTabClick(id,title,content);
- }
- });
- }
- // 私有创建选项卡内容的方法
- #createContents(tabsContainer) {
- const contentContainer = document.createElement('div');
- contentContainer.setAttribute("name", "contentContainer");
- const classes = this.#options.classes || {};
- for (let tab of this.#tabsConfig) {
- // 创建一个div来包装选项卡外层
- const tabDiv = document.createElement('div');
- tabDiv.className = `${classes.tabContent || 'dynamic-tab-content'}`;
- tabDiv.setAttribute("data-tab-id", tab.id);
- tabDiv.setAttribute("data-tab-title", tab.title);
- // 创建一个div来包装选项卡内容
- const tabContentDiv = document.createElement('div');
- tabContentDiv.innerHTML = tab.content;
- if (tab.id === this.#activeTabId) {
- tabDiv.classList.add(classes.tabContentActive || 'dynamic-tab-content-active');
- }
- tabDiv.appendChild(tabContentDiv);
- contentContainer.appendChild(tabDiv);
- }
- tabsContainer.appendChild(contentContainer);
- }
- /**
- * 激活指定的选项卡
- * @param toType {{type: string,value:string}} 匹配的方式和匹配的值
- */
- #activateTab(toType) {
- const classes = this.#options.classes || {};
- // 更新按钮状态
- const butCss = `${this.#selector}>${this.#buttonContainerSelector}>.${classes.tabButton || 'dynamic-tab-button'}`;
- const buttons = document.querySelectorAll(butCss);
- buttons.forEach(button => {
- let dataTabValue;
- if (toType.type === "id") {
- dataTabValue = button.getAttribute("data-tab-id");
- } else {
- dataTabValue = button.getAttribute("data-tab-title");
- }
- if (dataTabValue === toType.value) {
- button.classList.add(classes.tabButtonActive || 'dynamic-tab-button-active');
- } else {
- button.classList.remove(classes.tabButtonActive || 'dynamic-tab-button-active');
- }
- });
- // 更新内容状态
- const contentCss = `${this.#selector}>${this.#contentContainerSelector}>.${classes.tabContent || 'dynamic-tab-content'}`;
- const contents = document.querySelectorAll(contentCss);
- contents.forEach(tabDiv => {
- let dataTabValue;
- if (toType.type === "id") {
- dataTabValue = tabDiv.getAttribute("data-tab-id");
- } else {
- dataTabValue = tabDiv.getAttribute("data-tab-title");
- }
- if (dataTabValue === toType.value) {
- tabDiv.classList.add(classes.tabContentActive || 'dynamic-tab-content-active');
- } else {
- tabDiv.classList.remove(classes.tabContentActive || 'dynamic-tab-content-active');
- }
- });
- this.#activeTabId = toType.value;
- }
- /**
- * 激活指定的选项卡,通过选项卡id
- * @param tabID {string}
- */
- activateTabId(tabID) {
- this.#activateTab({type: "id", value: tabID})
- }
- /**
- * 激活指定的选项卡,通过选项卡标题
- * @param tabTitle {string}
- */
- activateTabTitle(tabTitle) {
- this.#activateTab({type: "title", value: tabTitle})
- }
- }