Chrome Extensions : Get all images on page - javascript

After hours of reading in the Google-Documentations and Stackoverflow I decided to post this question. There already are some similar ones but I haven't found a answer that really helped me.
However, I'm trying to get a list of all images embeded on a page to use it in the Chrome extension. I've tried to do it with simle Javascript (document.images) but didn't get any entries. After some research I found out, that the only way to read elements from a page is using a EventListener. The function should be started using the chrome context-menu.
chrome.contextMenus.create({
title: "ExampleFunction",
contexts:["page"],
onclick: exampleFunction,
});
This part works fine, but how do I get the images after calling the function?
I've tried some ways using eventlisteners and finally got this function:
function downloadImages(info,tab) {
alert('o');
chrome.extension.onRequest.addListener(function(result){
for (var i in result.images) {
allImages.push(result.images[i]);
}
alert(allImages[0]);
});
}
The first alert works perfect but everything else is just doing nothing.

First you have to actually get the images, and the way to do that is to use a content script. I am assuming that your onclick was a typo and that you have this instead:
chrome.contextMenus.create({
title: "ExampleFunction",
contexts:["page"],
onclick: downloadImages,
});
Then you would want to have something like this:
function downloadImages(info,tab) {
alert('o');
chrome.tabs.executeScript(tab.id,{file:"script.js"});
}
chrome.runtime.onMessage.addListener(function(message){
//In case you want to do other things too this is a simple way to handle it
if(message.method == "downloadImages"){
message.images.forEach(function(v){
allImages.push(v);
});
alert(allImages[0]);
}
});
And then for your script.js:
var images = [];
for(var i = 0; i < document.images.length; i++){
images.push(document.images[i].src);
}
chrome.runtime.sendMessage({method:"downloadImages",images:images});
This grabs the array of images and sends back the src of each image to your background page so you can do whatever you want with it.

Related

Image processing issue

I am using javascript/jQuery to manage a slide show that can handle random occurrences of portrait or landscape images.
The code works fine if there is an "alert" in the first function called to process a loaded image.
It fails without the alert.
I am testing locally and the images are loaded into an array when the page loads.
The files are quite small. I suspect however that the issue is one of timing.
Below is the function where the Alert works. I donĀ“t exactly understand what the code is doing as I am new to jQuery. It would help to know what the function is doing and a suggestion of how to fix the issue. I can post a working sample if it would help.
function FixImages(fLetterBox) {
$("div.aspectcorrect").each(function (index, div) {
var img = $(div).find("img").get(0);
alert("FixI")
FixImage(fLetterBox, div, img);
});
}
I suspect that you might be passing in the wrong arguments for the .each() callback. If you want div to refer to the element that is currently being looked at in each iteration, using $(this) should work:
function FixImages(fLetterBox) {
$("div.aspectcorrect").each(function (index) {
var img = $(this).find("img").get(0);
FixImage(fLetterBox, div, img);
});
}

Equal Height is not working .js file

I have a function that I wrote basically as below:
function getListHeight() {
$(".tur-list .col-lg-5 figure img").each(function() {
var getTurHeight = $(this).parents(".tur-list").find(".col-lg-7").outerHeight();
var getLeftHeight = $(this).parents("tur-list").find(".col-lg-5 figure img").outerHeight();
if (getTurHeight > getLeftHeight) {
$(this).outerHeight(getTurHeight);
}
});
}
to make equal my columns and it works as I wanted so there is nothing to here. my problem is this code is not working on my .js file but if I copy and paste it console my code is working so if you try you will see
Please click to my real demo
and copy getListHeight(); and paste it on console you will see my columns will be equal my question is why my code is not working properly in .js file ? what I have to do to work my code ?
and my getListHeight() function is work with $(window).resize when I resize the window or with click event but my function is not working in document.ready.
its not working because the images are not loaded yet, the image tag is there but the size is not set yet because the image is still being loaded.
i'd change the code to the following:
function matchSize() {
var getTurHeight = $(this).parents(".tur-list").find(".col-lg-7").outerHeight();
var getLeftHeight = $(this).parents("tur-list").find(".col-lg-5 figure img").outerHeight();
if (getTurHeight > getLeftHeight) {
$(this).outerHeight(getTurHeight);
}
}
function onResize() {
$(".tur-list .col-lg-5 figure img").each(matchSize);
}
function getListHeight() {
$(".tur-list .col-lg-5 figure img").load(matchSize);
}
$(document).ready(function(){
getListHeight();
$(document).on('resize', onResize)
onResize()
});
this will work on resize, on newly loaded images, and on previously loaded images before javascript kicks in (cached images probably).
here is a link to the codepen fork: https://codepen.io/Bamieh/pen/gRLPqm
P.S. i do recommend that you do not rely on the col-* classes as a selector, since the code will easily break as soon as you change your styles, using data-* attributes for selection is the way to go in my opinion.

Delete a single URL from a chrome-extension popup-window seems not working with adding event listeners (the event listener might be scoped?)

