Как и предполагаемые комментарии, решение заключается в использовании вложенных пространств / строк.
<div class="container">
<div class="row">
<div class="span4">1</div>
<div class="span8">
<div class="row">
<div class="span4">2</div>
<div class="span4">3</div>
</div>
<div class="row">
<div class="span4">4</div>
<div class="span4">5</div>
</div>
</div>
</div>
<div class="row">
<div class="span4">6</div>
<div class="span4">7</div>
<div class="span4">8</div>
</div>
</div>
(извлек некоторое объяснение, которое было скрыто в комментариях в другом ответе)
проблема заключается в следующей строке:
this.dom.addEventListener("click", self.onclick, false);
Здесь, Вы передаете функциональный объект, который будет использоваться в качестве обратного вызова. Когда триггер события, функция вызвана, но теперь это не имеет никакой связи ни с каким объектом (это).
проблема может быть решена путем обертывания функции (с, он - ссылка на объект) в закрытии следующим образом:
this.dom.addEventListener(
"click",
function(event) {self.onclick(event)},
false);
, Так как переменная сам была присвоена это , когда закрытие было создано, функция закрытия будет помнить значение сам переменная, когда это звонило в более позднее время.
альтернативный способ решить это состоит в том, чтобы сделать служебную функцию (и избегать использования переменных для привязки это ):
function bind(scope, fn) {
return function () {
fn.apply(scope, arguments);
};
}
обновленный код был бы тогда похож:
this.dom.addEventListener("click", bind(this, this.onclick), false);
<час> Function.prototype.bind
часть ECMAScript 5 и обеспечивает ту же функциональность. Таким образом, можно сделать:
this.dom.addEventListener("click", this.onclick.bind(this), false);
Для браузеров, которые еще не поддерживают ES5, , MDN обеспечивает следующий контейнер :
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
this.dom.addEventListener("click", function(event) {
self.onclick(event)
}, false);
это - одна из самых запутывающих точек JS: 'эта' переменная значит для большей части локального объекта..., но функции являются также объектами, таким образом, 'это' указывает там. Существуют другие тонкие моменты, но я не помню их всех.
я обычно избегаю использования 'этого', просто определяю локальное 'меня' переменная и использование это вместо этого.
Объяснение состоит в том, что self.onclick
не означает то, что Вы думаете, что это означает в JavaScript. Это на самом деле означает эти onclick
функция в прототипе объекта self
(всегда не ссылаясь self
самого).
JavaScript только имеет функции и никаких делегатов как C#, таким образом, не возможно передать метод И объект, к этому нужно относиться как обратный вызов.
единственный способ назвать метод в обратном вызове состоит в том, чтобы назвать его самостоятельно в функции обратного вызова. Поскольку функции JavaScript являются закрытиями, они в состоянии получить доступ к переменным, объявленным в объеме, в котором они были созданы.
var obj = ...;
function callback(){ return obj.method() };
something.bind(callback);
Хорошее объяснение проблемы (у меня были проблемы с пониманием решений, описанных до сих пор) доступно здесь .