Форум программистов, компьютерный форум, киберфорум
JavaScript: API
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
1
Chrome Extention

Как заставить функцию из content выполняться по запросу background?

27.12.2017, 17:34. Показов 4364. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем доброго времени суток! Прошу вашей помощи! Есть расширение для Chrome, в нем Background.js который закрывает новые вкладки, если вкладок более заданного. После того как вкладка закрыта, вкладка на которую возвращается браузер, обновляется. После чего срабатывает conent.js в котором прописано нажатие нужной кнопки на удаленном сайте.
Нужно по запросу, только после обновления страницы, нажать на кнопку. На данный момент, кнопка нажимается даже если вручную перейти на страницу.
Мне посоветовали использовать sendMessage но он не срабатывает, не могу понять в чем дело. Даже сообщение не срабатывает.

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Background.js
function handleTabRemoved(tab) {
    updateTabsCount();
  chrome.tabs.reload(tab.id);
  began();
  
  }
  
function began() {
 
  chrome.extension.sendMessage(
{
greeting: 'hello'
}, 
function(response) {
      console.log(response.msg); 
    });
}
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//content.js
function handleTabClick() {
  
    setTimeout(function()   {
        document.getElementById('0').click();
    }, 5000);
}
 
chrome.extension.onMessage.addListener(
  function(sender, request, sendResponse) {
    if (request.greeting == 'hello'){
    setTimeout(function() {alert('111')}, 5000);
 
 
      sendResponse({msg: 'Update'});
    return true;
    }
 
  });
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.12.2017, 17:34
Ответы с готовыми решениями:

Как заставить функцию выполняться в потоке
По примерам написал код создания потока: #include <iostream> using namespace std; #include...

Заставить периодически выполняться функцию
Есть какие-то еще способы реализации сабжа кроме, чем наподобие такого? aTimer = new...

Как заставить макрос автоматически выполняться?
Доброго времени суток. Есть макрос, который из одного текстового поля формы должен автоматом...

Как заставить функции выполняться по порядку?
function first(){ setTimeout(function(){ console.log('1'); }, 1000); } function...

24
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 18:10 2
BeleK0ss, а chrome.extension.sendMessage... где об этом можно почитать? Возможно речь о chrome.runtime.sendMessage и chrome.runtime.onMessage соответственно?
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 18:16  [ТС] 3
Прошу прощения. Подставлял от безысходности. сейчас код выглядит так
Javascript
1
2
3
4
5
6
7
function began() {
 
  chrome.runtime.sendMessage({greeting: "hello"}, function(response) 
    {
      console.log(response.msg);
    });
}
Javascript
1
2
3
4
5
6
7
8
9
10
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.greeting == "hello") {
    setTimeout(function() {alert('111')}, 5000);
    }
      sendResponse({msg: "Update"});
        return true;
    
 
  });
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 18:37 4
BeleK0ss, я так понимаю, в результате ты ждешь, что в консоли что-то появится и это и будет результатом? Не надо этого ждать. Консоль связана с конкретной вкладкой и отправка в нее чего бы то ни было из бэкграунда результата не даст, поскольку он с конкретной вкладкой не связан.
Кроме того, я, видимо, просто не вижу всей картины, но мне непонятно, где это все вызывается. Если весь этот механизм должен запускаться при попытке открыть новую вкладку, то по всей видимости где-то должен быть обработчик вот этого события или чего-то в этом роде. В обработчике прибиваешь новую вкладку и запускаешь весь механизм. Как-то так.
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 18:47  [ТС] 5
Вот вся картина:
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
var isEnabled = true;
var maxTabs = 1;
var tabsCount;
 
 
function updateBadgeText() {
    var tabsBalance = maxTabs - tabsCount;
    var tabsAllowanceRemaining = (tabsBalance > 0) ? tabsBalance : 0;
 
    chrome.browserAction.setBadgeText({
        text: "" + tabsAllowanceRemaining
        
    });
    
}
 
function updateTabsCount() {
    
    chrome.tabs.query({
        windowType: 'normal',
        pinned: false
    }, function (tabs) {
        tabsCount = tabs.length;
        updateBadgeText();
    });
}
 
 
 
function handleTabCreated(tab) {
   if (tabsCount >= maxTabs) {
        setTimeout(function() {
        chrome.tabs.remove(tab.id);
        }, 2000);   
    }
    else {
        updateTabsCount();
    }
}
 
 
 
 
function handleTabRemoved(tab, response) {
    updateTabsCount();
    chrome.tabs.reload(tab.id);
    began();
    
    }
    
function began() {
 
  chrome.runtime.sendMessage({greeting: "hello"}, function(response) 
    {
      console.log(response.msg);
    });
}
 
