javascript - 如何使新的 JqueryUI 选项卡实例可删除?

标签 javascript jquery-ui tabs jquery-ui-draggable jquery-ui-droppable

$(document).ready(function() {

             var tabTitle = $('#tab_title'),
                 tabContent = $('#tab_content'),
                 tabTemplate = '<li class="ui-droppable ui-state-default"><a href="#{href}">#{label}</a> <span class="ui-icon ui-icon-close" role="presentation">Remove Tab</span></li>',
                 tabCounter = $('#tabs').children('div').length + 1,
                 feedTemplate = '';
             
             var tabs = $('#tabs').tabs();
             var feeds = $('#tabs').children('div');
             
             // Modal dialog init: custom buttons and a "close" callback resetting the form inside
             var dialog = $( "#dialog" ).dialog({
                 autoOpen: false,
                 modal: true,
                 buttons: {
                     Add: function() {
                         addTab();
                         $( this ).dialog( "close" );
                     },
                     Cancel: function() {
                         $( this ).dialog( "close" );
                     }
                 },
                 close: function() {
                     form[ 0 ].reset();
                 }
             });
             
             // AddTab form: calls addTab function on submit and closes the dialog
             var form = dialog.find( "form" ).on( "submit", function( event ) {
                 addTab();
                 dialog.dialog( "close" );
                 event.preventDefault();
             });
             
             // Actual addTab function: adds new tab using the input from the form above
             function addTab() {
                 var label = tabTitle.val() || 'Tab ' + tabCounter,
                     id = 'tabs-' + tabCounter,
                     li = $( tabTemplate.replace( /#\{href\}/g, '#' + id ).replace( /#\{label\}/g, label ) ),
                     tabContentHtml = tabContent.val() || 'Plop Tab ' + tabCounter + ' contentz.';
                 
                 tabs.find( '.ui-tabs-nav' ).append( li );
                 tabs.append( '<div class="ui-tabs-panel ui-corner-bottom ui-widget-content" id="' + id + '"><div class="elements grid nws-tab-feeds nws-tab-feeds-col ui-tabs-panel ui-corner-bottom ui-widget-content ui-droppable"><div class="element grid-item outerContainer-col outerContainer ui-draggable ui-draggable-handle">' + tabContentHtml + '<span class="ui-icon ui-icon-close" role="presentation">Remove feed</span></div></div></div>' );

                 tabCounter++;
                 
//                DOESN'T WORK 
//                                  $( ".elements" ).droppable( "option", "accept", ".special" );

//                 $( ".elements" ).droppable({
//                     accept: ".element"
//                 });

                 
                 tabs.tabs( "refresh" );
                 
             }
             
             // AddTab button: just opens the dialog
             $( "#add_tab" )
                 .button()
                 .on( "click", function() {
                     dialog.dialog( "open" );
                 });
             
             // Close icon: removing the tab on click
             tabs.on( "click", "span.ui-icon-close", function() {
                 var panelId = $( this ).closest( "li" ).remove().attr( "aria-controls" );
                 $( "#" + panelId ).remove();
                 tabs.tabs( "refresh" );
             });

             // Close icon: removing the feed on click
             feeds.on( "click", "span.ui-icon-close", function() {
                 $(this).parent().remove();
             });
             
             tabs.on( "keyup", function( event ) {
                 if ( event.altKey && event.keyCode === $.ui.keyCode.BACKSPACE ) {
                     var panelId = tabs.find( ".ui-tabs-active" ).remove().attr( "aria-controls" );
                     $( "#" + panelId ).remove();
                     tabs.tabs( "refresh" );
                 }
             });

             $('.elements').children().draggable({
                 appendTo: 'body',
                 opacity: 0.9,
                 helper: "clone",
                 zIndex: 1000,
                 cursorAt: {
                     left: 50,
                     top: 20
                 },
             });

             // drop into needle element
             $('.elements').droppable({
                 accept: '.element',
                 tolerance: 'pointer',
                 activeClass: "can-drop",
                 hoverClass: "drop-here",
                 drop: function(event, ui) {
                     $(this).append(ui.draggable[0]);
                     // var count = $("#tabs-1 div").length;
                     console.log('l: ' + $(this).children().length);
                 }
             });

             // drop
             $('ul.ui-tabs-nav').children().droppable({
                 accept: '.element',
                 tolerance: 'pointer',
                 over: function(event, ui) {
                     $("#tabs").tabs("option", "active", $(event.target).index());
                     console.log('plop: ' + $(event.target).index());

                     $.ui.ddmanager.prepareOffsets(ui.draggable.draggable('instance'));
                 }
             })

             
         });
:root {
  --main-color-level-1: #eeeeec;
  --main-color-level-2: #abbd81;
  --main-color-level-3: #3B1E2D;
  --main-color-level-4: #700;
  --main-color-level-5: #FF7F00;
  --main-color-level-6: #3d3644;
  --main-color-level-7: #FF5400;
  --main-color-level-8: #bbb; 
  --main-color-level-9: #333; 
  --main-color-level-10: #444; 
}

.ui-icon-close {
    cursor: pointer;
    float:right;
    margin:2px;
}

@font-face {
    font-family: system;
    font-style: normal;
    font-weight: 300;
    src: local(".SFNSText-Light"),
    local(".HelveticaNeueDeskInterface-Light"),
    local(".LucidaGrandeUI"),
    local("Ubuntu"),
    local("Segoe UI Light"),
    local("Roboto-Light"),
    local("DroidSans"),
    local("Tahoma");
}

body,
.ui-widget {
    /* font-family: "system" !important; */
    /* background:var(--main-color-level-9); */
    /* color:var(--main-color-level-1); */
    /* color:#eeeeec; */
    /* font-family: Arial, helvetica, sans-serif; */
}

/* Tooltips */

label {
    display: inline-block;
    width: 5em;
}

.ui-tooltip,
.arrow:after {
    background: black;
    border: 2px solid white;
}

.ui-tooltip {
    padding: 10px 20px;
    /* color: white; */
    border-radius: 6px;
    /* font: bold 14px "Helvetica Neue", Sans-Serif; */
    /* text-transform: uppercase; */
    box-shadow: 0 0 7px black;
    font-size:75%;
}

.arrow {
    width: 70px;
    height: 16px;
    overflow: hidden;
    position: absolute;
    left: 50%;
    margin-left: -35px;
    bottom: -16px;
}

.arrow.top {
    top: -16px;
    bottom: auto;
}

.arrow.left {
    left: 20%;
}

.arrow:after {
    content: "";
    position: absolute;
    left: 20px;
    top: -20px;
    width: 25px;
    height: 25px;
    box-shadow: 6px 5px 9px -9px black;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
}

.arrow.top:after {
    bottom: -20px;
    top: auto;
}

/* end */
.expose {
    position:relative;
}

button {
    margin: .2em 0 0 0;
}

#overlay {
    background:rgba(50,50,50,0.8);
    display:none;
    width:100%; height:100%;
    position:absolute; top:0; left:0; z-index:99998;
}

img.nws-loading-anim {
    margin: 0 0 0 .2em;
}

.nws-feed-text {
    /* font-weight: 900; */
    font-weight: normal;
    font-size: .7em;
    /* line-height:1em; */
    padding:.3em;
}

.nws-feed-link {
    cursor: pointer;
}

li.nws-feed-link {
    padding:0;
    margin:0;
}

.ui-tabs .ui-tabs-panel {
    padding: .2em 0 0 0;
}

.outerContainer {
    /* min-height:50vh; */
    /* min-height:100px; */
    margin: 0 0 .5em 0;
}

form {
    margin:0;
}

img.thumb {
    display:none;
    position:absolute;
    top:1em;
    right:50%;
    clear:both;
    float:right;
    margin:.2em;
}

.tooltip:hover:after {
    content: attr(data-tooltip);
}

/* a.nws-feed-title:link { */
/*     color:var(--main-color-level-2); */
/*     font-weight:bold; */
/*     text-decoration:none; */
/* } */

/* a.nws-feed-title:visited { */
/*     color:var(--main-color-level-5); */
/* } */

/* a:link { */
/*     color:var(--main-color-level-1); */
/*     font-weight:bold; */
/*     text-decoration:none; */
/* } */

/* a:visited { */
/*     color:var(--main-color-level-8); */
/* } */

/* a:hover { */
/*     color:var(--main-color-level-1); */
/* } */

/* a:active { */
/*     color:var(--main-color-level-7); */
/* } */

h1 {
    margin:0 0 .2em 0;
}



span.nws-error {
    color: var(--main-color-level-1);
}

/* div.nws-error { */
/*     background-color: var(--main-color-level-4); */
/* } */

/* Feed Item */

div.nws-tab-feeds {
}

.outerContainer {
}

.nws-tab-feeds-col {
    columns: 15em;
    column-gap: .3em;
}

.nws-tab-feeds-block {
}

.outerContainer-col {
    page-break-inside: avoid;
    break-inside: avoid;
}

.outerContainer-block {
    width:24%;
    display:inline-block;
    vertical-align:top;
}

.outerContainer-phone {
    width:100%;
}

.feedTitle {
    /* height:1.2em; */
    font-size:.8em !important;
    /* font-variant: small-caps; */
    padding:.2em;
    overflow:hidden;
    /* background:var(--main-color-level-3); */
    /* padding:.2em .2em 0; */
    white-space:nowrap;
    text-overflow: ellipsis;
}

.ui-menu { width: 150px; }

.feedTitle:hover {
    filter: brightness(175%);
}

.feed {
    /* vertical-align:top; */
    /* margin: 0 1% .5em 0; */
    /* font-size:.7em; */
    /* border: var(--main-color-level-10) 1px solid; */
    /* background: var(--main-color-level-3); */
}

.feed .nws-feed-icon {
    /* background: var(--main-color-level-3); */
}

/* .feed:hover { */
/*     border: var(--main-color-level-5) 1px solid; */
/* } */

.feed ul li img.feed {
    width:28%;
    margin: 0 0.5em 0.1em 0;
    vertical-align:text-top;
    float:left;
}

.feed ul li img.audio {
    width:10%;
    margin: 0 1% 1% 0;
    vertical-align:text-top;
    float:left;
}

.feed ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* .feed ul li { */
/*     margin:0; */
/*     padding: .3em; */
/*     /\* background: var(--main-color-level-9); *\/ */
/*     line-height:1em; */
/* } */

.feed ul li:nth-child(even) {
    filter: brightness(75%);
}

.fa-fw {
    font-size: .7em !important;
    margin: .3em .3em 0 0;
}


/* .feed ul li:hover { */
/*     background: var(--main-color-level-5); */
/*     color: var(--main-color-level-3); */
/* } */

.nws-button-reload,
.nws-button-gallery-feed {
    /* color: var(--main-color-level-5); */
    cursor: pointer;
    float: right;
    /* margin: .5em 0 0 0; */
}

.nws-button-gallery-tab,
.nws-button-col-wrapping-col,
.nws-button-col-wrapping-block,
.nws-button-col-wrapping-phone {
    cursor: pointer;
}

.nws-button-gallery-tab,
.nws-button-col-wrapping-col,
.nws-button-col-wrapping-block,
.nws-button-col-wrapping-phone {
    /* color: var(--main-color-level-3); */
}

.nws-button-reload:hover,
.nws-button-gallery-feed:hover,
.nws-button-gallery-tab:hover,
.nws-button-col-wrapping-col:hover,
.nws-button-col-wrapping-block:hover,
.nws-button-col-wrapping-phone:hover {
    /* color:var(--main-color-level-7); */
}

.nws-button-col-wrapping-block {
    /* font-size:150%; */
    position:absolute;
    top:.4em;
    right:4em;
}

.nws-button-col-wrapping-col {
    /* font-size:150%; */
    position:absolute;
    top:.4em;
    right:2.5em;
}

.nws-button-col-wrapping-phone {
    /* font-size:150%; */
    position:absolute;
    top:.4em;
    right:1.5em;
}

.nws-button-gallery-tab {
    /* font-size:150%; */
    position:absolute;
    top:.4em;
    right:0;
}

i {
    margin: 0 1em 0 0;
}

i:hover {
    filter: brightness(75%);
}

/* Images */
.favicon img {
    /* color:none; */
    /* font-weight:normal; */
    /* text-decoration:none; */
    /* margin:.1em; */
    width:16px;
}

img.full {
    width:100%;
}

.audio-note {
    font-size:150%;
    color:var(--main-color-level-7);
    margin:0 .1em .1em 0;
}

/* Tabs */

/* .ui-tabs-selected span { */
/*     color:var(--main-color-level-5); */
/* } */

/* .ui-state-active, */
/* .ui-widget-content { */
/*     background: var(--main-color-level-6) !important; */
/*     font-weight: normal; */
/* } */

/* .ui-state-active a, */
/* .ui-state-active a:link, */
/* .ui-state-active a:visited { */
/*     color:var(--main-color-level-5); */
/* } */

/* .ui-widget-header { */
/*     background: #999; */
/*     /\* border: 1px solid #AAAAAA; *\/ */
/*     border: 0; */
/*     font-weight: bold; */
/* } */

/* .ui-tabs .ui-tabs-panel { */
/*     padding: .5em .2em; */
/* } */

/* Back Office */
.feedUp {
    line-height:1.5em;
    vertical-align:bottom;
}

.feedDel:hover {
    color:orange;
}

.feedUp:hover {
    color:green;
}

/* Version Checking */
#version {
    font-weight: bolder;
    float:right;
    font-size:150%;
    cursor:pointer;
    height:1.5em;
}

#version .unknown {
    color:orange;
}

