CodeMirror的Bootstrap选项卡

时间:2014-10-21 13:01:28

标签: javascript jquery twitter-bootstrap codemirror

我有一个非常复杂的页面,我在选项卡中的隐藏选项卡中有许多CodeMirror实例。为了使它更加复杂,我记得最后一个活动标签。

我设法让它工作一半(http://codepen.io/anon/pen/LheaF)问题出现在第二个编辑标签中:

  1. 在单击主Code Mirror选项卡之前加载第二个选项卡。当您单击“代码镜像”选项卡时,它也不会正确加载编辑器,直到您单击两次。
  2. 我希望第二个标签调用refresh()方法(如果它已经启动),就像我对主编辑一样。
  3. 其中复制辅助编辑器的错误

  4. (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);
    

5 个答案:

答案 0 :(得分:6)

问题:

  1. 可能会在一个不可见的元素上创建CodeMirror(其中一个父元素的display:none)。这打破了CodeMirror
  2. 所做的各种计算
  3. 通过从CodeMirror容器元素获取CodeMirror实例,我们可以随时调用刷新(通过查找.CodeMirror旁边的textarea
  4. 固定为2的副作用。
  5. 请在此处查看更新版本:http://codepen.io/lloiser/pen/arBkv

    您可以在codepen中查看我的更改,以查找// -->条评论

答案 1 :(得分:3)

工作解决方案: http://codepen.io/anon/pen/hupwy

我解决了问题2和3,因为我无法复制1。

我使用哈希表来存储第二个编辑器CodeMirror对象。然后,我修改了现有的mainEditor代码,以刷新已存在的对象。

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});
  }
}

我不熟悉CodeMirror,所以这可能不是最优雅的解决方案,但看起来上面的代码可以防止您看到的重复项。希望这会有所帮助。

答案 2 :(得分:1)

如果codemirror在隐藏div中呈现内容时出现问题,为什么不直接显示所有tab-panel div,然后调用codemirror,然后隐藏不需要的tab?

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>

对我有用!!

答案 3 :(得分:1)

HTML

这是一个引导标签框架,如果你使用jquery-UI,它会有点不同。

<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
    });
});

答案 4 :(得分:0)

为什么不设置超时?..只需在单击选项卡时执行该代码:

dimensions="ga:previousPagePath,ga:PagePath"

在我遇到这个问题的斗争中,这对我帮助很大。感谢Sekaryo Shin,他节省了我的时间。