Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Объект JS не понятное поведение или как повесить обработчик внутри объекта (https://javascript.ru/forum/events/48321-obekt-js-ne-ponyatnoe-povedenie-ili-kak-povesit-obrabotchik-vnutri-obekta.html)

Arnowt 29.06.2014 15:46

Объект JS не понятное поведение или как повесить обработчик внутри объекта
 
function floatBlock(el){
		this.el=el;
		var init=false;
		this.run=function(){
			alert(this.el+' | '+init);//!!!!!!!!!!!!!!!!!!!!!
			if(init!=true){init=true; $(window).resize(this.run);}
		}
		this.run();
	}
	$().ready(function(){new floatBlock('QWERT')});
  • Запускаем скрипт.
  • алерт ожидаемо выдает выдает «QWERT | false»
  • делаем ресайз
  • и вот тут для меня не понятная фигня получается «undefined | true»
почему el==undefined? неужели объект пересоздается? почему тогда init==true?

рони 29.06.2014 16:13

Arnowt,
$(function ()
  	  {
  	    function floatBlock(el) {
  	      this.el = el;
  	      var init = false;
  	      this.run = (function (a)
  	        {
  	          return function() {
  	            alert(a.el+' | '+init); //!!!!!!!!!!!!!!!!!!!!!
  	            if(init!=true) {init = true; $(window).resize(a.run);}
  	          }
  	        }
  	      )(this)
  	      this.run();
  	    }
  	    new floatBlock('QWERT')
  	  }
  	)

Arnowt 29.06.2014 16:59

Египетская сила...
анонимная функция которая возвращает анонимную функцию...
СПС конечно, но может есть варианты по проще? :)
которые и через пол года можно быстро понять, учитывая что я больше на php специализируюсь.

рони 29.06.2014 17:22

Arnowt,
http://learn.javascript.ru/bind

Aetae 29.06.2014 17:23

Цитата:

Сообщение от Arnowt (Сообщение 318639)
анонимная функция которая возвращает анонимную функцию...

Это есть суть js, mon ami.)

Обычно чтобы сохранить this (ребята пришедшие из других языков и не понимающие сути js) делают так:
$(function() {
    function floatBlock(el) {
        this.el = el;
        var init = false;
        var _self = this;
        this.run = function() {
            alert(this.el + ' | ' + init); //!!!!!!!!!!!!!!!!!!!!!
            if (init != true) {
                init = true;
                $(window).resize(_self.run);
            }
        }

        this.run();
    }
    new floatBlock('QWERT')
})


Можно ещё так:
$(window).resize(this.run.bind(this));
, но bind есть не во всех браузерах.(хотя полифил несложно пишется)

Arnowt 29.06.2014 17:38

Через «SELF» уже пробовал но как-то тоже не комильфо :D
упростил до максимума:
function floatBlock(el){
	this.el=el;
	this.move=function(){
		alert(this.el);
		//тут будет основной алгоритм 
	};
	$(window).resize(this.move);
	$(window).scroll(this.move);
	this.move();
}
$(function(){new floatBlock('QWERT')});

может тогда проще всякий раз передавать параметр и вообще не хранить его в объекте
ну типа:
$(window).resize(function(){this.move(el)});

?

Arnowt 29.06.2014 17:43

Хотя и через bind, думаю будет нормально... осел 6,0 не интересен, так можно и до калькулятора дойти. :)
На современных смартфонах, он же должен поддерживаться?

Aetae 29.06.2014 19:00

Цитата:

Сообщение от Arnowt (Сообщение 318647)
$(window).resize(function(){this.move(el)});

так работать всё равно не будет, ибо в resize скрывается eventListener, и при появлении события в this принудительно передаётся элемент оное поймавший.

Теперь можно ещё так:
$(window).resize(()=>this.move(el));
но это пока только в последних ff.:)

Цитата:

Сообщение от Arnowt (Сообщение 318647)
На современных смартфонах, он же должен поддерживаться?

http://caniuse.com/#search=bind


Часовой пояс GMT +3, время: 02:03.