#version .mns-vc-unmoved {
    color:green;
}

#version .mns-vc-moved {
    color:red;
    display:invisible;
}

.monospace {
    font-family: monospace;
}

/* Galleryshow  */

#viewer {
    z-index: 1000;
    position: fixed;
    display: none;
    /* overflow: hidden; */

    top:0 !important;
    bottom: 0;
    left: 0 !important;
    right: 0;

    margin: auto;
    /* min-width: 300px; */
}

#viewer-img {
    /* width: 500px; */
    border: 1px solid #2E3436;
}

#viewer span {
    padding: 2px;
    position: absolute;
    margin-right:5px;
    font-size: 20px;
    font-weight: bold;
    color: #333333;
    /* background-color: #ccc; */
    /* z-index: 1001; */
    cursor: pointer;
    /* border-radius: 50%; */
    opacity: 0;
    transition: .3s;
}

#viewer span:hover {
    /* box-shadow: 0px 0px 2px 1px #333333; */
    color: orange;
}

#viewer:hover span {
    opacity: 1;
}

#viewer #cross {
    top: 4px;
    left: 4px;
}

#viewer #prev {
    top: 2px;
    left: 25px;
}

#viewer #pause, #play {
    top: 2px;
    left: 46px;
}

#viewer #next {
    top: 2px;
    left: 68px;
}

