I am trying to construct a thumbnail slideshow with javascript. I am very new to Javascript so my way of doing it might be a little strange...
The problem I am running into is that I have a main image, and then I have 4 thumbnails. When I click on the first thumbnail it changes the main image, and the first thumbnail. But when I click on the changed thumbnail it needs to change the main image with a different photo (the one that corresponds to the new thumbnail)
I initialize my functions with a call like this:
document.getElementById('thumb1').onclick=thumbs1;
Which uses this function:
function thumbs1(){
num1 = 1;
num2 = 0;
var src1 = largeArray[num1];
var src2 = thumbArray[num2];
document.getElementById('main').src=src1;
document.getElementById('one').src=src2;
document.getElementById('one').id='change';
}
And I am trying to change the id of the new thumbnail to "change" and call another function like this:
document.getElementById('change').onclick=changed;
And this used the following function:
function changed(){
num1 = 0;
var src1 = largeArray[num1];
document.getElementById('change').src=src1;
document.getElementById('change').id='one';
}
When using Firebug I found the error, and I believe it is being caused by the fact that the call to document.getElementById('change').onclick=changed;. The browser can not find the Element Id "change" because I have not called the function which changed the ID yet.
Does anyone know how to fix this problem. (I know the code is of low quality... I am teaching my self)
Here is a live link to the page: My Page
Thanks for any help!!
var array = //id's of your images here. you could type them static or search your document for images and get their id attribute.
document.addEventListener("click", function(e){
var clicked_image = e.target || e.srcElement; //using jquery can help with this cause older versions of IE are stupid, but depends on if you want to support them.
var id = clicked_image.getAttribute(id);
var temp = document.getElementById("main").src;
for (var i = 0; i < array.length; i++){
if(array[i] == id){
document.getElementById("main").src = clicked_image.src;
clicked_image.src = temp;
}
}
})
That's pretty quick and dirty, you would be better off assigning eventlisteners to just your images. You would use the same syntax as above, but it should give you an idea of what to do.
With this you don't have to worry about what image got clicked, you just change the main, and you change the thumb to what the main was. So you eliminate the hassle of trying to keep track of what each image is.
Related
I found out that you can have a fallback URL for an <img> using onerror if the first loading fails.
But it is possible to provide a list of sources (urls) to try and keep trying until one of them loads?
I was messing around with this for about an hour and was working towards this solution with JavaScript. I think its very clunky and I wonder if there is more more pretty way of doing this.
My ugly approach
Each image has several data attributes such as fallback1, fallback2 with the alternatives sources to load from if loading fails. Every image also has this.onerror=null;this.src='error.jpg
So every image that fails to load will show the picture error.jpg instead.
So an image may look like this
<img src="https://i.imgur.com/iYNdJeW.jpg" onerror="this.onerror=null;this.src='error.jpg'" data-fallback1="https://i.imgur.com/iYNdJeW2.jpg" data-fallback2="https://i.imgur.com/iYNdJeW3.jpg" />
Call a script in window.onload that iterates over each image and check if the source ends with error.jpg.
If it does it takes the first fallback url in that image's data properties (fallback1) and changes the source to that. Then removes that data-property from the image (not sure if that is possible or meant to be done), because he has already been tried. Then the script recursively runs again.
The recursion stops if if no images' source ends in error.jpg OR If all images whose source ends with error.jpg do not have any data attributes (no more alternative sources to try).
I think it would work, but it seem very very hackish.
I found out about <picture> and <source> and was very optimistic, but <picture> just accepts a 404 if the image does not load.
Has anyone come up with a better approach for doing this? Ideally I wish you could give img a list of urls and it would just keep trying until it got a non-error.
You're setting onerror to null when your first error is fired. Onerror will automatically fire if you change the source and it fails to load again. You could just store the list of fallbacks and increment an index each time onerror is fired.
Here's an example, and you could easily convert this to store all of the different variables directly on the element. I've provided 4 fake URLs and a final placeholder image as a real URL. You'll see it does load the placeholder image.
var fallbacks = ["https://example.com/badurl1.jpg", "https://example.com/badurl2.jpg", "https://example.com/badurl3.jpg", "https://via.placeholder.com/350x150"];
var index = 0;
document.querySelector("img").onerror = function(){
if(index >= fallbacks.length) return;
let next = fallbacks[index];
this.src = next;
index++;
};
<img src="https://example.com/badurl.jpg"/>
This will cycle through a list until your image stops getting an error
to edit it, change the 'fallbacksrc' array
HTML
<img src="*" id="img" onerror="ImgOnError()"></img>
JS
let fallbacksrc=[]; //All All Fallbacks Here, when error will start at the second one because 1st one is already tried
let fallbackcount = 1;
let Img = document.getElementById('img')
function ImgOnError(){
if(fallbackcount >= fallbacksrc.length){
fallbackcount = 0
Img.src=fallbacksrc[fallbackcount]
}else{
Img.src=fallbacksrc[fallbackcount]
}
fallbackcount++;
}
I've come up with a vanilla-JavaScript way where you don't need to specify the image in javascript.
Define this function:
function incrementFallbackSrc(img, srcs) {
if (typeof img.fallbackSrcIndex === 'undefined') img.fallbackSrcIndex = 0;
img.src = srcs[img.fallbackSrcIndex++];
}
and for each image, pass all the fallback URLs in the function call.
<img
src="https://i.imgur.com/iYNdJeW.jpg"
onerror="javascript: incrementFallbackSrc(this, ['https://i.imgur.com/iYNdJeW2.jpg',
'https://i.imgur.com/iYNdJeW3.jpg',
'error.jpg'])">
>
to set it programmatically, you may have to put the function inside the definitiaion like so:
img.setAttribute('onerror', "function incrementFallbackSrc(img, srcs) {if (typeof img.fallbackSrcIndex === 'undefined') img.fallbackSrcIndex = 0;img.src = srcs[img.fallbackSrcIndex++];}; incrementFallbackSrc(this, ['" + fallbackUrl1 + "," + fallbackUrl2 + "'])");
I'm looking for a way to copy pdf documents and stack them resized (I think resize works as duplicate, so once this works I will be able to complete my script).
I've been using .duplicate for now, and I can only manage to copy 1 item[0] on the same doc. Besides if I copy element by element I won't be able to replace them easily that's why I want to copy the whole document
I'm opening every script I find to understand a possible method.
Syntax is ok
var targetFile = app.documents.add(); //this is my output file - it is created
folder = Folder.myDocuments; //this paragraph works for now
sourceFolder = folder.selectDlg("source");
for ( i = 0; i < files.length; i++ ){
var sourceDoc = app.open(files[i]);
var doc = app.activeDocument;
for (l = 0; l < doc.pageItems.length; l++) { //corrected error
doc.pageItems[i].selected = true;
}
var mySel = app.activeDocument.selection; //this paragraph need rework
newItem = mySel[0].duplicate(targetFile); //mysel.duplicate(targetFile) is not a function
// MAIN ERROR
}
I use ESTK and notepad++ and have checked the variable, nothing obviously wrong during F10 debug. Using Jongware's CHM reference guide and some github tutorial but they tend to help for single operation script. My goal is to have script without GUI to reduce errors and time to proceed
Thank you for your time
EDIT: spotted an error with i used two times in a loop
Simple self solution:
var mySel = app.activeDocument.selection;
app.executeMenuCommand('copy');
targetFile.activate();
newItem = app.executeMenuCommand('paste');
I need to download all the images from the gallery of this site but I don't know how to obtain the URL of them or where these URL are stored on.
I tried to download the entire site with some programs but none of them seems to download even the menu.
Hope someone have any idea how to achieve this without having to do it manually one by one.
Here I can saw the code that produce the URLs:
<script type="text/javascript">
$(function(){
$(".text-frame").not(".default-frame").hide();
$('#menubar .button').hover(function(){
$(this).toggleClass("button-hover");
});
$('#menubar .button').click(function(){
$(".text-frame").hide();
$("#image-viewer").hide();
$(".button").removeClass("button-active");
var showTextframe = $(this).attr("rel");
$("#" + showTextframe).show();
$(this).addClass("button-active");
});
function showImages (imgLinks){
for (var i = 0; i < imgLinks.length; i++){
//$("#image-box").append($('<img>').attr('src', imgLinks[i]));
var $imgSelector = $('<a>'+ (i + 1) +'</a>')
.data('imglink',imgLinks[i])
.click(function(){
$("#image-box").find("img").attr('src', $(this).data('imglink'));
$("#image-links").find('a').removeClass('active');
$(this).addClass('active');
//alert ("I open Image" + $(this).data('imglink'));
});
$("#image-links").append($imgSelector);
$("#image-links").find('a:first').trigger('click');
}
}
$.get("plants_w_links.md", function(semillaMenu){
var markdownConverter = new Showdown.converter();
$semillaMenu = $(markdownConverter.makeHtml(semillaMenu));
$semillaMenu.find("img").each(function(){
var $menuimage = $(this);
var $menulink = $(this).parent("li").find("a");
var menuimages = $menulink.data("menuimages") || [];
menuimages.push($menuimage.attr("src"));
$menulink.data("menuimages",menuimages);
$menuimage.remove();
});
$semillaMenu.find("a").click(function(){
var menuImages = $(this).data("menuimages");
//$("#image-box").empty();
$("#image-links").empty();
if (menuImages){
$("#image-viewer").show();
showImages(menuImages);
}
});
$semillaMenu.addClass("sf-menu sf-vertical");
$('#semilla-menu').html($semillaMenu);
jQuery('ul.sf-menu').superfish({delay:10});
});
});
</script>
The function showImages seems to generate the URL but I don't know what to do with that.
I found here many question asking something similar but all of them talking about donwloading images with progressive URL (like blabla.com/image1.jpg, blabla.com/image2.jpg, etc.) but it is not the case, the images are generated without a pattern (or not any that I can obtain or deduce).
EDIT: I need to know how those functions work in order to run something similar in the Chrome inspect console that gives me all the URL instead the URL of the clicked option of the menu.
EDIT2: Someone in a IRC channel told me that the script may be jQuery, so I'm adding the tag.
var urls = new Array();
Array.prototype.forEach.call( document.images, function( img ){ urls.push( img.src ) } );
console.log( urls );
After execution these lines of code urls will contain sources of all images on the page.
Finally someone on the jQuery chat tell me how to solve my problem. Accesing directly to this link was the answer. The link seems to contain the structure of the menues that semillaMenu function format (aparently) and process to show the images on the site.
This doesn't solve my question yet, because it's only working for this case. What I wanted was a way to obtain the URLs with a script but it's solve my problem.
So I let it be unaswered if someone know how to make a script that gives all the image links without having to process manually the plants_w_links.md file.
I'd like to know how can I replace every .gif images in a page for an image url that I already have. I've looked after many solutions but none could help me.
Edit: Removed the old code since it was causing some confusion
So does anybody knows how to do this? JS pure would be better since I can't get jQuery working properly with Tampermonkey.
Edit 2: Managed to get another code sort of working, but it doesn't replaces the image url, just adds to it.
var theImages = document.getElementsByTagName('img');
for(i=0; i<theImages.length; i++) {
if(theImages[i].src.indexOf('.gif') != -1) {
theImages[i].src = ('imageurl.jpg')}
}
Take a look at this line var image_png_src = image_png_src.replace(".gif", "image.jpg");. image_png_src is not yet defined but you try to call a replace property. Any way you probably wanted to use image_gif_src instead.
var image_png_src = image_gif_src.replace(".gif", "image.jpg");
Assuming your images have the same name, and you just want to change the extention, your code is almost right, you just made a small mistake. Here is the correct version:
var images = document.getElementsByTagName("img");
for (var i = 0; i < images.length; i++) {
var image_gif_src = images[i].src;
var image_png_src = image_gif_src.replace(".gif", ".jpg");
images[i].src = image_png_src;
}
Notice how image_png_src.replace in the second line of the for loop has been replaced with image_gif_src.replace? You were trying to do a replace on the wrong variable. Also, I changed "image.jpg" in your original example to just ".jpg" because I'm assuming you only mean to change the extention, not append the word "image" onto the end of whatever image you're changing.
If you want to change every gif to some other image, not just change the extention, this code would do it:
images[i].src = image_png_src;
for (var i = 0; i < images.length; i++) {
if( images[i].src.indexOf(".gif") > -1){
images[i].src = "New Image.jpg";
}
}
jquery approach
$("img").each(function(){
$(this).attr('src',$(this).attr('src').replace(".gif", ".jpg"));
});
fyi, to use jquery or other js libraries in Xmonkey,
simply add
// #require http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
in the ==UserScript== header. In case of conflicts, turning on jQuery.noConflict(); may help.
So I got it working using the following script:
var theImages = document.getElementsByTagName('img');
for(i=0; i<theImages.length; i++) {
if(theImages[i].src.indexOf('.gif') != -1) {
theImages[i].src = ('imageurl.jpg')}
}
Thanks to everybody that helped.
im kinda new to javascript i mean i know the syntax but not so much the libraries.
i need some help to get some files (pictures) from a folder into an arry lets say:
var[] pictures = ?;
(the folder is in my project and contain some pictures)
so i can loop over them and diplay them on the page i did some search but i didnt find any guide on how to do this.
i realy want to understand on how to do this for future projects even a link to known guid you guys know we will be a big help.
if it help im using asp.net.
Well, there are a lot of ways to approach the problem, to me what you can do is (if you don't know the location of the images beforehand) make a service that returns the src of every image, store that in an array, and then show them in the page.
I believe you are using jQuery so you can make an ajax request like this:
jQuery.ajax({
url: /*path to*/"Service.asmx/getSources"
//options, check documentation
});
then, from asp, make a new service (Service.asmx in my case) and create a method that returns the location of the pictures (in my case the method is called getSources)
I recommend you use JSON (and jQuery.getJSON() method) so you can return a List<string>.
Lastly you can iterate or store the sources in an array, I'll put an example with the getJSON method
var sources = []
jQuery.getJSON("Service.asmx/getSources", function(data) {
for(var i = 0, len = data.length; i<len ; i++) {
sources.push(data[i]);//store every source in the array
}
});
once you have the sources you can display them like this fiddle
Tell me if it helped or if you need another solution.
If you want an array of pictures just to display them later, you can simply use:
var sources = [
"path/to/yourImage1.jpg",
"path/to/yourImage2.jpg",
// ...
"path/to/yourImageN.jpg",
];
var pics = [];
for(var i = 0; i < sources.length; i++) {
var pic = new Image();
pic.src = sources[i];
pics[i] = pic;
}