Background information
I am trying to make a functional chrome-extension popup-window that enables the user to add links (based on the open tab's URL) when he desires it, and deletes one link or delete all of the links in just one click. Down below are all of my files! I must say in advance that I am not very good (and not experienced) with using jQuery's library but if that's the only solution that I have, than I will use it in my code.
The problem
The buttons to delete all the links and the button to add one link does work perfectly without bugs. However, the button to which one link should be deleted doesn't work, I tried various ways including splicing. I am trying to remove the link from the DOM and from the chrome.storage.local, both actions do not work. In the following code you can see all of the files I have thus far. The code of when the 'X' button is pressed doesn't get executed (see these pictures): https://i.stack.imgur.com/gg1Dy.png and https://i.stack.imgur.com/4oGdI.png
The code
manifest.json:
gist.github.com/kobrajunior/78acda830c2d1c384333542422f1494d
popup.js:
functions to look at: addToDom and removeMe and the very first event listener when the DOM is fully loaded
gist.github.com/kobrajunior/4852f85ae18cfb9edbe542a820b8c107
For extra information (if needed), the popup.html:
gist.github.com/kobrajunior/1c26691734c19391c62dc336ed2e1791
Thank you in advance.
For the following lines in popup.js, you want to restore (show all the items/buttons) and bind listeners, however don't forget addToDom is called inside the callback of chrome.storage.local.get, that means by the time you assign value to allButtons, they're not added to DOM, that causes allButtons.length === 0 and you didn't bind anything in fact.
Try to move the binding logic inside the callback of restore (You may encounter other issues however that's not covered in this quesions).
document.addEventListener('DOMContentLoaded', function () {
restore();
var allButtons = document.getElementsByClassName('buttons');
function listenI(i) {
allButtons[i].addEventListener('click', () => removeMe(i));
}
for (var i = 0; i < allButtons.length; i++) {
listenI(i);
}
});
function restore() {
// get the tab link and title
chrome.storage.local.get({ urlList: [], titleList: [] }, function (data) {
urlList = data.urlList;
titleList = data.titleList;
// add the titles and url's to the DOM
for (var i = 0, n = urlList.length; i < n; i++) {
addToDom(urlList[i], titleList[i]);
}
});
}

jQuery not selecting every image

I'm currently working on an userscript for a forum, however, it doesn't seem to work.
The forum has two themes, I want to replace the userbars (located in /groupimages/) from the new theme with the ones from the old theme.
I'm currently trying this:
$("img[src*='/groupimages/']").each(function() {
$(this).attr("src", $(this).attr("src").replace("/modern_pl/", "/blackreign/"));
});
/modern_pl/ is the directory of the new theme, /blackreign/ of the old one.
An example URL of an image is /images/modern_pl/groupimages/english/strange.gif
It does select some pictures, but not all. It looks like it suddenly stops, without giving out any error message in Chromes JS-Console.
Lets say the strange.gif is there 3 times on the page, it only replaces it once. Some other pictures (that should be selected because the source contains /groupimages/) are completely ignored, so I doubt that this is happening because one picture is there more than once.
Any ideas?
To me the snippet looks good.
Did you place it inside a Document ready function? If not, the problem could be that the pictures just aren't yet loaded when the script runs.
Try this:
$(function(){
$("img[src*='/groupimages/']").each(function() {
$(this).attr("src", $(this).attr("src").replace("/modern_pl/", "/blackreign/"));
});
});
UPDATE
Its hard to help when the code you present works.. but lets assume there is content loaded by ajax after the page loaded completely.
You could do this.. which is not nice at all.. but assuming you don't have further access to the code on the website, try this:
setTimeout(function(){
$("img[src*='/groupimages/']").each(function() {
$(this).attr("src", $(this).attr("src").replace("/modern_pl/", "/blackreign/"));
});
},1000);
This waits a second for other scripts to be loaded before running your code.
Something like that ?
var img = $( 'img' );
img.attr( 'src', img.attr( 'src' ).replace( "\/groupimages\/", "\/modern_pl\/") );

using javascript setTimeout to see if div has loaded

I'm loading remote data using dynamic script tags and JSON. the remote page that I'm displaying on my website has a div in it that I use to load content into.
The problem is the javascript functions do not see the div as the page loads because it is remote data. If I set a timeout of about 300, it usually works and my javascript can see the div. But sometimes it takes longer and it breaks the javascript.
I'm tring this:
function load_content() {
if (document.getElementById('remote_div') == null) {
setTimeout('load_content()', 300);
} else {
document.getElementById('remote_div').innerHTML = 'Content goes here'
}
}
but it just doesn't work. What am I doing wrong?
You may want to do this using setInterval. Something like:
var intrval = setInterval( function(){
if(document.getElementById('remote_div')) {
load_content();
clearInterval(intrval);
}, 50);
function load_content() {
//loading content here
}
This way you don't have to estimate the loading time. load_content is executed when div#remote_div can be found in the DOM tree.
Edited based on comments, forgot to assign the interval, so it wouldn't ever clear indeed.
Are you using iframe?
If so, try
document.getElementById('YOUR_IFRAME_ID').contentWindow.document.getElementById('remote_div')

Categories

Resources