#pause {
    display: none;
}

#viewer #img-name {
    font-weight: normal;
    color:#eeeeec;
    background-color: #2e3436;
    bottom: 30px;
    /* right:1px; */
    /* top: 30px; */
    /* left: -200px; */
    left:1px;
    padding: .2em .5em;
    font-size: 14px;
    text-align: left;
    border-radius: 0 5px 5px 0;
    transition: .5s;
    text-overflow: ellipsis;
}

#viewer #buttons {
    position:absolute;
    font-size:5pt;
    z-index:1001;
    width:5em;
    height:3em;
    opacity:0.5;
    font-weight: normal;
    color:#eeeeec;
    background-color: #2e3436;
    top: 1px;
    /* right:1px; */
    /* top: 30px; */
    /* left: -200px; */
    left:1px;
    padding: .2em .5em;
    font-size: 14px;
    text-align: left;
    border-radius: 0 0 5px 0;
    transition: .5s;
    text-overflow: ellipsis;
}


#viewer:hover #cross {
    left: 4px;
    z-index:1002;
}

#viewer:hover #prev {
    z-index:1002;
    left: 25px;
}

#viewer:hover #play {
    z-index:1002;
    left: 46px;
}

#viewer:hover #next {
    z-index:1002;
    left: 64px;
}

