2014-10-21 20 views
6

Tôi có một trang khá phức tạp nơi tôi có một số phiên bản của CodeMirror trong các tab ẩn trong các tab. Để sau đó làm cho nó phức tạp hơn, tôi nhớ các tab hoạt động cuối cùng.Các tab Bootstrap với CodeMirror

Tôi đã quản lý để có được nó một nửa làm việc (http://codepen.io/anon/pen/LheaF) vấn đề là với các tab Second Editor:

  1. nó tải các tab thứ hai trước khi các tab Mã Gương chính đã được nhấp vào. Khi bạn bấm vào tab Mã Phản chiếu, nó sẽ không tải chính xác trình soạn thảo, cho đến khi bạn bấm hai lần.
  2. Tôi muốn các tab thứ hai gọi phương thức refresh() nếu phương thức của nó đã được khởi tạo, như tôi làm cho trình chỉnh sửa chính.
  3. Bug nơi sao chép nó các biên tập viên thứ

(function($) { 
    var mainEditor; 

    function initMainCodeEditor() { 
     if (mainEditor instanceof CodeMirror) { 
      mainEditor.refresh(); 
     } else { 
      // Load main editor 
      var el = document.getElementById("codifyme"); 
      mainEditor = CodeMirror.fromTextArea(el, { 
       lineNumbers: true 
      }); 
      mainEditor.setSize('100%', 50); 
     } 
    } 

    function initSecondaryCodeEditor() { 
     var $active = $('#code_mirror_editors > .active > a'); 
     var $sec_tab = $($active.data('target')); 

     CodeMirror.fromTextArea($sec_tab.find('textarea')[0], { 
      lineNumbers: true 
     }); 
    } 

    $(document).ready(function() { 

     // Only load editors if tab has been clicked 
     $('#maintabs > li > a[data-target="#codemirror"]').on('shown.bs.tab', function(e) { 
      initMainCodeEditor(); 
     }); 

     $('#code_mirror_editors > li > a[data-toggle="tab"]').on('shown.bs.tab', function(e) { 
      initSecondaryCodeEditor(); 
     }); 

     // Remember tabs 
     var json, tabsState; 
     $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) { 
      tabsState = localStorage.getItem("tabs-state"); 
      json = JSON.parse(tabsState || "{}"); 
      json[$(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id")] = $(e.target).data('target'); 

      localStorage.setItem("tabs-state", JSON.stringify(json)); 
     }); 

     tabsState = localStorage.getItem("tabs-state"); 

     json = JSON.parse(tabsState || "{}"); 
     $.each(json, function(containerId, target) { 
      return $("#" + containerId + " a[data-target=" + target + "]").tab('show'); 
     }); 

     $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() { 
      var $this = $(this); 
      if (!json[$this.attr("id")]) { 
       return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show"); 
      } 
     }); 

    }); // doc.ready 
})(jQuery); 

Trả lời

5

Những vấn đề:

  1. nó có thể xảy ra mà bạn tạo ra các CodeMirror trên một yếu tố mà không phải là có thể nhìn thấy (một trong những cha mẹ của nó có display: none). Điều này phá vỡ tính toán khác nhau được thực hiện bởi CodeMirror
  2. bằng cách nhận các trường hợp CodeMirror ngay từ yếu tố container CodeMirror cho phép chúng tôi gọi refresh mọi lúc bạn muốn (bằng cách tìm các .CodeMirror bên cạnh textarea của bạn)
  3. cố định như một tác dụng phụ của 2.

xem phiên bản cập nhật tại đây: http://codepen.io/lloiser/pen/arBkv

bạn có thể thấy những thay đổi của tôi trong tìm codepen cho // --> comments

3

Giải pháp làm việc:http://codepen.io/anon/pen/hupwy

tôi giải quyết vấn đề 2 và 3 như tôi không thể nhân rộng 1.

tôi đã sử dụng bảng băm để lưu trữ đối tượng Trình soạn thảo CodeMirror thứ hai. Sau đó, tôi đã sửa đổi mã mainEditor hiện tại của bạn để làm mới các đối tượng nếu chúng đã tồn tại.

