Задача — связать 2 абсолютно любые объекта. Менять исходный код объектов нельзя.
Описанное ниже расчитано на самостоятельность читателя и желание разобраться в реализации.
Пример (утрированный).
Есть 2 объекта в доме:
И 1 яваскриптовый:
Требуется: отреагировать на a1.onclick вызовом Core.another2
Реализация:
Убираем Observer:
Observer.
Реализация построена на клонировании метода отслеживаемого объекта.
Observer.Attach клонирует метод, создавая новый с уникальным именем.
Отслеживаемому методу присваивается новое действие, содержащее вызов клона и вызов необходимой функции (obj2.call_back)
Очередность вызова контролируем параметром before метода Observer.Attach.
Описанное ниже расчитано на самостоятельность читателя и желание разобраться в реализации.
Пример (утрированный).
Есть 2 объекта в доме:
<div id="a1" onclick="alert(123)"></div> <div id="a2"></div>
И 1 яваскриптовый:
Core = function() { this.some = function(a,b,c,d,e,f,g) { var a1 = $('a1').innerHTML var a2 = a+''+b+''+c+''+d+''+e+''+f+''+g $('a1').innerHTML = a1 + a2 } this.another = function() { var a = $('a1').innerHTML var a2 = 'some_text_more' $('a1').innerHTML = a + a2 } this.another2 = function() { var a = $('a2').innerHTML var a2 = 'yahoo' $('a2').innerHTML = a + a2 } } var Core = new Core()
Требуется: отреагировать на a1.onclick вызовом Core.another2
Реализация:
var n = Observer.Attach($('a1'), 'onclick', Core, 'another')
Убираем Observer:
Observer.Dettach($('a1'), n)
Observer.
Реализация построена на клонировании метода отслеживаемого объекта.
Observer.Attach клонирует метод, создавая новый с уникальным именем.
Отслеживаемому методу присваивается новое действие, содержащее вызов клона и вызов необходимой функции (obj2.call_back)
Очередность вызова контролируем параметром before метода Observer.Attach.
Observer = function() {} Observer.prototype = { List: {}, Attach: function(obj, method, obj2, call_back, before) { var new_method = this.CloneOldMethod(obj, method) eval('obj.'+method+' = '+this.NewDefaultMethod('obj2', call_back, new_method, before)) return new_method }, Dettach: function(obj, observed_method) { eval('var m = this.List.'+observed_method) eval('obj.'+m.method+' = m.realization') eval('delete(obj.'+observed_method+')') eval('delete(this.List.'+observed_method+')') }, NewDefaultMethod: function(obj_name, call_back, new_method, before) { var m_old = 'this.'+new_method+'(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6])' var m_new = obj_name+'.'+call_back+'()' var cmd = '' cmd += 'function() {' before === true ? cmd += m_new +';'+ m_old : cmd += m_old +';'+ m_new cmd += '}' return cmd }, CloneOldMethod: function(obj, method) { var new_method = 'a'+this.giveUnique() eval('obj.'+new_method+' = obj.'+method) eval('this.List.'+new_method+' = {object: obj, \'method\': method, realization:obj.'+method+'}') return new_method }, giveUnique: function () { return (new Date()).getTime() } } Observer = new Observer()