/*
 * #viewer:hover #img-name {
 *     left: 1px;
 * }
 */

.icon-home, .icon-play, .icon-pause, .icon-prev, .icon-next, .icon-arrow-left, .icon-close {
    border-radius: 0 5px 5px 0;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    font-smoothing: antialiased;
}

.icon-home:before {
	content: "\e000";
}

.icon-play:before {
	content: "▶";
}

.icon-pause:before {
	content: "■";
}

.icon-prev:before {
	content: "◁";
}

.icon-next:before {
	content: "▷";
}

.icon-arrow-left:before {
	content: "?";
}

.icon-close:before {
	content: "✖";
}

/* ◁ ▶ ▷ ■ */

/* ► Play. ▌▌ Pause. ■ Stop. */

#overlay {
    position: fixed;
    display: none;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    /* filter:alpha(opacity=80); */
    /* -moz-opacity:0.8; */
    /* -khtml-opacity: 0.8; */
    opacity: 0.9;
    z-index: 500;

    text-align: center;
    margin: auto;
}

#error {
    width: 150px;
    text-align: center;
    padding: 1em;
    /* margin: auto; */
    border: orange 1px solid;
}

.notif {
    font-weight: bold;
    padding : .5em .5em .5em 0;
    border-top : 1px solid red;
}

