Я работаю над проектом, который начинался как просто создание функции, которая принимает аргумент (XML файл) и преобразует его в структуру HTML/CSS (более ранняя версия, которую можно найти здесь). Это отлично поработало. Тем не менее, я бы хотел реализовать больше возможностей и большую гибкость. Я прочитал эту тему (например, 1, 2, 3), но я не могу обвести вокруг него голову.
Мой плагин имеет множество специфичных для экземпляра запросов:
- Переменные
- Параметры
- обработчики событий
и есть несколько важных вариантов:
- отобразить полноэкранную версию
- отображает обычную версию (поставляется с кнопкой "open fs version" ).
- укажите контейнер для нормальной версии
- установить шрифт нормальной версии
- установить возможные шрифты для версии fs (для увеличения и уменьшения дерева)
- установите класс, который, когда пользователь нажимает на элемент с этим классом, открывает версию fs
Я нарисую базовую структуру текущего состояния плагина.
Два первых варианта - самые важные. Но по умолчанию используется true
, и если у пользователя есть оба из них на false
, плагин не будет выполняться.
Затем плагин назначает глобальные переменные и создает новые элементы DOM на основе этой информации. На практике это выглядит примерно так (обратите внимание, что глобальные переменные объявляются в верхней части моего script).
function initVars(args) {
fontsizes = fsFontSizes;
errorContainer = $(".tv-error");
var trees = [],
tooltips = [];
if (args.normalView) {
normalView = true;
$(args.container).append('<div id="tree-visualizer" style="display: none"></div>');
SS = $("#tree-visualizer");
var SSHTML = '<div class="tv-error" style="display: none"><p></p></div>' +
'<div class="tree" style="font-size: ' + args.fontSize + 'px;"></div>' +
'<aside class="tooltip" style="display: none"><ul></ul>' +
'<button>✕</button></aside>';
if (args.fsView) {
SSHTML += '<button class="tv-show-fs">Fullscreen</button>';
}
SS.append(SSHTML);
treeSS = SS.find(".tree");
tooltipSS = SS.find(".tooltip");
trees.push("#tree-visualizer .tree");
tooltips.push("#tree-visualizer .tooltip");
}
if (args.fsView) {
fsView = true;
$("body").append('<div id="fs-tree-visualizer-" class=""fs-tree-visualizer" style="display: none"></div>');
FS = $("#fs-tree-visualizer");
var FSHTML = '<div class="tv-error" style="display: none"><p></p></div>' +
'<div class="tree"></div><aside class="tooltip" style="display: none"><ul></ul>' +
'<button>✕</button></aside><div class="zoom-opts"><button class="zoom-out">-</button>' +
'<button class="zoom-default">Default</button><button class="zoom-in">+</button>' +
'<button class="close">✕</button></div>';
FS.hide().append(FSHTML);
treeFS = FS.find(".tree");
tooltipFS = FS.find(".tooltip");
zoomOpts = FS.find(".zoom-opts");
zoomCounter = Math.round(fontSizes.length / 2);
trees.push("#fs-tree-visualizer .tree");
tooltips.push("#fs-tree-visualizer .tooltip");
}
if (args.fsBtn != "") {
$(args.fsBtn).addClass("tv-show-fs");
}
anyTree = $(trees.join());
anyTooltip = $(tooltips.join());
}
Вы увидите, что я работаю с идентификаторами, что затрудняет работу с несколькими экземплярами. Один из способов решения этого вопроса, я думал, - добавить класс для стилизации и добавить идентификатор к каждому экземпляру с помощью глобального счетчика, который отслеживает экземпляры (counter++
для каждого экземпляра). Обратите внимание, что anyTree
используется, когда я хочу настроить таргетинг на дерево FS, а также на дерево нормальных представлений. Это НЕ означает, что я хочу настроить таргетинг на все деревья всех экземпляров! Это должно быть ограничено и для каждого экземпляра.
Итак, мой вопрос: как мне разрешить несколько экземпляров и особенно: как я могу перейти от глобальных переменных к локальным переменным, не теряя при этом силы, которые у меня есть сейчас? В этот момент я могу работать с глобальными переменными и получать доступ к каждой переменной везде, где захочу. Но как я могу ограничить глобальную переменную на один экземпляр? Работайте с этим счетчиком, как я предложил?
Также, где я могу назначить события? В настоящее время это так, как мой плагин инициализирует (я оставил глобальные переменные и функции):
$.treeVisualizer = function(xml, options) {
var args = $.extend({}, $.treeVisualizer.defaults, options);
/* At least one of the arguments (default true) have to be true */
if (args.normalView || args.fsView) {
initVars(args);
loadXML(xml);
} else {
console.error("Cannot initialize Tree Visualizer: either the container " +
"does not exist, or you have set both normal and fullscreen view to " +
"false, which does not make sense.");
}
/* Event handlers -- only after we've initiated the variables to globals */
$(document).ready(function() {
// Show fs-tree-visualizer tree
$(".tv-show-fs").click(function(e) {
// Show corresponding fullscreen version
FS.show();
// Execute some functions
sizeTreeFS();
e.preventDefault();
});
// Zooming
zoomOpts.find("button").click(function() {
var $this = $(this);
// Do something
});
anyTree.on("click", "a", function(e) {
// Do something, and execute function: has to
// target the right tooltip
tooltipPosition();
e.preventDefault();
});
});
}
Это подходящее место для размещения обработчиков событий?