技术实践

WinBox.js—Web的HTML5窗口管理器

WinBox是一个现代的 HTML5网络窗口管理器。 轻量级、出色的性能、无依赖、完全可定制、免费和开源!

羊先生的头像
羊先生2021.07.25 · 1 分钟阅读 · 42 阅读
WinBox.js—Web的HTML5窗口管理器封面
文章正文还需 1 分钟

演示

点击前往

GitHub

image.png

代码

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover, shrink-to-fit=no">
    <meta name="robots" content="index, follow">
    <link rel="stylesheet" href="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/highlight.js/10.6.0/styles/railscasts.min.css">
    <title>WinBox是一个现代的 HTML5网络窗口管理器。 轻量级、出色的性能、无依赖、完全可定制、免费和开源!</title>
    <link rel="stylesheet" href="dist/css/winbox.min.css">
    <link rel="stylesheet" href="dist/css/themes/modern.min.css">
    <link rel="stylesheet" href="dist/css/themes/white.min.css">
    <script src="dist/js/winbox.min.js"></script>
    <style>
        /* WinBox Theme: "custom" */
        
        .winbox.custom {
            background: linear-gradient(90deg, #ff00f0, #0050ff);
            box-shadow: none;
            border-radius: 12px 12px 0 0;
        }
        
        .winbox.custom.max,
        .winbox.custom.min {
            border-radius: 0;
        }
        
        .winbox.custom .wb-body {
            /* margin represents the width of window border: */
            margin: 4px;
            color: #fff;
            background: #131820;
        }
        
        .winbox.custom .wb-title {
            font-size: 13px;
            text-transform: uppercase;
            font-weight: 600;
        }
        
        .winbox.custom .wb-icon * {
            opacity: 0.65;
        }
        
        .winbox.custom .wb-icon *:hover {
            opacity: 1;
        }
        
        .winbox.custom .wb-max {
            background-image: url(src/img/max.svg);
            background-size: 17px auto;
        }
        
        .winbox.custom .wb-min {
            background-image: url(src/img/min.svg);
        }
        
        .winbox.custom .wb-close {
            background-image: url(src/img/close.svg);
        }
        
        .winbox.custom .wb-full {
            display: none;
        }
        
        .winbox.custom .wb-body::-webkit-scrollbar {
            width: 12px;
        }
        
        .winbox.custom .wb-body::-webkit-scrollbar-track {
            background: transparent;
        }
        
        .winbox.custom .wb-body::-webkit-scrollbar-thumb {
            border-radius: 10px;
            background: #263040;
        }
        
        .winbox.custom .wb-body::-webkit-scrollbar-thumb:window-inactive {
            background: #181f2a;
        }
        
        .winbox.custom .wb-body::-webkit-scrollbar-corner {
            background: transparent;
        }
        /* WinBox Theme: "my-theme" */
        
        .winbox.my-theme {
            background: #fff;
        }
        
        .winbox.my-theme .wb-body {
            color: #fff;
            background: #131820;
        }
        
        .winbox.my-theme .wb-title {
            color: #000;
        }
        
        .winbox.my-theme .wb-icon {
            filter: invert(1);
        }
    </style>
    <link rel="stylesheet" href="demo/style.css">
    <meta name="description" content="WinBox是一个现代的 HTML5网络窗口管理器。 轻量级、出色的性能、无依赖、完全可定制、免费和开源!">
    <meta name="keywords" content="window manager, web window, html5 popup, javascript window, web desktop, html5 windows, web frame, web box">
</head>

<body>
    <div class="background"></div>
    <div class="scroll">
        <div class="wrapper">
            <h2>WinBox是一个现代的 HTML5网络窗口管理器。 轻量级、出色的性能、无依赖、完全可定制、免费和开源!</h2>
            <br>
            <div class="button" onclick="window.examples['theme-modern']()" style="background-color: #ca00b4">运行列子</div>
            <br><br>
            <hr>
            <br> 使用捆绑版本
            <br>
            <p>捆绑版本包括所有资产,如 js、css、html 和图标图像作为 base64</p>
            <pre><code class="language-html">&lt;head>
    &lt;script src="dist/winbox.bundle.js">&lt;/script>
&lt;/head></code></pre>
            <div class="break"></div>
            <br> 使用非捆绑版本
            <br>
            <p>非捆绑版本需要分别加载js和css(css也包含base64的图标)</p>
            <br>
            <pre><code class="language-html">&lt;head>
    &lt;link rel="stylesheet" href="dist/css/winbox.min.css">
    &lt;script src="dist/js/winbox.min.js">&lt;/script>
&lt;/head></code></pre>
            <div class="break"></div>
            <br>预加载库/异步加载(推荐)
            <br>
            <p>只需将链接标记添加到指示预加载脚本的标题部分。在正文关闭之前添加您的站点脚本。根据您的代码,您可能需要以正确的顺序加载它们</p>
            <br>
            <pre><code class="language-html">&lt;html>
    &lt;head>
        &lt;link rel="preload" href="winbox.bundle.js"/>
    &lt;/head>
    &lt;body>
        &lt;script src="winbox.bundle.js" defer>&lt;/script>
        &lt;script src="my-script.js" defer>&lt;/script>
    &lt;/body>
&lt;/html></code></pre>
            <div class="break"></div>
            <hr>
            <br>构造函数
            <br><br>
            <pre><code class="language-js">WinBox(title, options&lt;key: value>)</code></pre>
            <br>
            <hr>
            <br> 基本窗口
            <br><br>
            <pre><code class="language-js">new WinBox("Basic Window");</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['basic']()">Run Code</div>
            <br><br>

            <hr>
            <br> 自定义展示的元素
            <br><br>
            <pre><code class="language-js">new WinBox("Custom Root", {

    root: document.body
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['root']()">Run Code</div>
            <br><br>

            <hr>
            <br> 自定义边界
            <br><br>
            <pre><code class="language-js">new WinBox("Custom Border", {

    border: "0.3em"
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['border']()">Run Code</div>
            <br><br>

            <hr>
            <br> 自定义颜色
            <br><br>
            <pre><code class="language-js">new WinBox({

    title: "Custom Color",
    background: "#ff005d",
    border: 4
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['color']()">Run Code</div>
            <br><br>

            <hr>
            <br> 限制窗口
            <br><br>
            <pre><code class="language-js">new WinBox("Limit Viewport", {

    top: 50,
    right: 50,
    bottom: 0,
    left: 50
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['viewport']()">Run Code</div>
            <br><br>

            <hr>
            <br> 分区屏幕
            <br><br>
            <pre><code class="language-js">new WinBox("Splitscreen (Left)", {

    right: "50%",
    max: true
});

new WinBox("Splitscreen (Right)", {

    x: "100%",
    left: "50%",
    max: true
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['splitscreen']()">Run Code</div>
            <br><br>

            <hr>
            <br> 自定义位置/大小
            <br><br>
            <pre><code class="language-js">new WinBox({

    title: "Custom Position / Size",
    x: "center",
    y: "center",
    width: "50%",
    height: "50%"
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['position']()">Run Code</div>
            <br><br>

            <hr>
            <br> 模态窗口
            <br><br>
            <pre><code class="language-js">new WinBox("Modal Window", {

    modal: true
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['modal']()">Run Code</div>
            <br><br>

            <hr>
            <br> 设置innerHTML
            <br><br>
            <pre><code class="language-js">new WinBox({

    title: "Set innerHTML",
    html: "&lt;h1>Lorem Ipsum&lt;/h1>"
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['innerhtml']()">Run Code</div>
            <br><br>

            <hr>
            <br> 克隆
            <br><br>

            <pre><code class="language-html">&lt;div id="backstore" style="display: none">
    &lt;div id="content">
        &lt;h1>Lorem Ipsum&lt;/h1>
        &lt;p>Lorem ipsum [...]&lt;/p>
        &lt;p>Duis autem vel [...]&lt;/p>
        &lt;p>Ut wisi enim [...]&lt;/p>
    &lt;/div>
&lt;/div></code></pre>
            <div class="break"></div>
            <pre><code class="language-js">new WinBox("Mount DOM", {

    mount: document.getElementById("content")
                   .cloneNode(true)
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['mount-clone']()">Run Code</div>
            <br><br>

            <hr>
            <br> 挂载DOM(单例)+自动卸载
            <br><br>
            <pre><code class="language-js">new WinBox("Mount DOM", {

    mount: document.getElementById("content")
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['mount-auto']()">Run Code</div>
            <br><br>

            <hr>
            <br> 打开一个url
            <br><br>
            <pre><code class="language-js">new WinBox("WinBox.js", {

    url: "https://nextapps-de.github.io/winbox/"
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['iframe']()">Run Code</div>
            <br><br>

            <hr>
            <br> 所有API
            <br><br>
            <pre><code class="language-js">new WinBox({

    id: "my-window",
    class: ["no-full", "my-theme"],
    root: document.body,
    title: "All Options",
    background: "#fff",
    border: 4,
    width: 200,
    height: 200,
    x: "center",
    y: "center",
    max: false,
    splitscreen: true,
    top: 50,
    right: 50,
    bottom: 0,
    left: 50,
    html: "width: 200, height: 200",
    onfocus: function(){
        this.setBackground("#fff");
    },
    onblur: function(){
        this.setBackground("#999");
    },
    onresize: function(width, height){
        this.body.textContent = (
            "width: " + width + ", " +
            "height: " + height
        );
    },
    onmove: function(x, y){
        this.body.textContent = (
            "x: " + x + ", " +
            "y: " + y
        );
    },
    onclose: function(force){
        return !confirm("Close window?");
    }
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['all-options']()">Run Code</div>
            <br><br>

            <hr>
            <br> 通过编程控制
            <br><br>
            <pre><code class="language-html">&lt;div id="controls">
    &lt;button onclick="buttons.minimize()">Minimize (Toggle)&lt;/button>
    &lt;button onclick="buttons.maximize()">Maximize (Toggle)&lt;/button>
    &lt;button onclick="buttons.fullscreen()">Fullscreen (Toggle)&lt;/button>
    &lt;button onclick="buttons.move()">Move (Center, Center)&lt;/button>
    &lt;button onclick="buttons.resize()">Resize (50%, 50%)&lt;/button>
    &lt;button onclick="buttons.title()">Set Title&lt;/button>
    &lt;button onclick="buttons.color()">Set Color&lt;/button>
    &lt;button onclick="buttons.close()">Close&lt;/button>
&lt;/div></code></pre>
            <div class="break"></div>
            <pre><code class="language-js">var winbox = new WinBox("Controls", {

    mount: document.getElementById("controls"),
    border: 4,
    onclose: function(force){
        return !force && !confirm("Close window?");
    }
});</code></pre>
            <div class="break"></div>
            <pre><code class="language-js">window.buttons = {

    minimize: function(){

        winbox.minimize();
    },
    maximize: function(){

        winbox.maximize();
    },
    fullscreen: function(){

        winbox.fullscreen();
    },
    move: function(){

        winbox.move("center", "center");
    },
    resize: function(){

        winbox.resize("50%", "50%");
    },
    title: function(){

        winbox.setTitle("Title-" + Math.random());
    },
    color: function(){

        winbox.setBackground(
            "rgb(" + (Math.random() * 255 | 0) + "," +
                     (Math.random() * 255 | 0) + "," +
                     (Math.random() * 255 | 0) + ")"
        );
    },
    modal: function(){

        winbox.body.parentNode.classList.toggle("modal");
    },
    close: function(){

        winbox.close();
    },
    force_close: function(){

        winbox.close(true);
    }
};</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['controls']()">Run Code</div>
            <br><br>

            <hr>
            <br>窗口样板
            <br><br>
            <img src="demo/boilerplate.svg" width="100%" alt="WinBox Boilerplate">

            <hr>
            <br> 自定义风格(全局)
            <br><br>
            <pre><code class="language-css">.winbox {
    background: linear-gradient(90deg, #ff00f0, #0050ff);
    border-radius: 12px 12px 0 0;
    box-shadow: none;
}

.winbox.min {
    border-radius: 0;
}

.wb-body {
    /* the width of window border: */
    margin: 4px;
    color: #fff;
    background: #131820;
}

.wb-title {
    font-size: 13px;
    text-transform: uppercase;
    font-weight: 600;
}</code></pre>
            <div class="break"></div>

            自定义Icon
            <br><br>
            <pre><code class="language-css">.wb-icon * {
    opacity: 0.65;
}

.wb-icon *:hover {
    opacity: 1;
}

.wb-min {
    background-image: url(src/img/min.svg);
    background-size: 15px center;
}

.wb-max {
    background-image: url(src/img/max.svg);
}

.wb-close {
    background-image: url(src/img/close.svg);
}

.wb-full {
    display: none;
}</code></pre>
            <div class="break"></div>

            自定义滚动条
            <br><br>
            <pre><code class="language-css">.wb-body::-webkit-scrollbar {
    width: 12px;
}
.wb-body::-webkit-scrollbar-track {
    background: transparent;
}
.wb-body::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background: #263040;
}
.wb-body::-webkit-scrollbar-thumb:window-inactive {
    background: #181f2a;
}
.wb-body::-webkit-scrollbar-corner {
    background: transparent;
}</code></pre>
            <div class="break"></div>
            <pre><code class="language-js">new WinBox("Custom CSS", {

    mount: document.getElementById("content")
                   .cloneNode(true)
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['custom-css']()">Run Code</div>
            <br><br>

            <hr>
            <br> 自定义类名定制样式
            <br><br>
            <pre><code class="language-css">.winbox.my-theme{
    background: #fff;
}
.winbox.my-theme .wb-body {
    color: #fff;
    background: #131820;
}
.winbox.my-theme .wb-title {
    color: #000;
}
.winbox.my-theme .wb-icon {
    filter: invert(1);
}</code></pre>
            <div class="break"></div>
            <pre><code class="language-js">new WinBox("Custom CSS (Class)", {

    class: "my-theme",
    mount: document.getElementById("content")
                   .cloneNode(true)
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['custom-class']()">Run Code</div>
            <br><br>

            <hr>
            <br> 主题
            <br><br>
            <pre><code class="language-html">&lt;head>
    &lt;link rel="stylesheet" href="dist/css/winbox.min.css">
    &lt;link rel="stylesheet" href="dist/css/themes/modern.min.css">
    &lt;script src="dist/js/winbox.min.js">&lt;/script>
&lt;/head></code></pre>
            <div class="break"></div>
            <pre><code class="language-js">new WinBox("Theme", {

    class: "modern",
    mount: document.getElementById("content")
                   .cloneNode(true)
});</code></pre>
            <div class="break"></div>
            <div class="button" onclick="window.examples['theme-modern']()">Run Code</div>
            <br><br>

        </div>
    </div>
    <div id="backstore" style="display: none">
        <div id="content">
            <h1>Lorem Ipsum</h1>
            <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
                no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam
                et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna
                aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
            <p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore
                te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
            <p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat
                nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>
        </div>
        <div id="controls">
            <button onclick="window.buttons['minimize']()">Minimize (Toggle)</button>
            <button onclick="window.buttons['maximize']()">Maximize (Toggle)</button>
            <button onclick="window.buttons['fullscreen']()">Fullscreen (Toggle)</button>
            <button onclick="window.buttons['modal']()">Modal (Toggle)</button>
            <button onclick="window.buttons['center']()">Move (Center, Center)</button>
            <button onclick="window.buttons['move']()">Move (Right, Bottom)</button>
            <button onclick="window.buttons['resize']()">Resize (50%, 50%)</button>
            <button onclick="window.buttons['title']()">Set Title</button>
            <button onclick="window.buttons['color']()">Set Color</button>
            <button onclick="window.buttons['add']()">Add Class (my-theme)</button>
            <button onclick="window.buttons['remove']()">Remove Class (my-theme)</button>
            <button onclick="window.buttons['close']()">Close</button>
            <button onclick="window.buttons['force_close']()">Force Close</button>
        </div>
    </div>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/highlight.js/10.6.0/highlight.min.js"></script>
    <script>
        (function() {

            let winbox;

            window.examples = {

                "basic": function() {

                    new WinBox("Basic Window");
                },
                "root": function() {

                    new WinBox("Custom Root", {

                        root: document.body
                    });
                },
                "border": function() {

                    new WinBox("Custom Border", {

                        border: "0.3em"
                    });
                },
                "color": function() {

                    new WinBox({

                        title: "Custom Color",
                        background: "#ff005d",
                        border: 4
                    });
                },
                "viewport": function() {

                    new WinBox("Limit Viewport", {

                        top: 50,
                        right: 50,
                        bottom: 0,
                        left: 50
                    });
                },
                "splitscreen": function() {

                    new WinBox("Splitscreen (Left)", {

                        right: "50%",
                        max: true
                    });

                    new WinBox("Splitscreen (Right)", {

                        x: "100%",
                        left: "50%",
                        max: true
                    });
                },
                "position": function() {

                    new WinBox({

                        title: "Custom Position / Size",
                        x: "center",
                        y: "center",
                        width: "50%",
                        height: "50%"
                    });
                },
                "modal": function() {

                    new WinBox("Modal Window", {

                        modal: true
                    });
                },
                "innerhtml": function() {

                    new WinBox({

                        title: "Set innerHTML",
                        html: "<h1>Lorem Ipsum</h1>"
                    });
                },
                "mount-clone": function() {

                    new WinBox("Mount DOM", {

                        mount: document.getElementById("content")
                            .cloneNode(true)
                    });
                },
                "mount-auto": function() {

                    new WinBox("Mount DOM", {

                        mount: document.getElementById("content")
                    });
                },
                "iframe": function() {

                    new WinBox("WinBox.js", {

                        url: "https://nextapps-de.github.io/winbox/",
                        class: "iframe"
                    });
                },
                "all-options": function() {

                    new WinBox({

                        id: "my-window",
                        class: ["no-full", "my-theme"],
                        root: document.body,
                        title: "All Options",
                        background: "#fff",
                        border: 4,
                        index: 50,
                        width: 200,
                        height: 200,
                        minheight: 100,
                        minwidth: 100,
                        x: "center",
                        y: "center",
                        max: false,
                        splitscreen: true,
                        top: 50,
                        right: 50,
                        bottom: 0,
                        left: 50,
                        html: "width: 200, height: 200",
                        onfocus: function() {
                            this.setBackground("#fff");
                        },
                        onblur: function() {
                            this.setBackground("#999");
                        },
                        onresize: function(width, height) {
                            this.body.textContent = (
                                "width: " + width + ", " +
                                "height: " + height
                            );
                        },
                        onmove: function(x, y) {
                            this.body.textContent = (
                                "x: " + x + ", " +
                                "y: " + y
                            );
                        },
                        onclose: function(force) {
                            return !confirm("Close window?");
                        }
                    });
                },
                "custom-css": function() {

                    new WinBox("Custom CSS", {

                        class: "custom",
                        mount: document.getElementById("content")
                            .cloneNode(true)
                    });
                },
                "custom-class": function() {

                    new WinBox("Custom CSS (Class)", {

                        class: "my-theme",
                        mount: document.getElementById("content")
                            .cloneNode(true)
                    });
                },
                "theme-modern": function() {

                    new WinBox("Theme: Modern", {

                        class: "modern",
                        mount: document.getElementById("content")
                            .cloneNode(true)
                    });
                },
                "controls": function() {

                    winbox = new WinBox("Controls", {

                        mount: document.getElementById("controls"),
                        border: 4,
                        onclose: function(force) {
                            return !force && !confirm("Close window?");
                        }
                    });
                }
            };

            window.buttons = {

                minimize: function() {

                    winbox.minimize();
                },
                maximize: function() {

                    winbox.maximize();
                },
                fullscreen: function() {

                    winbox.fullscreen();
                },
                center: function() {

                    winbox.move("center", "center");
                },
                move: function() {

                    winbox.move("right", "bottom");
                },
                resize: function() {

                    winbox.resize("50%", "50%");
                },
                title: function() {

                    winbox.setTitle("Title-" + Math.random());
                },
                color: function() {

                    winbox.setBackground(
                        "rgb(" + (Math.random() * 255 | 0) + "," +
                        (Math.random() * 255 | 0) + "," +
                        (Math.random() * 255 | 0) + ")"
                    );
                },
                modal: function() {

                    winbox.body.parentNode.classList.toggle("modal");
                },
                add: function() {

                    winbox.addClass("my-theme");
                },
                remove: function() {

                    winbox.removeClass("my-theme");
                },
                close: function() {

                    winbox.close();
                },
                force_close: function() {

                    winbox.close(true);
                }
            };

        }());

        hljs.highlightAll();
    </script>
</body>

</html>