function handleTabUpdated(tab) {
    updateTabsCount();
}
 
 
function init() {
    updateTabsCount();
    chrome.tabs.onCreated.addListener(handleTabCreated);
    chrome.tabs.onRemoved.addListener(handleTabRemoved);
    chrome.tabs.onUpdated.addListener(handleTabUpdated);
    }
 
function teardown() {
    chrome.tabs.onCreated.removeListener(handleTabCreated);
    chrome.tabs.onRemoved.removeListener(handleTabRemoved);
    chrome.tabs.onUpdated.removeListener(handleTabUpdated);
    }
 
chrome.browserAction.onClicked.addListener(function (tab) {
    if (!isEnabled) {
        init();
        chrome.browserAction.setIcon({ path: "icons/19.png" });
    }
    else {
        teardown();
        chrome.browserAction.setIcon({ path: "icons/19-disabled.png" });
        chrome.browserAction.setBadgeText({ 'text': '' });
  }
 
    isEnabled = !isEnabled;
});
 
began();
init();
Добавлено через 8 минут
Нет, я не жду изменений в консоли. Я полагаю что по идее должно выйти сообщение, или если подставить handleTabClick(); из content будет нажата кнопка на странице. Но ни того ни другого не происходит. Если убрать отправку собщений, оставить только функцию нажатия кнопки, кнопка будет нажата. Мне нужно сделать так что бы нажатие вызывалось после срабатывания определенной функции.
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 19:00 6
BeleK0ss, собственно ответ нашелся в документации
Note that extensions cannot send messages to content scripts using this method. To send messages to content scripts, use tabs.sendMessage.
То есть, если адресатом сообщения является контент-скрипт, то надо использовать tabs.sendMessage.

Добавлено через 1 минуту
Цитата Сообщение от BeleK0ss Посмотреть сообщение
я не жду изменений в консоли.
А 55-я строка для чего?
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 19:06  [ТС] 7
Если вписать tabs.sendMessage выдает
extensions::schemaUtils:115 Uncaught Error: Invocation of form tabs.sendMessage(object, function) doesn't match definition tabs.sendMessage(integer tabId, any message, optional object options, optional function responseCallback)
at Object.normalizeArgumentsAndValidate (extensions::schemaUtils:115)
at Object.<anonymous> (extensions::binding:363)
at began (background.js:53)
at background.js:91

55 строка была взята из примера.

А теперь все гуд, убрал лишний began(); внизу страницы. но всеравно не работает

Javascript
1
2
3
4
5
function began() {
 
  chrome.tabs.sendMessage({greeting: "hello"}, function(response) 
    {});
}
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 19:10 8
Цитата Сообщение от BeleK0ss Посмотреть сообщение
Если вписать tabs.sendMessage выдает
Ну надо сначала документацию смотреть. Сигнатура этого метода немного отличается. Здесь надо передавать id вкладки, которой предназначено сообщение.
chrome.tabs.sendMessage
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 19:17  [ТС] 9
Да, вижу... Не подскажите каким образом это можно сделать?
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 19:22 10
BeleK0ss, ну например методу began добавить параметр tabId, как-то так
Javascript
1
2
3
4
5
function began(tabId) {
 
  chrome.tabs.sendMessage(tabId, {greeting: "hello"}, function(response) 
    {});
}
Ну и соответственно при вызове (47-ая строка) передавать ид вкладки
Javascript
1
began(tab.id);
Добавлено через 1 минуту
Кстати, если коллбэк не используется, его можно не передавать. Он как раз там - необязательный параметр, в отличие от ид вкладки.
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 19:31  [ТС] 11
Тогда получается вот так
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
function handleTabRemoved(tab) {
    updateTabsCount();
    chrome.tabs.reload();
    began(tab.id);
 
    }
    
function began(tabId) {
 
  chrome.tabs.sendMessage(tabId, {greeting: "hello"}, function(response) 
    {});
}
и

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function handleTabClick() {
    
        setTimeout(function()   {
                document.getElementById('0').click();
        }, 5000);
}
 
chrome.runtime.onMessage.addListener(
  function(request, sender) {
    if (request.greeting == "hello") {
    handleTabClick();
    }
    
  });
Но начинает тогда жаловаться В
Javascript
1
2
chrome.tabs.sendMessage(tabId, {greeting: "hello"}, function(response) 
    {});
На первую открытую скобку.