var seccondEditor = new Object(); 
function initSecondaryCodeEditor(){ 
    var $active = $('#code_mirror_editors > .active > a');  
    var $sec_tab = $($active.data('target')); 
    var sec_edi = ($sec_tab.find('textarea')[0]); 
    if(seccondEditor[sec_edi.id] instanceof CodeMirror){ 
      seccondEditor[sec_edi.id].refresh(); 
     } else { 
    seccondEditor[sec_edi.id] = CodeMirror.fromTextArea(sec_edi, {lineNumbers: true}); 
    } 
} 

Tôi không thạo trong CodeMirror vì vậy đây không thể là giải pháp thanh lịch nhất, nhưng có vẻ như các mã trên ngăn các bản sao bạn đang nhìn thấy. Hi vọng điêu nay co ich.

0

Tại sao không chỉ để thiết lập thời gian chờ .. chỉ exec mã mà khi tab nhấp:

update_mirror = function() { 
    var codeMirrorContainer = $sec_tab.find(".CodeMirror")[0]; 
    if (codeMirrorContainer && codeMirrorContainer.CodeMirror) { 
    codeMirrorContainer.CodeMirror.refresh(); 
    } 
} 
// Attention! magic! 
setTimeout(update_mirror, 100); 

Điều đó đã giúp tôi rất nhiều khi tôi đã có một cuộc chiến chống lại vấn đề đó. Nhờ có Sekaryo Shin, anh ấy đã tiết kiệm thời gian của tôi.

1

nếu sự cố xảy ra khi mã hóa hiển thị nội dung trong div bị ẩn, tại sao không chỉ xử lý tất cả div bảng điều khiển, sau đó gọi mã hóa, sau đó ẩn tab không cần thiết ??

HTML:

<div role="tabpanel" class="tab-pane active" id="tp1"> 
     <textarea class="code" data-lang="text/html"> 
      <!--- content #1 here --> 
     </textarea> 
    </div> 
    <div role="tabpanel" class="tab-pane active hideAfterRendering" id="tp2"> 
     <textarea class="code" data-lang="text/html"> 
      <!--- content #2 here --> 
     </textarea> 
    </div> 
    <div role="tabpanel" class="tab-pane active hideAfterRendering" id="tp3"> 
     <textarea class="code" data-lang="text/html"> 
      <!--- content #3 here --> 
     </textarea> 
    </div> 

SCRIPT:

<script> 
     $(document).ready(function() { 
      //render codeMirror 
      $('.code').each(function() { 
       CodeMirror.fromTextArea(this, { 
        mode: "properties", 
        lineNumbers: true, 
        indentUnit: 4, 
        readOnly: true, 
        matchBrackets: true 
       }); 
      }); 
      //hide tab-panel after codeMirror rendering (by removing the extra 'active' class 
      $('.hideAfterRendering').each(function() { 
       $(this).removeClass('active') 
      }); 
     }); 
    </script> 

trình tốt cho tôi !!

0

HTML

Đây là khung thẻ bootstrap, nếu bạn sử dụng jquery-UI, sẽ hơi khác một chút.

<ul class="nav nav-tabs"> 
    <li class="active"><a href="#tab1" data-toggle="tab">tab1</a></li> 
    <li><a href="#tab2" data-toggle="tab">tab2</a></li> 
</ul> 

<div class="tab-content"> 
    <div class="tab-pane fade in active" id="tab1"><textarea type="text" id="tab1Content" name="xxx"></textarea></div>  
    <div class="tab-pane fade" id="tab2"><textarea type="text" id="tab2Content" name="yyy"></textarea></div> 
</div> 

JS

var cm1, cm2; 
$(document).ready(function() { 
    //when the bootstrap tab is fully shown, call codemirror's refresh(). 
    //Also, if you use jquery-UI, it's gonna be different here. 
    $('.nav-tabs a').on('shown.bs.tab', function() { 
     cm1.refresh(); 
     cm2.refresh(); 
    }); 
    cm1 = CodeMirror.fromTextArea(document.getElementById("tab1Content"), { 
     lineNumbers: true 
    }); 
    cm2 = CodeMirror.fromTextArea(document.getElementById("tab2Content"), { 
     lineNumbers: true 
    }); 
}); 
Các vấn đề liên quan