0

Я пытаюсь сделать расширение Chrome, которое займет заголовки веб-страницы, отправьте его на API обработки языков, который вернет «оценку настроя», а затем выделит заголовки на странице разными цветами на основе вес оценки. У меня все работает, кроме функций подсветки.Как внести изменения в DOM после запроса API в расширении Chrome?

Я предполагаю, что поскольку XMLHTTPRequests запускается асинхронно, они возвращают информацию только после завершения загрузки DOM, и в этот момент слишком поздно изменять CSS и изменять элемент element.style.backgroundColor. Когда я удаляю вызов API и просто проверяю, соответствует ли textContent определенному слову или фразе, подсветка работает нормально.

Есть ли в любом случае возможность повторной обработки страницы после получения данных и обещание разрешено? Я просмотрел хром-сообщения, но это не похоже на решение. Спасибо за любой совет, который вы можете предоставить!

Вот сценарий ниже. (Я удалил заголовки из запроса HTTP):

function highlightSentiment(){ 
var elements = document.getElementsByTagName('a'); 

for (var i = 0; i < elements.length; i++) { 
    var element = elements[i]; 

    function highlight(sentiment){ 
     if(sentiment.type == "negative"){ 
     element.style.backgroundColor = "red"; 
     console.log("neg"); 
     } else if(sentiment.type == "positive"){ 
     console.log("pos"); 
     element.style.backgroundColor = "blue"; 
     } 
    } 

    var text = element.textContent; 

    getSentiment(text).then(highlight, function(status){ 
      console.log("error"); 
    }); 
    } 
    } 

function getSentiment(headline){ 
    var urltext = "text=" + headline.split(' ').join('+'); 
    return new Promise(function(resolve, reject){ 
    var req = new XMLHttpRequest(); 
     req.open(
       "GET", 
       "https://twinword-sentiment-analysis.p.mashape.com/analyze/?"+ 
       urltext, 
       true); 

     req.responseType='json'; 
     req.onload = onResponseReceived; 
     req.send(null); 
     function onResponseReceived() { 
     var status = req.status; 
     if(status ==200){ 
      resolve(req.response); 
     } else { 
      reject(status); 
     } 
     } 
    }); 
} 
+1

Вы должны прочитать связанные вопросы. Они объясняют проблему, которая заключается в том, что ваши переменные не то, что вы ожидаете от них * во время выполнения кода *, после асинхронного вызова. Относительно простое решение состоит в том, чтобы изменить: 'function highlight (sentiment) {' to 'function highlight (element, sentiment) {' и 'getSentiment (текст). Then (highlight, function (status) {' to' getSentiment(). then (highlight.bind (null, element), function (status) {' – Makyen

+0

спасибо Makyen! Это сработало! Я знал, что у меня не будет доступа к переменной в обратном вызове, но я не мог понять, как пройти это правильно или связано с ним, поскольку также был передан HTTP-ответ. Нулевое связывание элементов отлично работало! – thesoorae

ответ

-1

(Edit - пожалуйста, игнорировать это - я никогда не слышал о «Promises» до этого поста.)

Вы хотите позвонить HighlightSentiment() после получения ответа, а не при выполнении запроса.

Итак, в onResponseReceived, либо в if (status == 200) {"block or in" resolve (req.response); " вызовите HighlightSentiment() с возвращенными данными.

У вас есть полный контроль над DOM даже после получения ответа.

НТН, Джим