/* Experiments */
.elements {
  margin: 4px;
  padding: 10px 5px;
}

.element {
  padding: 4px 8px;
  cursor: move;
  /* width:24%; */
}

.element:hover {
  background-color: #f1f1f1;
}

.elements.can-drop {
  outline: 1px dashed #ccc;
}

.elements.drop-here {
  outline: 1px solid #999;
}
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

<div id="dialog" title="Tab data">
            <form>
                <fieldset class="ui-helper-reset">
                    <label for="tab_title">Title</label>
                    <input type="text" name="tab_title" id="tab_title" value="Tab Title" class="ui-widget-content ui-corner-all">
                    <label for="tab_content">Content</label>
                    <textarea name="tab_content" id="tab_content" class="ui-widget-content ui-corner-all">Tab content</textarea>
                </fieldset>
            </form>
        </div>

        <div id="tabs">
            <ul>
                <li><a href="#tabs-1">plip</a> <span class="ui-icon ui-icon-close" role="presentation">Remove Tab</span></li>
                <li><a href="#tabs-2">plop</a> <span class="ui-icon ui-icon-close" role="presentation">Remove Tab</span></li>
            </ul>
            <div id="tabs-1">
                <div class="elements grid nws-tab-feeds nws-tab-feeds-col ui-tabs-panel ui-corner-bottom ui-widget-content">
                    <div data-index="" class="element grid-item outerContainer-col outerContainer">Element 1:plip <span class="ui-icon ui-icon-close" role="presentation">Remove feed</span></div>
                    <div data-index="" class="element grid-item outerContainer-col outerContainer">Element 2:plop <span class="ui-icon ui-icon-close" role="presentation">Remove feed</span></div>
                    <div data-index="" class="element grid-item outerContainer-col outerContainer">Element 3:zob <span class="ui-icon ui-icon-close" role="presentation">Remove feed</span></div>
                </div>
            </div>
            <div id="tabs-2">
                <div class="elements grid nws-tab-feeds nws-tab-feeds-col ui-tabs-panel ui-corner-bottom ui-widget-content">
                    <div data-index="" class="element grid-item outerContainer-col outerContainer">Element 11:foo <span class="ui-icon ui-icon-close" role="presentation">Remove feed</span></div>
                    <div data-index="" class="element grid-item outerContainer-col outerContainer">Element 12:bar <span class="ui-icon ui-icon-close" role="presentation">Remove feed</span></div>
                </div>
            </div>
        </div>
        <button id="add_tab">Add Tab</button>

