Передача селектора $ (this) во вложенные функции

#javascript #jquery

#javascript #jquery

Вопрос:

Итак, у меня есть скрипт, который должен просматривать каждый P тег внутри родительского DIV объекта с именем класса entry-content и переводить каждый из них с помощью Google translate API.

Таким образом, когда пользователь нажимает на ссылку для перевода страницы с английского на испанский, запускается эта функция:

 function spanish() {
$(".entry-content p").each(function(){
      var text = $(this).html();
        google.language.detect(text, function(result) {
          google.language.translate(text, "en", "es", function(result) {
           if (result.translation) {
                alert($(this).html());  //outputs NULL
                $(this).html(result.translation); //doesn't work
            }
          });
        });
      });
}
  

Проблема в том, что при переходе к внутренней функции $(this).html() возвращается значение NULL, и я не могу изменить текущие элементы html, чтобы заменить его на новый переведенный текст.

Итак, я предполагаю, что мой вопрос таков: как бы мне передать текущий выбранный элемент во вложенные функции?

Спасибо

Ответ №1:

Вы можете сохранить его в локальной переменной

Значение this всегда будет относиться к контексту, в котором вызывается функция. В вашем примере вы передаете функцию google.language.translate , и, таким образом, предположительно, она google.language.translate вызывает эту функцию.

Однако, если вы сохраните значение, $(this) когда оно будет вашим p , вы сможете использовать эту переменную из функции обратного вызова.

 function spanish() {
    $(".entry-content p").each(function(){
      var $this = $(this);
      var text = $this.html();
        google.language.detect(text, function(result) {
          google.language.translate(text, "en", "es", function(result) {
           if (result.translation) {
                alert($this.html());  //outputs NULL
                $this.html(result.translation); //doesn't work
            }
          });
        });
      });
}
  

Комментарии:

1. Теперь это кажется таким очевидным, спасибо. в качестве дополнительного вопроса могу я спросить, зачем использовать $? в чем разница между var $this = $(this); и var this = $ (this);

2. ну, this это зарезервированное ключевое слово. Вы все равно не сможете установить это и получить к нему доступ извне. var anythingElse = $(this) это сработало бы, и вы можете смело делать все, что угодно. $this стало чем-то вроде соглашения для обозначения «это, обернутое в jQuery», но вы можете использовать все, что вам заблагорассудится.

Ответ №2:

Это потому, что this изменяет контекст в этом обратном вызове, просто сохраните ссылку на нужный элемент / объект, вот так:

 function spanish() {
  $(".entry-content p").each(function(){
    var text = $(this).html(), self = this;
    google.language.detect(text, function(result) {
      google.language.translate(text, "en", "es", function(result) {
       if (result.translation) {
            $(self).html(result.translation);
        }
      });
    });
  });
}
  

Ответ №3:

Сохраните запись ‘this’ в соответствующем контексте — в противном случае this относится к внутренней функции, а не к родительской функции.

 function spanish() {
$(".entry-content p").each(function(){

      // Save a record of 'this' in the proper context.
      var me = this;

      var text = $(this).html();
        google.language.detect(text, function(result) {
          google.language.translate(text, "en", "es", function(result) {
           if (result.translation) {
                alert($(me).html());  
                $(me).html(result.translation); 
            }
          });
        });
      });
}
  

Ответ №4:

Я бы сделал что-то вроде этого. Затем изучите замыкания, чтобы понять, что он делает.

 function spanish() {
$(".entry-content p").each(function(){
var $this = this; // new
      var text = $(this).html();
        google.language.detect(text, function(result) {
          google.language.translate(text, "en", "es", function(result) {
           if (result.translation) {
                alert($(this).html());  //outputs NULL
                $this.html(result.translation); 
            }
          });
        });
      });
}