jQuery、bootstrap 选项卡和 CodeMirror.refresh()
jQuery, bootstrap tabs and CodeMirror.refresh()
我在单击树视图中的 link 时创建选项卡。在该选项卡中,创建了另外两个选项卡,并且在它们中有转换为 CodeMirror 的文本区域。在创建 CodeMirror 实例时,我遇到了很多问题,通常我的问题与 .refresh()
事件有关。
CodeMirror 没有完全加载到不活动的选项卡中,因此我在创建实例时添加了一些更改,并将它们全部收集在数组中,稍后我在代码循环中使用 .refresh()
以便 CodeMirror 编辑器完全加载。
在我这样做之前,CodeMirror 被添加到我在单击时创建的所有选项卡中的所有文本区域,但我总是刷新所有 CodeMirror 实例,而不仅仅是新选项卡中的实例。这导致在另一个选项卡中输入的值被清除。
因此,对于新的更改,我只刷新在新选项卡中创建的当前 CodeMirror 实例。但是现在,通过此更改,所有仍处于打开状态的旧选项卡中的 CodeMirror(顺便说一句,可以关闭选项卡)消失了。所以现在我想知道,CodeMirror.refresh()
会刷新整个页面吗?
下面是我的代码的一部分,创建 CodeMirror 实例的部分。我认为创建选项卡的代码与此功能障碍没有任何关系:
/* 添加 CodeMirror 转换所有文本框,需要超时,直到加载所有 dom 元素 */
setTimeout(function () {
var textAreaId = 0;
$(".AI-textarea").each(function () {
$(this).attr("id", "text" + textAreaId);
++textAreaId;
});
var queryArr = [];
var dimensionArr = [];
var queryBuilder = $(tabPanelDiv).find(".QueryBuilder");
queryBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
queryArr.push(editorQuery);
});
var dimensionBuilder = $(tabPanelDiv).find(".DimensionBuilder");
dimensionBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
dimensionArr.push(editorQuery);
});
for (var i = 0; i < queryArr.length; i++) {
queryArr[i].refresh();
}
for (var a = 0; a < dimensionArr.length; a++) {
dimensionArr[a].refresh();
}
}, 100);
我必须让 setTimeout 函数中的代码等待创建文本区域。该函数在点击事件中。
是否有人可以指出可能导致 CodeMirror 从旧选项卡中的 Dom 消失的原因?是 CodeMirror.refresh()
事件还是点击事件做了我不知道的事情?正在创建新选项卡时,最后一个 CodeMirror 实例是否丢失?
下面是两个选项卡的屏幕截图,第一个显示了全新选项卡的外观。第二个显示旧选项卡的外观,应该看起来一样。
编辑
这是完整的点击事件,如果有帮助,也许是代码中较早的部分导致了这个?很抱歉混用 javascript 和 jquery,可能需要重写。
$(".treeviewLinks").click(function (e) {
e.preventDefault();
var targetElement = e.target || e.srcElement;
/*** Create everything for the upper tabs that open when tree view link is clicked ***/
if ($(".tabHelper").find("#upperTab").length == 0) {
var ul = document.createElement("ul");
ul.className = "nav nav-tabs";
ul.id = "upperTab";
ul.setAttribute("role", "tablist");
$(".tabHelper").append(ul);
}
var ul = $("#upperTab");
var id = $('#upperTab li').size() + 1;
var li = document.createElement("li");
var a = document.createElement("a");
var span = document.createElement("span");
li.setAttribute("role", "presentation");
a.href = "#" + id;
a.setAttribute("aria-controls", id);
a.setAttribute("role", "tab");
a.setAttribute("data-toggle", "tab");
span.className = "glyphicon glyphicon-remove pull-right exit";
a.innerHTML = targetElement.innerHTML;
if ($(".tabHelper").find(".tab-content").length == 0) {
var tabContentDiv = document.createElement("div");
tabContentDiv.className = "tab-content";
}
$(".tabHelper").append(tabContentDiv);
var tabContentDiv = $(".tabHelper").find(".tab-content").first();
var tabPanelDiv = document.createElement("div");
tabPanelDiv.className = "tab-pane"
tabPanelDiv.id = id;
tabPanelDiv.setAttribute("role", "tabpanel");
ul.append(li);
li.appendChild(a);
a.appendChild(span);
tabContentDiv.append(tabPanelDiv);
var upperTab = document.getElementById("upperTab");
var tabContent = document.getElementsByClassName("tab-content")[0];
var cId = $(tabContent).size() + 1;
if (id == 1) {
var tmpLi = upperTab.firstChild;
tmpLi.className = "active";
}
else if (id > 1) {
$(li).siblings().removeClass("active");
li.className = "active";
}
if (cId == 1) {
var tmpTabPane = tabContent.firstChild;
tmpTabPane.className += " active";
}
else if (cId > 1) {
$(tabPanelDiv).siblings().removeClass("active");
tabPanelDiv.className += " active";
}
/*** Create ul for nav-tabs and tab-content for query and dimension builder tabs ***/
var qdUl = document.createElement("ul");
qdUl.className = "nav nav-tabs query-dimension-tabs";
qdUl.setAttribute("role", "tablist");
var qdDiv = document.createElement("div");
qdDiv.className = "tab-content query-dimsension-tabs-content";
for (var i = 0; i < tabContent.childNodes.length; i++) {
var item = $(tabContent.childNodes[i]);
if (item.children().length < 1) {
item.append(qdUl);
item.append(qdDiv);
}
}
/*** Create li in nav-tabs and tab-panel in tab-content for query and dimension builder tabs ***/
var qLi = document.createElement("li");
var dLi = document.createElement("li");
qLi.setAttribute("role", "presentation");
qLi.className = "active";
dLi.setAttribute("role", "presentation");
var navTabs = $(".query-dimension-tabs");
var qA = document.createElement("a");
var dA = document.createElement("a");
qA.setAttribute("role", "tab");
qA.setAttribute("data-toggle", "tab");
qA.innerHTML = "Query Builder";
dA.setAttribute("role", "tab");
dA.setAttribute("data-toggle", "tab");
dA.innerHTML = "Dimension Builder";
for (var i = 0; i < navTabs.length; i++) {
var item = $(navTabs[i]);
if (item.children().length < 1) {
item.append(qLi);
item.append(dLi);
qLi.appendChild(qA);
dLi.appendChild(dA);
}
}
var qdId = 0;
$(".query-dimension-tabs").each(function () {
$(this).find("a").each(function () {
$(this).attr("href", "#tab" + qdId);
$(this).attr("aria-controls", "tab" + qdId);
++qdId;
});
});
var tabPane1 = document.createElement("div");
var tabPane2 = document.createElement("div");
tabPane1.className = "tab-pane active";
tabPane1.setAttribute("role", "tabpanel");
tabPane2.className = "tab-pane";
tabPane2.setAttribute("role", "tabpanel");
$(".tab-content:not(:first)").each(function () {
$(this).append(tabPane1);
$(this).append(tabPane2);
});
var pId = 0;
$(".query-dimsension-tabs-content").each(function () {
$(this).find(".tab-pane").each(function () {
$(this).attr("id", "tab" + pId);
++pId;
});
if (!($.contains($(this), "form"))) {
var firstPane = $($(this).children()[0]);
var secondPane = $($(this).children()[1]);
firstPane.load("/Webfront/QueryBuilder");
secondPane.load("/Webfront/DimensionBuilder");
}
});
//var url = '@Url.Action("QueryDimensionTab", "Webfront")';
/*** Add CodeMirror to convert all textboxes, needs timeout until all dom elements are loaded ***/
setTimeout(function () {
var textAreaId = 0;
$(".AI-textarea").each(function () {
$(this).attr("id", "text" + textAreaId);
++textAreaId;
});
var queryArr = [];
var dimensionArr = [];
var queryBuilder = $(tabPanelDiv).find(".QueryBuilder");
queryBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
queryArr.push(editorQuery);
});
var dimensionBuilder = $(tabPanelDiv).find(".DimensionBuilder");
dimensionBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
dimensionArr.push(editorQuery);
});
for (var i = 0; i < queryArr.length; i++) {
queryArr[i].refresh();
}
for (var a = 0; a < dimensionArr.length; a++) {
dimensionArr[a].refresh();
}
}, 100);
});
我找到了导致 CodeMirror 旧实例消失的原因。这是因为我在 jQuery .each()
中加载表单,它循环遍历所有具有这些表单的 div。我将负载移到它外面并修复了它。
旧代码:
var pId = 0;
$(".query-dimsension-tabs-content").each(function () {
$(this).find(".tab-pane").each(function () {
$(this).attr("id", "tab" + pId);
++pId;
});
if (!($.contains($(this), "form"))) {
var firstPane = $($(this).children()[0]);
var secondPane = $($(this).children()[1]);
firstPane.load("/Webfront/QueryBuilder");
secondPane.load("/Webfront/DimensionBuilder");
}
});
新代码:
var pId = 0;
$(".query-dimsension-tabs-content").each(function () {
$(this).find(".tab-pane").each(function () {
$(this).attr("id", "tab" + pId);
++pId;
});
});
var formToLoad = $($(tabPanelDiv).children()[1]);
var firstPane = $($(formToLoad)[0].firstChild);
var secondPane = $($(formToLoad)[0].lastChild);
firstPane.load("/Webfront/QueryBuilder");
secondPane.load("/Webfront/DimensionBuilder");
如果有人对我如何以不同的方式在 jQuery 中动态加载这些部分视图有建议或想法,我们将不胜感激。我认为这可能不是最好的方法。
我在单击树视图中的 link 时创建选项卡。在该选项卡中,创建了另外两个选项卡,并且在它们中有转换为 CodeMirror 的文本区域。在创建 CodeMirror 实例时,我遇到了很多问题,通常我的问题与 .refresh()
事件有关。
CodeMirror 没有完全加载到不活动的选项卡中,因此我在创建实例时添加了一些更改,并将它们全部收集在数组中,稍后我在代码循环中使用 .refresh()
以便 CodeMirror 编辑器完全加载。
在我这样做之前,CodeMirror 被添加到我在单击时创建的所有选项卡中的所有文本区域,但我总是刷新所有 CodeMirror 实例,而不仅仅是新选项卡中的实例。这导致在另一个选项卡中输入的值被清除。
因此,对于新的更改,我只刷新在新选项卡中创建的当前 CodeMirror 实例。但是现在,通过此更改,所有仍处于打开状态的旧选项卡中的 CodeMirror(顺便说一句,可以关闭选项卡)消失了。所以现在我想知道,CodeMirror.refresh()
会刷新整个页面吗?
下面是我的代码的一部分,创建 CodeMirror 实例的部分。我认为创建选项卡的代码与此功能障碍没有任何关系:
/* 添加 CodeMirror 转换所有文本框,需要超时,直到加载所有 dom 元素 */
setTimeout(function () {
var textAreaId = 0;
$(".AI-textarea").each(function () {
$(this).attr("id", "text" + textAreaId);
++textAreaId;
});
var queryArr = [];
var dimensionArr = [];
var queryBuilder = $(tabPanelDiv).find(".QueryBuilder");
queryBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
queryArr.push(editorQuery);
});
var dimensionBuilder = $(tabPanelDiv).find(".DimensionBuilder");
dimensionBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
dimensionArr.push(editorQuery);
});
for (var i = 0; i < queryArr.length; i++) {
queryArr[i].refresh();
}
for (var a = 0; a < dimensionArr.length; a++) {
dimensionArr[a].refresh();
}
}, 100);
我必须让 setTimeout 函数中的代码等待创建文本区域。该函数在点击事件中。
是否有人可以指出可能导致 CodeMirror 从旧选项卡中的 Dom 消失的原因?是 CodeMirror.refresh()
事件还是点击事件做了我不知道的事情?正在创建新选项卡时,最后一个 CodeMirror 实例是否丢失?
下面是两个选项卡的屏幕截图,第一个显示了全新选项卡的外观。第二个显示旧选项卡的外观,应该看起来一样。
编辑
这是完整的点击事件,如果有帮助,也许是代码中较早的部分导致了这个?很抱歉混用 javascript 和 jquery,可能需要重写。
$(".treeviewLinks").click(function (e) {
e.preventDefault();
var targetElement = e.target || e.srcElement;
/*** Create everything for the upper tabs that open when tree view link is clicked ***/
if ($(".tabHelper").find("#upperTab").length == 0) {
var ul = document.createElement("ul");
ul.className = "nav nav-tabs";
ul.id = "upperTab";
ul.setAttribute("role", "tablist");
$(".tabHelper").append(ul);
}
var ul = $("#upperTab");
var id = $('#upperTab li').size() + 1;
var li = document.createElement("li");
var a = document.createElement("a");
var span = document.createElement("span");
li.setAttribute("role", "presentation");
a.href = "#" + id;
a.setAttribute("aria-controls", id);
a.setAttribute("role", "tab");
a.setAttribute("data-toggle", "tab");
span.className = "glyphicon glyphicon-remove pull-right exit";
a.innerHTML = targetElement.innerHTML;
if ($(".tabHelper").find(".tab-content").length == 0) {
var tabContentDiv = document.createElement("div");
tabContentDiv.className = "tab-content";
}
$(".tabHelper").append(tabContentDiv);
var tabContentDiv = $(".tabHelper").find(".tab-content").first();
var tabPanelDiv = document.createElement("div");
tabPanelDiv.className = "tab-pane"
tabPanelDiv.id = id;
tabPanelDiv.setAttribute("role", "tabpanel");
ul.append(li);
li.appendChild(a);
a.appendChild(span);
tabContentDiv.append(tabPanelDiv);
var upperTab = document.getElementById("upperTab");
var tabContent = document.getElementsByClassName("tab-content")[0];
var cId = $(tabContent).size() + 1;
if (id == 1) {
var tmpLi = upperTab.firstChild;
tmpLi.className = "active";
}
else if (id > 1) {
$(li).siblings().removeClass("active");
li.className = "active";
}
if (cId == 1) {
var tmpTabPane = tabContent.firstChild;
tmpTabPane.className += " active";
}
else if (cId > 1) {
$(tabPanelDiv).siblings().removeClass("active");
tabPanelDiv.className += " active";
}
/*** Create ul for nav-tabs and tab-content for query and dimension builder tabs ***/
var qdUl = document.createElement("ul");
qdUl.className = "nav nav-tabs query-dimension-tabs";
qdUl.setAttribute("role", "tablist");
var qdDiv = document.createElement("div");
qdDiv.className = "tab-content query-dimsension-tabs-content";
for (var i = 0; i < tabContent.childNodes.length; i++) {
var item = $(tabContent.childNodes[i]);
if (item.children().length < 1) {
item.append(qdUl);
item.append(qdDiv);
}
}
/*** Create li in nav-tabs and tab-panel in tab-content for query and dimension builder tabs ***/
var qLi = document.createElement("li");
var dLi = document.createElement("li");
qLi.setAttribute("role", "presentation");
qLi.className = "active";
dLi.setAttribute("role", "presentation");
var navTabs = $(".query-dimension-tabs");
var qA = document.createElement("a");
var dA = document.createElement("a");
qA.setAttribute("role", "tab");
qA.setAttribute("data-toggle", "tab");
qA.innerHTML = "Query Builder";
dA.setAttribute("role", "tab");
dA.setAttribute("data-toggle", "tab");
dA.innerHTML = "Dimension Builder";
for (var i = 0; i < navTabs.length; i++) {
var item = $(navTabs[i]);
if (item.children().length < 1) {
item.append(qLi);
item.append(dLi);
qLi.appendChild(qA);
dLi.appendChild(dA);
}
}
var qdId = 0;
$(".query-dimension-tabs").each(function () {
$(this).find("a").each(function () {
$(this).attr("href", "#tab" + qdId);
$(this).attr("aria-controls", "tab" + qdId);
++qdId;
});
});
var tabPane1 = document.createElement("div");
var tabPane2 = document.createElement("div");
tabPane1.className = "tab-pane active";
tabPane1.setAttribute("role", "tabpanel");
tabPane2.className = "tab-pane";
tabPane2.setAttribute("role", "tabpanel");
$(".tab-content:not(:first)").each(function () {
$(this).append(tabPane1);
$(this).append(tabPane2);
});
var pId = 0;
$(".query-dimsension-tabs-content").each(function () {
$(this).find(".tab-pane").each(function () {
$(this).attr("id", "tab" + pId);
++pId;
});
if (!($.contains($(this), "form"))) {
var firstPane = $($(this).children()[0]);
var secondPane = $($(this).children()[1]);
firstPane.load("/Webfront/QueryBuilder");
secondPane.load("/Webfront/DimensionBuilder");
}
});
//var url = '@Url.Action("QueryDimensionTab", "Webfront")';
/*** Add CodeMirror to convert all textboxes, needs timeout until all dom elements are loaded ***/
setTimeout(function () {
var textAreaId = 0;
$(".AI-textarea").each(function () {
$(this).attr("id", "text" + textAreaId);
++textAreaId;
});
var queryArr = [];
var dimensionArr = [];
var queryBuilder = $(tabPanelDiv).find(".QueryBuilder");
queryBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
queryArr.push(editorQuery);
});
var dimensionBuilder = $(tabPanelDiv).find(".DimensionBuilder");
dimensionBuilder.each(function (index, el) {
var editorQuery = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabMode: "indent",
mode: "text/x-sql",
theme: "eclipse"
});
dimensionArr.push(editorQuery);
});
for (var i = 0; i < queryArr.length; i++) {
queryArr[i].refresh();
}
for (var a = 0; a < dimensionArr.length; a++) {
dimensionArr[a].refresh();
}
}, 100);
});
我找到了导致 CodeMirror 旧实例消失的原因。这是因为我在 jQuery .each()
中加载表单,它循环遍历所有具有这些表单的 div。我将负载移到它外面并修复了它。
旧代码:
var pId = 0;
$(".query-dimsension-tabs-content").each(function () {
$(this).find(".tab-pane").each(function () {
$(this).attr("id", "tab" + pId);
++pId;
});
if (!($.contains($(this), "form"))) {
var firstPane = $($(this).children()[0]);
var secondPane = $($(this).children()[1]);
firstPane.load("/Webfront/QueryBuilder");
secondPane.load("/Webfront/DimensionBuilder");
}
});
新代码:
var pId = 0;
$(".query-dimsension-tabs-content").each(function () {
$(this).find(".tab-pane").each(function () {
$(this).attr("id", "tab" + pId);
++pId;
});
});
var formToLoad = $($(tabPanelDiv).children()[1]);
var firstPane = $($(formToLoad)[0].firstChild);
var secondPane = $($(formToLoad)[0].lastChild);
firstPane.load("/Webfront/QueryBuilder");
secondPane.load("/Webfront/DimensionBuilder");
如果有人对我如何以不同的方式在 jQuery 中动态加载这些部分视图有建议或想法,我们将不胜感激。我认为这可能不是最好的方法。