所以我想制作一个Chrome扩展程序,自动赞同你在LinkedIn上查看的人的所有技能。
我有以下教程的基本扩展:google:
manifest.json:
{
"manifest_version": 2,
"name": "ALSE - Auto LinkedIn Skills Endorser",
"description": "This extension allows you to automatically endorse all of the skills of the LinkedIn friend you are currently viewing with a single click!",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "Click here to see the endorse all of the skills of your LinkedIn friend!"
},
"permissions": [
"activeTab",
"https://ajax.googleapis.com/"
]
}
popup.html:
<!doctype html>
<!--
This page is shown when the extension button is clicked, because the
"browser_action" field in manifest.json contains the "default_popup" key with
value "popup.html".
-->
<html>
<head>
<title>Getting Started Extension's Popup</title>
<style>
body {
font-family: "Segoe UI", "Lucida Grande", Tahoma, sans-serif;
font-size: 100%;
}
#status {
/* avoid an excessively wide status text */
white-space: pre;
text-overflow: ellipsis;
overflow: hidden;
max-width: 400px;
}
</style>
<!--
- JavaScript and HTML must be in separate files: see our Content Security
- Policy documentation[1] for details and explanation.
-
- [1]: https://developer.chrome.com/extensions/contentSecurityPolicy
-->
<script src="popup.js"></script>
</head>
<body>
<div id="status"></div>
<img id="image-result" hidden>
<button id ="testButton" type="button">Click Me!</button>
</body>
</html>
popup.js:
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Get the current URL.
*
* @param {function(string)} callback - called when the URL of the current tab
* is found.
*/
function getCurrentTabUrl(callback) {
// Query filter to be passed to chrome.tabs.query - see
// https://developer.chrome.com/extensions/tabs#method-query
var queryInfo = {
active: true,
currentWindow: true
};
chrome.tabs.query(queryInfo, function(tabs) {
// chrome.tabs.query invokes the callback with a list of tabs that match the
// query. When the popup is opened, there is certainly a window and at least
// one tab, so we can safely assume that |tabs| is a non-empty array.
// A window can only have one active tab at a time, so the array consists of
// exactly one tab.
var tab = tabs[0];
// A tab is a plain object that provides information about the tab.
// See https://developer.chrome.com/extensions/tabs#type-Tab
var url = tab.url;
// tab.url is only available if the "activeTab" permission is declared.
// If you want to see the URL of other tabs (e.g. after removing active:true
// from |queryInfo|), then the "tabs" permission is required to see their
// "url" properties.
console.assert(typeof url == 'string', 'tab.url should be a string');
callback(url);
});
// Most methods of the Chrome extension APIs are asynchronous. This means that
// you CANNOT do something like this:
//
// var url;
// chrome.tabs.query(queryInfo, function(tabs) {
// url = tabs[0].url;
// });
// alert(url); // Shows "undefined", because chrome.tabs.query is async.
}
/**
* @param {string} searchTerm - Search term for Google Image search.
* @param {function(string,number,number)} callback - Called when an image has
* been found. The callback gets the URL, width and height of the image.
* @param {function(string)} errorCallback - Called when the image is not found.
* The callback gets a string that describes the failure reason.
*/
function getImageUrl(searchTerm, callback, errorCallback) {
// Google image search - 100 searches per day.
// https://developers.google.com/image-search/
var searchUrl = 'https://ajax.googleapis.com/ajax/services/search/images' +
'?v=1.0&q=' + encodeURIComponent(searchTerm);
var x = new XMLHttpRequest();
x.open('GET', searchUrl);
// The Google image search API responds with JSON, so let Chrome parse it.
x.responseType = 'json';
x.onload = function() {
// Parse and process the response from Google Image Search.
var response = x.response;
if (!response || !response.responseData || !response.responseData.results ||
response.responseData.results.length === 0) {
errorCallback('No response from Google Image search!');
return;
}
var firstResult = response.responseData.results[0];
// Take the thumbnail instead of the full image to get an approximately
// consistent image size.
var imageUrl = firstResult.tbUrl;
var width = parseInt(firstResult.tbWidth);
var height = parseInt(firstResult.tbHeight);
console.assert(
typeof imageUrl == 'string' && !isNaN(width) && !isNaN(height),
'Unexpected respose from the Google Image Search API!');
callback(imageUrl, width, height);
};
x.onerror = function() {
errorCallback('Network error.');
};
x.send();
}
function renderStatus(statusText) {
document.getElementById('status').textContent = statusText;
}
document.addEventListener('DOMContentLoaded', function() {
getCurrentTabUrl(function(url) {
// Put the image URL in Google search.
renderStatus('Performing Google Image search for ' + url);
getImageUrl(url, function(imageUrl, width, height) {
renderStatus('Search term: ' + url + '\n' +
'Google image search result: ' + imageUrl);
var imageResult = document.getElementById('image-result');
// Explicitly set the width/height to minimize the number of reflows. For
// a single image, this does not matter, but if you're going to embed
// multiple external images in your page, then the absence of width/height
// attributes causes the popup to resize multiple times.
imageResult.width = width;
imageResult.height = height;
imageResult.src = imageUrl;
imageResult.hidden = false;
}, function(errorMessage) {
renderStatus('Cannot display image. ' + errorMessage);
});
});
});
document.addEventListener('DOMContentLoaded', function() {
var button = document.getElementById('testButton');
var elems = document.getElementsByClassName("endorse-button");
// onClick's logic below:
button.addEventListener('click', function() {
alert(elems);
alert(elems.length);
for (i in elems) {
elems[i].click()
}
});
});
当我访问朋友的LinkedIn个人资料时,我可以使用Chrome控制台中的以下命令认可他们的技能:
document.getElementsByClassName("endorse-button")[0].click();
其中0可以被任何整数替换
我遇到的主要问题是,当我尝试将此逻辑放在Chrome扩展程序中时,它无法正常工作。我总是得到elems.length是0,其中
elems = document.getElementsByClassName("endorse-button");
这是popup.js中具有逻辑:
的代码片段document.addEventListener('DOMContentLoaded', function() {
var button = document.getElementById('testButton');
var elems = document.getElementsByClassName("endorse-button");
// onClick's logic below:
button.addEventListener('click', function() {
alert(elems);
alert(elems.length);
for (i in elems) {
elems[i].click()
}
});
});
我认为这与background.js有关?和清单中的背景属性?不确定,我会继续修补并让你发布。这应该很容易理解。谢谢!!!