2015-08-10 4 views
0

Я пытаюсь понять разницу между этими двумя методами обратного вызова и тем, как они обрабатывают контекст $(this).

Рабочий пример

$("#container").on("click",".button", function() { 
    $(this).text("foo"); 
}); 

Этот процесс работает просто отлично. Однако, если я хочу сделать другой подход, я теряю контекст события.

Номера Рабочего пример

bindAnEventToAnElement: function(theElement, theEvent, theFunctions) { 
    $("body").on(theEvent, theElement, function() { 
     theFunctions(); 
    }); 
} 

bindAnEventToAnElement(".button", "click", function() { 
    $(this).text("foo"); 
}); 

Последние производит неопределенную ошибку. Есть ли способ, с помощью которого я могу обрабатывать обратные вызовы, сохраняя при этом контекст события?

Fiddle http://jsfiddle.net/szrjt6ta/

+0

Вы можете просто сделать '$ ("тело") на (theEvent, theElement, theFunctions); 'и контекст будет правильным. Здесь все о контексте :) –

ответ

2

AFAIK, JQuery-х this в этой функции обратного вызова относится к значению event.currentTarget. Таким образом, вы должны также передать объект события и сделать что-то вроде этого:

$("#container").on("click", ".button", function() { 
    $(this).text("foo"); 
}); 

theApp = { 
    bindAnEventToAnElement: function (theElement, theEvent, theFunctions) { 
     $("body").on(theEvent, theElement, function (e) { 
      theFunctions.apply(this /* or e.currentTarget */, arguments); 
     }); 
    } 
} 

theApp.bindAnEventToAnElement(".button-two", "click", function() { 
    $(this).text("foo"); 
}); 

Working Fiddle

Если я пытаюсь объяснить проблему, JQuery является обязательным для функции обратного вызова передать это как e.currentTarget. Но вы передаете другую функцию обратного вызова внутри этой функции обратного вызова, область видимости которой не будет ее родительской функцией обратного вызова, но будет window. Таким образом, вам необходимо снова привязать к завернутой функции, которую вы можете использовать с помощью apply или call.

+0

Что такое «аргументы» в этом примере? – Yuschick

+0

@Yuschick Каждая функция имеет переменные 'this' и' arguments'. (они зарегистрированы). Здесь 'arguments' - массив параметров, которые вы передали этой функции. Для лучшего объяснения лучше проверить MDN. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments –

+0

благодарим вас за объяснение и ссылку. После немного более реального сценария, я думаю, что это будет хорошо работать для меня. Большое спасибо! – Yuschick

1

Вы должны вручную связать контекст функции для того, чтобы иметь this индексируются внутри обратного вызова:

$("body").on(theEvent, theElement, function() { 
    theFunctions.apply(this); 
}); 

напримерhttp://jsfiddle.net/szrjt6ta/1/

Найти еще около apply()here

+0

Но можете ли вы объяснить, в чем проблема? Я хотел бы понять. Я также, в идеале, должен был бы передать это в аргументе theFunctions. – Yuschick

0

Использование .call(this) Метод call() вызывает функцию с заданным значением и аргументами, предоставленными индивидуально.

Примечания: Несмотря на то, что синтаксис этой функции практически идентичен применения(), основное отличие состоит в том, что вызов() принимает список аргументов , в то время как применить() принимает один массив аргументов.

$("#container").on("click",".button", function() { 
     $(this).text("foo"); 
    }); 

theApp = { 
    bindAnEventToAnElement: function(theEvent, theElement, theFunctions) { 
     $("body").on(theEvent, theElement, function() { 
      theFunctions.call(this); 
     }); 
    } 
} 

    theApp.bindAnEventToAnElement("click", ".button-two", function() { 
     $(this).text("fooe"); 
    }); 

Fiddle

0

Изменение прикрепление обработчика событий из

$("body").on(theEvent, theElement, function() {theFunctions();}); 

в

$("body " + theElement).on(theEvent, theFunctions); 

Как это:

HTML:

<div id="container"> 
    <a class="button">Button</a><br /> 
    <a class="button-two">Button Binded</a> 
</div> 

JQuery:

$("#container").on("click",".button", function() { 
    $(this).text("foo"); 
}); 

theApp = { 
    bindAnEventToAnElement: function(theElement, theEvent, theFunctions) { 
     $("body " + theElement).on(theEvent, theFunctions); 
    } 
} 

theApp.bindAnEventToAnElement(".button-two", "click", function() { 
    $(this).text("foo"); 
}); 

Fiddle:.https://jsfiddle.net/szrjt6ta/10/

Смежные вопросы