Google Compiler не назначает пустые массивы переменным?
Так что я довольно новичок в использовании Google Compiler и столкнулся с несколькими проблемами. Во-первых, в моем предварительно обработанном коде я устанавливаю пустой массив для переменной, которая будет заполнена позже, но при компиляции она полностью удаляет переменную, так что она становится неопределенной при попытке использовать ее позже.
Вот код, который я немного изменил. Строка 19 заканчивается удалением, поэтому rowDivs отображается как неопределенное в строке 44:
/**
* Equal Heights
*
* @see https://css-tricks.com/equal-height-blocks-in-rows/
*/
goog.provide('EqualHeights');
(function($) {
// = Equalize columns on load and resize
equal_heights();
$(window).resize(function() {
equal_heights();
})
var currentTallest = 0;
var currentRowStart = 0;
var rowDivs = new Array();
function setConformingHeight(el, newHeight) {
// set the height to something new, but remember the original height in case things change
el.data("originalHeight", (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight")));
el.height(newHeight);
}
function getOriginalHeight(el) {
// if the height has changed, send the originalHeight
return (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight"));
}
function equal_heights() {
// find the tallest DIV in the row, and set the heights of all of the DIVs to match it.
$('[data-equalizer-watch]').each(function() {
// "caching"
var $el = $(this);
var topPosition = $el.position().top;
if (currentRowStart != topPosition) {
// we just came to a new row. Set all the heights on the completed row
for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) setConformingHeight(rowDivs[currentDiv], currentTallest);
// set the variables for the new row
rowDivs.length = 0;
// empty the array
currentRowStart = topPosition;
currentTallest = getOriginalHeight($el);
rowDivs.push($el);
}
else {
// another div on the current row. Add it to the list and check if it's taller
rowDivs.push($el);
currentTallest = (currentTallest < getOriginalHeight($el)) ? (getOriginalHeight($el)) : (currentTallest);
}
});
// do the last row
for (currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) {
setConformingHeight(rowDivs[currentDiv], currentTallest);
}
}
})(jQuery);
Для настроек компилятора я использую следующие флаги. Обратите внимание, что я даже не использую уровень сложности продвинутой оптимизации:
--closure_entry_point main.js
--externs node_modules/google-closure-compiler/contrib/externs/jquery-1.9.js
--language_in ECMASCRIPTS5
--warning_level: VERBOSE
Я, наверное, упускаю что-то очевидное, но просто хочу встать на правильный путь. Благодарю.
1 ответ
В режиме простой компиляции локальные переменные минимизируются и потенциально удаляются, если не используются. Вероятно, происходит следующее: на основе указанной вами точки входа компилятор замыкания определяет, что rowDivs
никогда не может использоваться.
Для исправления нужно сообщить компилятору замыкания больше информации.
(Отказ от ответственности: я никогда не использовал jquery, поэтому я могу быть не в курсе. Я также никогда не использовал узлы или модули, и есть специальные способы написания для тех, с которыми я не знаком.)
Одна вещь, чтобы попробовать это специальный флаг для jquery: --process_jquery_primitives
см. https://github.com/google/closure-compiler/wiki/jQuery-Expansions
JQuery-1.9 Extern определяет $
как глобальная переменная, поэтому вам не нужно передавать ее в вашу функцию.
Вам может потребоваться указать closure-compiler для экспорта определенных вами функций. См. "Экспорт символов, которые вы хотите сохранить" в https://developers.google.com/closure/compiler/docs/api-tutorial3
Если вы открыты для использования "объектно-ориентированного стиля", вот несколько идей. Вероятно, есть способ написать свой код, не переходя на объектно-ориентированный стиль, но я недостаточно знаком с этим стилем, чтобы помочь вам.
(Я не знаю, как заставить jquery активироваться при запуске вашей программы, но я предполагаю, что это происходит где-то в вашем коде запуска.)
Похоже, вы разработали этот код, чтобы быть самореализующейся функцией, которая происходит всякий раз, когда вы говорите goog.require('EqualHeights')
, Но вы на самом деле ничего не определяете для пространства имен EqualHeights. Может быть, это вместо:
goog.provide('EqualHeights');
/**
* @constructor
*/
EqualHeights = function() {
this.currentTallest = 0;
this.currentRowStart = 0;
this.rowDivs = new Array();
};
/**
* @param {!Element} el
* @param {number} newHeight
*/
EqualHeights.prototype.setConformingHeight = function(el, newHeight) {
// set the height to something new, but remember the original height in case things change
el.data("originalHeight", (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight")));
el.height(newHeight);
};
/**
* @param {!Element} el
* @return {number}
*/
EqualHeights.prototype.getOriginalHeight = function(el) {
// if the height has changed, send the originalHeight
return (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight"));
}
/**
* @return {undefined}
*/
EqualHeights.prototype.equal_heights = function() {
// find the tallest DIV in the row, and set the heights of all of the DIVs to match it.
$('[data-equalizer-watch]').each(function() {
// "caching"
var $el = $(this);
var topPosition = $el.position().top;
if (this.currentRowStart != topPosition) {
// we just came to a new row. Set all the heights on the completed row
for(currentDiv = 0 ; currentDiv < this.rowDivs.length ; currentDiv++)
setConformingHeight(this.rowDivs[currentDiv], this.currentTallest);
// set the variables for the new row
this.rowDivs.length = 0;
// empty the array
this.currentRowStart = topPosition;
this.currentTallest = getOriginalHeight($el);
this.rowDivs.push($el);
}
else {
// another div on the current row. Add it to the list and check if it's taller
this.rowDivs.push($el);
this.currentTallest = (this.currentTallest < getOriginalHeight($el)) ? (getOriginalHeight($el)) : (this.currentTallest);
}
});
// do the last row
for (currentDiv = 0 ; currentDiv < this.rowDivs.length ; currentDiv++) {
setConformingHeight(this.rowDivs[currentDiv], this.currentTallest);
}
}
Тогда в вашем коде запуска есть это:
goog.require('EqualHeights');
var eh = new EqualHeights();
// = Equalize columns on load and resize
eh.equal_heights();
$(window).resize(function(){eh.equal_heights();});
Мне неясно, что делает эта строка:
var $el = $(this);
Значение this
должен быть EqualHeights
объект внутри каждого метода. Вы можете использовать goog.bind
функция (если она доступна для вас), чтобы убедиться, что this
это то, что вы хотите, чтобы это было для этой функции.