admin管理员组文章数量:1415684
I'm fairly new to JS and not very familiar with jQuery, but I'd like to give a shot at dynamically calling slimbox's multi-image function.
For example, there is a photoslider that randomly cycles through 3 images on my website, and I would like slimbox to show 2 more images for the first and 1 more for the last. This means slimbox will display a total of 6 images in the slideshow.
So in case you need it, here's the detailed walk through: when the user visits my site, the user will see a div block that shows 1 image at a time. The image in the photoslider will rotate out to the next one (of the 3 randomly loaded). When the user clicks on the image, the user will trigger the slimbox (lightweight lightbox) and a larger slideshow will take up the screen (dimming the background). Through slimbox, the user will see a up to a total of 6 images cycle through.
In order to create a dynamic variable, I tried to use EVAL within a FOR loop, but this fails when running jQuery. EVAL works outside of the loop, though. I'm not sure which other function to use instead. Let's dig into the code...
Calling slimbox via JS:
// usage as shown for multi-image slideshow. yes, there are arrays within an array
jQuery.slimbox([["image","desc"], ["image","desc"], ["image","desc"]], startAtImage);
// or simplified further
jQuery.slimbox([[array1], [array3], [array2]], startAtImage);
// after appending the images to select the first and last images
jQuery.slimbox([[array1], [array4], [array5], [array3], [array2], [array6]], startAtImage);
Here's my attempt at dynamically calling the slimbox function:
var imgAlbum = "summer";
var arrayGiven = [1,3,2]; // randomized image order given
var img1 = [4,5]; // registering images to be appended -- aiming for [1,4,5]
var img2 = [6]; // registering images to be appended -- aiming for [2,6]
var desc1 = "Description #1"; // unique descriptions
var desc2 = "Description #2";
var desc3 = "Description #3";
var desc4 = "Description #4";
var desc5 = "Description #5";
var desc6 = "Description #6";
var arrayExtended = arrayGiven;
for(var i=1; i<=3; i++){ // cycle through arrayGiven and append images
var imgLocate = i;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended); // locating array index number of a specific image. if imgLocate = 1, then imgAtIndex = 0 , if 2 then 4, and so forth
var imgAfter = imgAtIndex + 1; // allows appending to selected image at index
eval("var imgCurrent = img" + imgLocate + ";"); // creating dynamic variable
if(imgCurrent != null){
arrayExtended.splice(imgAfter, 0, imgCurrent);
}
} // alert(arrayExtended) should be [1,4,5,3,2,6]
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
eval("var array" + imgLocate + " = ['img/" + imgAlbum + "/" + imgLocate + ".jpg',desc" + imgLocate + "];"); // if imgLocate = 1, then var array1 = ['img/summer/1.jpg',desc1];
// array1 array2 array3 array4 array5 array 6 ... now defined
}
var arrayMain = [];
for(var i=1; i<=arrayExtended.length; i++){ // must wait for arrays to be built before adding to arrayMain
var atIndex = i - 1;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended); // if imgLocate = 1, then imgAtIndex = 0 , if 2 then 4
eval("arrayMain.push('[' + array" + arrayExtended[atIndex] + " + ']');");
}
var imgClicked = 0; // clicked on image within arrayExtended index 0
var startAtImage = imgClicked; // slimbox slideshow will start on 1.jpg
jQuery.slimbox("[" + mainArray + "]",startAtImage);
And finally hoping for the following result:
jQuery.slimbox([["img/summer/1.jpg","Desciption #1"], ["img/summer/4.jpg","Desciption #4"], ["img/summer/5.jpg","Desciption #5"], ["img/summer/3.jpg","Desciption #3"], ["img/summer/2.jpg","Desciption #2"]], ["img/summer/6.jpg","Desciption #6"], 0);
Any help or advice will be much appreciated! There's much to learn.
Updated 8-26-11 Changed structure based on advices. Also added more images and groups into array to better illustrate the functionality needed. There are errors when trying to call image groups (1, 2, 7) from img object:
var imgAlbum = "summer";
var arrayGiven = [1,3,2,7,11]; // randomized image order given
var img = {
1: [4,5],
2: [6],
7: [10,8,9]
};
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6',
7: 'Description #7',
8: 'Description #8',
9: 'Description #9',
10:'Description #10',
11:'Description #11'
};
var arrayExtended = arrayGiven.slice();
for(var i=1; i<=arrayGiven.length; i++){
var imgLocate = i;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended);
var imgAfter = imgAtIndex + 1;
var imgCurrent = img[imgAfter];
if(imgCurrent != null){
arrayExtended.splice(imgAfter, 0, imgCurrent);
}
//alert(imgCurrent); // shows 4,5 undefined undefined undefined undefined
} //alert(arrayExtended);// shows 1,4,5,3,2,6,7,10,8,9,11
var imgArray = {};
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
imgArray[imgLocate] = ['imgs/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
}
var mainArray = [];
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
mainArray.push(imgArray[arrayExtended[atIndex]]);
//alert(imgArray[arrayExtended[atIndex]]); // shows (simplified) 1.jpg,Desc#1 undefined 3.jpg,Desc#3 2.jpg,Desc#2 undefined undefined
}
var imgClicked = 0;
var startAtImage = imgClicked;
jQuery.slimbox(mainArray,startAtImage);
Updated 8-30-11 FINAL SOLUTION Fixes applied and added randomizer from production code. The results are accurate. If you plan on using the randomizer, I remend keeping the images-to-be-appended outside of the getRandomArray range, unless you wish to see duplicates.
Thanks everyone for your awesome support!
function getRandomArray(min,max){
var A= [];
while(max>= min) A.push(max--)
A.sort(function(){return .5- Math.random()});
return A;
}
var randomness = getRandomArray(1,11).slice();
var leadingZeroArray = randomness.slice();
leadingZeroArray.unshift("0"); // was needed for my project, but if removed, everything else will need to be re-adjusted
var arrayGiven = randomness.slice(); // or you can plug in -> var arrayGiven = [1,3,2,7,11]; for original example
var imgAlbum = "summer";
var img = {
1: [4,5],
2: [6],
7: [10,8,9]
};
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6',
7: 'Description #7',
8: 'Description #8',
9: 'Description #9',
10:'Description #10',
11:'Description #11'
};
var arrayExtended = arrayGiven.slice();
for(var i=0; i<arrayGiven.length; i++){
var imgLocate = arrayGiven[i];
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended);
var imgAfter = imgAtIndex + 1;
var imgCurrent = img[imgLocate];
if(imgCurrent != null){
if(imgCurrent.length > 0){
for(var j=imgCurrent.length-1; j>-1; j--){
var imgMore = imgCurrent[j];
arrayExtended.splice(imgAfter, 0, imgMore);
}
}
else{arrayExtended.splice(imgAfter, 0, imgCurrent); }
}
}
var imgArray = {};
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
imgArray[imgLocate] = ['images/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
}
var mainArray = [];
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
mainArray.push(imgArray[arrayExtended[atIndex]]);
}
var imgClickedOn = 5;
var imgAtIndex = jQuery.inArray(imgClickedOn,arrayExtended);
jQuery.slimbox(mainArray,imgAtIndex);
I'm fairly new to JS and not very familiar with jQuery, but I'd like to give a shot at dynamically calling slimbox's multi-image function.
For example, there is a photoslider that randomly cycles through 3 images on my website, and I would like slimbox to show 2 more images for the first and 1 more for the last. This means slimbox will display a total of 6 images in the slideshow.
So in case you need it, here's the detailed walk through: when the user visits my site, the user will see a div block that shows 1 image at a time. The image in the photoslider will rotate out to the next one (of the 3 randomly loaded). When the user clicks on the image, the user will trigger the slimbox (lightweight lightbox) and a larger slideshow will take up the screen (dimming the background). Through slimbox, the user will see a up to a total of 6 images cycle through.
In order to create a dynamic variable, I tried to use EVAL within a FOR loop, but this fails when running jQuery. EVAL works outside of the loop, though. I'm not sure which other function to use instead. Let's dig into the code...
Calling slimbox via JS:
// usage as shown for multi-image slideshow. yes, there are arrays within an array
jQuery.slimbox([["image","desc"], ["image","desc"], ["image","desc"]], startAtImage);
// or simplified further
jQuery.slimbox([[array1], [array3], [array2]], startAtImage);
// after appending the images to select the first and last images
jQuery.slimbox([[array1], [array4], [array5], [array3], [array2], [array6]], startAtImage);
Here's my attempt at dynamically calling the slimbox function:
var imgAlbum = "summer";
var arrayGiven = [1,3,2]; // randomized image order given
var img1 = [4,5]; // registering images to be appended -- aiming for [1,4,5]
var img2 = [6]; // registering images to be appended -- aiming for [2,6]
var desc1 = "Description #1"; // unique descriptions
var desc2 = "Description #2";
var desc3 = "Description #3";
var desc4 = "Description #4";
var desc5 = "Description #5";
var desc6 = "Description #6";
var arrayExtended = arrayGiven;
for(var i=1; i<=3; i++){ // cycle through arrayGiven and append images
var imgLocate = i;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended); // locating array index number of a specific image. if imgLocate = 1, then imgAtIndex = 0 , if 2 then 4, and so forth
var imgAfter = imgAtIndex + 1; // allows appending to selected image at index
eval("var imgCurrent = img" + imgLocate + ";"); // creating dynamic variable
if(imgCurrent != null){
arrayExtended.splice(imgAfter, 0, imgCurrent);
}
} // alert(arrayExtended) should be [1,4,5,3,2,6]
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
eval("var array" + imgLocate + " = ['img/" + imgAlbum + "/" + imgLocate + ".jpg',desc" + imgLocate + "];"); // if imgLocate = 1, then var array1 = ['img/summer/1.jpg',desc1];
// array1 array2 array3 array4 array5 array 6 ... now defined
}
var arrayMain = [];
for(var i=1; i<=arrayExtended.length; i++){ // must wait for arrays to be built before adding to arrayMain
var atIndex = i - 1;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended); // if imgLocate = 1, then imgAtIndex = 0 , if 2 then 4
eval("arrayMain.push('[' + array" + arrayExtended[atIndex] + " + ']');");
}
var imgClicked = 0; // clicked on image within arrayExtended index 0
var startAtImage = imgClicked; // slimbox slideshow will start on 1.jpg
jQuery.slimbox("[" + mainArray + "]",startAtImage);
And finally hoping for the following result:
jQuery.slimbox([["img/summer/1.jpg","Desciption #1"], ["img/summer/4.jpg","Desciption #4"], ["img/summer/5.jpg","Desciption #5"], ["img/summer/3.jpg","Desciption #3"], ["img/summer/2.jpg","Desciption #2"]], ["img/summer/6.jpg","Desciption #6"], 0);
Any help or advice will be much appreciated! There's much to learn.
Updated 8-26-11 Changed structure based on advices. Also added more images and groups into array to better illustrate the functionality needed. There are errors when trying to call image groups (1, 2, 7) from img object:
var imgAlbum = "summer";
var arrayGiven = [1,3,2,7,11]; // randomized image order given
var img = {
1: [4,5],
2: [6],
7: [10,8,9]
};
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6',
7: 'Description #7',
8: 'Description #8',
9: 'Description #9',
10:'Description #10',
11:'Description #11'
};
var arrayExtended = arrayGiven.slice();
for(var i=1; i<=arrayGiven.length; i++){
var imgLocate = i;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended);
var imgAfter = imgAtIndex + 1;
var imgCurrent = img[imgAfter];
if(imgCurrent != null){
arrayExtended.splice(imgAfter, 0, imgCurrent);
}
//alert(imgCurrent); // shows 4,5 undefined undefined undefined undefined
} //alert(arrayExtended);// shows 1,4,5,3,2,6,7,10,8,9,11
var imgArray = {};
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
imgArray[imgLocate] = ['imgs/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
}
var mainArray = [];
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
mainArray.push(imgArray[arrayExtended[atIndex]]);
//alert(imgArray[arrayExtended[atIndex]]); // shows (simplified) 1.jpg,Desc#1 undefined 3.jpg,Desc#3 2.jpg,Desc#2 undefined undefined
}
var imgClicked = 0;
var startAtImage = imgClicked;
jQuery.slimbox(mainArray,startAtImage);
Updated 8-30-11 FINAL SOLUTION Fixes applied and added randomizer from production code. The results are accurate. If you plan on using the randomizer, I remend keeping the images-to-be-appended outside of the getRandomArray range, unless you wish to see duplicates.
Thanks everyone for your awesome support!
function getRandomArray(min,max){
var A= [];
while(max>= min) A.push(max--)
A.sort(function(){return .5- Math.random()});
return A;
}
var randomness = getRandomArray(1,11).slice();
var leadingZeroArray = randomness.slice();
leadingZeroArray.unshift("0"); // was needed for my project, but if removed, everything else will need to be re-adjusted
var arrayGiven = randomness.slice(); // or you can plug in -> var arrayGiven = [1,3,2,7,11]; for original example
var imgAlbum = "summer";
var img = {
1: [4,5],
2: [6],
7: [10,8,9]
};
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6',
7: 'Description #7',
8: 'Description #8',
9: 'Description #9',
10:'Description #10',
11:'Description #11'
};
var arrayExtended = arrayGiven.slice();
for(var i=0; i<arrayGiven.length; i++){
var imgLocate = arrayGiven[i];
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended);
var imgAfter = imgAtIndex + 1;
var imgCurrent = img[imgLocate];
if(imgCurrent != null){
if(imgCurrent.length > 0){
for(var j=imgCurrent.length-1; j>-1; j--){
var imgMore = imgCurrent[j];
arrayExtended.splice(imgAfter, 0, imgMore);
}
}
else{arrayExtended.splice(imgAfter, 0, imgCurrent); }
}
}
var imgArray = {};
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
imgArray[imgLocate] = ['images/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
}
var mainArray = [];
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
mainArray.push(imgArray[arrayExtended[atIndex]]);
}
var imgClickedOn = 5;
var imgAtIndex = jQuery.inArray(imgClickedOn,arrayExtended);
jQuery.slimbox(mainArray,imgAtIndex);
Share
Improve this question
edited Apr 29, 2013 at 10:46
Ingo Karkat
173k16 gold badges262 silver badges339 bronze badges
asked Aug 24, 2011 at 18:23
TransatticTransattic
401 silver badge7 bronze badges
4
- I think there might be a simpler way to do this, but I'm having some trouble understanding the intent of code. Do you think you could edit the question a little bit to describe what you want the code to do, in the end? – s4y Commented Aug 24, 2011 at 19:43
- I added more info below the 2nd paragraph. – Transattic Commented Aug 25, 2011 at 0:56
- I’m actually wondering about your code, the 2nd paragraph. Do you mean that you'd like to pass a total of six images to Slimbox, the first, fourth, and fifth being random, but want two specific images to be second and third and another to be last? Or, do you mean that you want to display three images in random order, with two images after a specific one (image #1) and another after a different specific one (image #2), no matter where they are in the random arrangement? Or, do you mean something else? – s4y Commented Aug 25, 2011 at 1:07
- It's a bit late to answer, but might as well... the page will show 3 random images in random order. When the user clicks on an image and that particular image has additional images linked to it, then slimbox will display that particular image clicked on plus X linked images to follow after. Image links (1.jpg -> 4.jpg, 5.jpg) (2.jpg -> 6.jpg) will be added into the array. So if on the home page, we see this order of images in the photoslider: 3.jpg, 1.jpg, 2.jpg, when clicked on 2.jpg slimbox will show 2.jpg, 6.jpg, 1.jpg, 4.jpg, 5.jpg, 3.jpg. Does that clear things up? – Transattic Commented Aug 25, 2011 at 23:32
4 Answers
Reset to default 4Instead of having multiple vars for img
, use an array or an object.
var img = {
1: [4,5],
2: [6]
};
Then instead of eval("var imgCurrent = img" + imgLocate + ";");
, you can do:
var imgCurrent = img[imgLocate];
You can do the same sort of thing for:
eval("var array" + imgLocate + " = ['img/" + imgAlbum + "/" + imgLocate + ".jpg',desc" + imgLocate + "];");
Create an object and put the arrays in there:
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6'
};
var imgArray = {};
imgArray[imglocate] = ['img/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
EDIT: Try changing var imgLocate = i;
inside for(var i=1; i<=arrayGiven.length; i++){
to var imgLocate = arrayGiven[i];
.
The global variables are members of the window
object, so you can just do:
var imgCurrent = window["img" + imgLocate];
However, using dynamic variable names like that is not a good practice. You should just put the values in an array:
var img = [
[4,5],
[6]
];
Now you can just access the array items:
var imgCurrent = img[imgLocate];
Note however that the array indices start at 0, not 1.
A few quick notes:
Please don’t use
eval()
. There are very, very few cases where it’s needed, and it has performance and security implications.You’ve discovered that JavaScript doesn’t have “variable variables” (the ability to get or set a variable by name), which is why you had to resort to
eval()
. When you need to look something up out of a set, don’t use a bunch of numbered variables. Try an array or an object instead.Objects in JavaScript don’t get copied when you assign them to variables. The line
var arrayExtended = arrayGiven;
doesn't make a copy of
arrayGiven
—arrayExtended
ends up being a variable which points at the same array. So, when you change something inarrayExtended
, it also changes it inarrayGiven
. If you need to copy an array in JavaScript, use.slice()
with no arguments:var arrayExtended = arrayGiven.slice();
Some other things in JavaScript, like objects, are trickier to copy.
What are you trying to do here? (
mainArray
is already an array) This is going to create a string which is a “[”, followed by the string representation ofmainArray
(each item in the array separated by mas), followed by “]”. Slimbox won’t know what to do with it.jQuery.slimbox("[" + mainArray + "]",startAtImage);
If you do want to wrap something in an array, just put brackets around it like you did up above:
[mainArray];
I think your main problem is "[" + mainArray + "]"
. With those tips, you should be able to make your code work (and, without eval()
). But, I want to show you my approach to this problem too. It’s below.
I’m storing the names and descriptions of all the images in an array. Because arrays in JavaScript (and a lot of other programming languages) start at 0 instead of one, I subtracted one from all the image numbers in the arrays that specify the order.
var album = "summer",
images = [
[
{ name: "1", description: "Description #1" },
{ name: "4", description: "Description #4" },
{ name: "5", description: "Description #5" }
],
[
{ name: "2", description: "Description #2" },
{ name: "6", description: "Description #6" }
],
[
{ name: "3", description: "Description #3" }
]
],
order = [0, 2, 1],
startAtImage = 0,
slimboxImages = Array.prototype.concat.apply([], order.map(function(id){ return images[id]; }))
.map(function(image){
return [ 'img/' + album + '/' + image.name + '.jpg', image.description];
});
jQuery.slimbox(slimboxImages, startAtImage);
any reason you can't just do
var imgCurrent = 'img' + imgLocate;
? It is basically NEVER a good idea to dynamically generate/execute code from within a script. It's next to impossible to debug, and you're not even really doing anything that can't be done WITHOUT eval in the first place.
本文标签:
版权声明:本文标题:javascript - Alternative way to using eval( ) to creating a dynamic variable within a for( ) while running jQuery? - Stack Overf 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745239396a2649232.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论