во втором на сам
Javascript
1
began(tab.id);
Error in event handler for tabs.onRemoved: ReferenceError: tab is not defined
at began (chrome-extension://gjbjlfmibeieoajjpddlekilgchggmeb/background.js:53:27)
at handleTabRemoved (chrome-extension://gjbjlfmibeieoajjpddlekilgchggmeb/background.js:47:2)
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 19:46 12
BeleK0ss, до того как ты внёс изменение tab не вызывал вопросов, а теперь вдруг оказалось, что он не определён. Такого ведь не бывает. Значит смотри, что ещё ты изменил. Например непонятно, куда делся второй аргумент функции, который в первоначальном варианте был.
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 20:00  [ТС] 13
Да вроде ничего кроме этих функций и не трогал. Если их закоментировать, все работает
Javascript
1
2
3
4
5
6
7
8
9
10
11
function handleTabRemoved(tab) {
    updateTabsCount();
    chrome.tabs.reload(tab.id);
    //began(tab.id);
    }
    
//function began(tabId) {
 
  //chrome.tabs.sendMessage(tabId, {greeting: "hello"}, function(response) 
   //{});
//}
Не могу понять в чем дело..... вернул return true

Javascript
1
2
3
4
5
6
7
chrome.runtime.onMessage.addListener(
  function(request, sender) {
    if (request.greeting == "hello") {
    handleTabClick();
    return true;
    }
  });
Теперь пишет

Error in event handler for tabs.onRemoved: Error: Invocation of form tabs.sendMessage(undefined, object) doesn't match definition tabs.sendMessage(integer tabId, any message, optional object options, optional function responseCallback)
at began (chrome-extension://gjbjlfmibeieoajjpddlekilgchggmeb/background.js:52:15)
at handleTabRemoved (chrome-extension://gjbjlfmibeieoajjpddlekilgchggmeb/background.js:47:2)
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 20:06 14
BeleK0ss, У функции handleTabRemoved было два параметра. Я так понимаю, именно такая сигнатура требуется для обработчика данного события? Куда делся второй параметр?
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 20:09  [ТС] 15
Понял, да была. Добавил её чисто для эксперемента. Но с ней и без нее не чувствует разницы. В целом, пока что вернул.
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
27.12.2017, 20:52 16
BeleK0ss, могу предположить, что причина в перезагрузке страницы. Метод скорее всего выполняется асинхронно и получается, что страница не перезагрузилась, а ты пытаешься до неё достучаться. Попробуй сначала дождаться завершения перезагрузки.
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
27.12.2017, 22:58  [ТС] 17
Хорошо, спасибо! Завтра попробую.
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
28.12.2017, 11:21 18
BeleK0ss, я положился на твой предыдущий код, думая, что в нем работает все кроме сообщений, но, видимо, ошибся. Смотрим документацию по событию onRemoved.
Во-первых, там первый параметр - не объект с данными о вкладке, а только ее идентификатор, так что tab.id будет в любом случае выдавать undefined и когда ты это использовал для перезагрузки страницы, это уже там не работало.
Во-вторых, tabId - это идентификатор удаленной вкладки, так что непонятно, чего ее перезагружать, если она уже удалена. Вместо этого надо запросить активную вкладку того же окна, если оно не закрылось, и работать с ней.
То есть, иными словами, код должен выглядеть примерно так
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function handleTabRemoved(tab, response)
{
    updateTabsCount();
    if (rsponse.isWindowClosing == false)
    {
        chrome.tabs.query({ "active": true, "windowId": response.windowId }, function (tabs)
        {
            chrome.tabs.reload(tabs[0].id, function ()
            {
                began(tabs[0].id);
            });
        });
    }
}
1
0 / 0 / 0
Регистрация: 27.12.2017
Сообщений: 23
28.12.2017, 11:44  [ТС] 19
Понял. Ошибки ушли. Пол ночи не спал... Теперь, если верить моим наблюдениям, благодаря тебе, он наконец-то начал обращаться исправно к began. Но пока-что еще не происходит нажатие из content.
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
28.12.2017, 11:51 20
Цитата Сообщение от BeleK0ss Посмотреть сообщение
Но пока-что еще не происходит нажатие из content.
Ну опять-таки, вот твой код
Javascript
1
2
3
4
5
6
7
8
9
10
11
chrome.extension.onMessage.addListener(
  function(sender, request, sendResponse) {
    if (request.greeting == 'hello'){
    setTimeout(function() {alert('111')}, 5000);
 
 
      sendResponse({msg: 'Update'});
    return true;
    }
 
  });
А вот документация. В документации первый параметр - сообщение, а второй - отправитель. У тебя все наоборот и в результате ты пытаешься читать отправителя как сообщение и, само собой, условие не проходит.
1
28.12.2017, 11:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.12.2017, 11:51
Помогаю со студенческими работами здесь

Как в домене заставить выполняться bat-файл?
Сервер 2008R2 Есть простой bat-файл c одной строчкой, который меняет часовой пояс (tzutil.exe /s...

Как заставить процедуру выполняться под админом?
Ситуация такая: Есть 2 базы данных, и при создании документа в одной из них, должны вноситься...

Как заставить скрипт выполняться дальше после ошибки?
Вообщем в структуре кода есть некотрый случайный элемент который может вызвать ошибку а может её и...

Как заставить команду выполняться ко всем вложенным файлам в папках?
В ГЛАВНОЙ директории имеется много ПОДДИРЕКТОРИЙ с вложенными файлами одинакового расширения. Я...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru