2016-05-17 6 views
0

Я пытаюсь сделать расширение Chrome, которое займет некоторое содержимое страницы (Внутренний HTML-код <span> с id="productTitile"). Затем мне нужно было бы взять это значение и поместить его в поле в моем popup.html ,Доступ к DOM из popup.js | Расширение Chrome

Я проверил много других вопросов о переполнении стека, но ни один из них не имеет рабочего ответа.

Я попытался это:

document.getElementById('input_87').value = chrome.tabs.executeScript({ 
    code: 'document.getElementById("productTitle").innerHTML' 
}); 

Но он просто возвращает undefined в поле. Затем я запустил document.getElementById("productTitle").innerHTML в консоли на родительской странице, и он дал мне ожидаемое значение, но когда я запустил весь код в консоли всплывающего расширения, он снова вернул undefined.

Может кто-нибудь, пожалуйста, помогите мне или скажите, что я делаю неправильно?

+0

'chrome.tabs.executeScript' асинхронный вызов, вы должны присвоить значение внутри его обратного вызова. –

ответ

1

Во-первых, как пишет Haibara Ai, chrome.tabs.executeScript является асинхронным - ничего не возвращает (и ничего не делает сразу).

Хорошим источником по этому вопросу в целом этот вопрос: How do I return the response from an asynchronous call?(спойлер: вы не можете)

Если вы look at the docs (который, кстати, должен быть ваш первый безусловный рефлекс), вы» увидим, что у него есть обратный вызов, и если вы прочитаете вышеупомянутый вопрос, вы поймете, что это ваш единственный вариант. Тем не менее, есть 2 дополнительные осложнения:

  1. Обратный вызов получает массив результатов. Это происходит потому, что executeScript может, необязательно (с указанным allFrames: true или frameId), выполняется в подкадрах. Таким образом, вы должны будете использовать первый элемент массива результатов:

    chrome.tabs.executeScript({ 
        code: 'document.getElementById("productTitle").innerHTML' 
    }, function(results) { 
        document.getElementById('input_87').value = results[0]; 
    }); 
    
  2. Вызов executeScript может потерпеть неудачу - например, когда страница не скрипты, независимо от разрешений, таких как Chrome Web Store. Разумно, чтобы проверить, что вы действительно получили результат, прежде чем использовать его:

    chrome.tabs.executeScript({ 
        code: 'document.getElementById("productTitle").innerHTML' 
    }, function(results) { 
        if (chrome.runtime.lastError) { 
        // Couldn't execute the script at all 
        } else if (typeof results[0] === "undefined") { 
        // Couldn't find what we wanted 
        } else { 
        // Everything is fine 
        document.getElementById('input_87').value = results[0]; 
        } 
    }); 
    
+0

Здравствуйте, @Xan, когда будет выполняться 'executeScript' в подкадрах, если пользователь не указал tabId, который по умолчанию соответствует активной вкладке? –

+0

Если пользователь не указал 'allFrames', возвращаемое значение не будет массивом, верно? –

+0

Он по-прежнему будет массивом не более 1 элемента. См. Документы. – Xan

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