我制作了可以拖放的div(class="element")

  • 在他们自己的标签“dropzone”中(class="elements")
  • 到另一个标签的“dropzone”

然后我添加了一个功能来添加/删除标签;但是那些新标签不是“可放置的” :( 我想我缺少某种所有 draggabledroppable 元素重新初始化。 .?

重现:运行上面的代码片段,创建一个新选项卡,然后尝试将一个元素拖放到其中。

最佳答案

当创建新的 tab 时,您应该调用 droppable 方法。所以你应该像这样改变 addTab() 函数:

function addTab() {
    var label = tabTitle.val() || 'Tab ' + tabCounter,
        id = 'tabs-' + tabCounter,
        li = $(tabTemplate.replace(/#\{href\}/g, '#' + id).replace(/#\{label\}/g, label)),
        tabContentHtml = tabContent.val() || 'Plop Tab ' + tabCounter + ' contentz.';

    tabs.find('.ui-tabs-nav').append(li);

    // Create draggableContent element
    var draggableContent = $('<div class="elements grid nws-tab-feeds nws-tab-feeds-col ui-tabs-panel ui-corner-bottom ui-widget-content ui-droppable"><div class="element grid-item outerContainer-col outerContainer ui-draggable ui-draggable-handle">' + tabContentHtml + '<span class="ui-icon ui-icon-close" role="presentation">Remove feed</span></div></div>');
    var parentDraggableContent = $('<div class="ui-tabs-panel ui-corner-bottom ui-widget-content" id="' + id + '"></div>');
    parentDraggableContent.append(draggableContent);
    tabs.append(parentDraggableContent);

    tabCounter++;

    // Call draggable for tabContentHtml
    draggableContent.draggable({
        cursor: 'move',
    });

    // Call droppable for tab 
    li.droppable({
        accept: '.element',
        tolerance: 'pointer',
        activeClass: "can-drop",
        hoverClass: "drop-here",
        drop: function(event, ui) {
            $(this).append(ui.draggable[0]);
            // var count = $("#tabs-1 div").length;
            console.log('l: ' + $(this).children().length);
        }
    });

    tabs.tabs("refresh");
}

关于javascript - 如何使新的 JqueryUI 选项卡实例可删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46407028/

相关文章:

jquery - 如何通过ajax将项目ID发送到服务器: jquery sortable

javascript - Netbeans javascript 缩进括号过多

ios - 在选项卡栏 Controller 中将数据从一个 View 传递到另一个 View 未按时传递

javascript - EXT JS 够快吗?

javascript - 使用 Vue.js 如何刷新使用 lodash 去抖动的方法?

javascript - 使用 HTML 将待办事项列表数据保存到本地存储

javascript - 使用 jQuery Sortable 排序和保存选项卡 + 字段

html - 需要帮助将 HTML+CSS 选项卡移动到相应的内容 Pane 下方

javascript - 无法调用未定义的 app.js :1 sencha nested 的方法 'substring'

javascript - onblur 事件未触发