运行 jQuery 时使用 eval() 在 for() 中创建动态变量的替代方法?
我对 JS 相当陌生,对 jQuery 不太熟悉,但我想尝试动态调用 slimbox 的多图像功能。
例如,我的网站上有一个照片滑块会随机循环显示 3 张图像,我希望 slimbox 在第一张图像中再显示 2 张图像,在最后一张图像中再显示 1 张图像。这意味着 slimbox 将在幻灯片中总共显示 6 张图像。
因此,如果您需要它,这里是详细的演练:当用户访问我的网站时,用户将看到一个 div 块,一次显示 1 个图像。照片滑块中的图像将旋转到下一张(随机加载的 3 张中的)。当用户单击图像时,用户将触发 slimbox(轻量级灯箱),并且更大的幻灯片将占据屏幕(使背景变暗)。通过 slimbox,用户将看到最多 6 张图像循环播放。
为了创建动态变量,我尝试在 FOR 循环中使用 EVAL,但是在运行 jQuery 时失败。不过,EVAL 在循环之外工作。我不确定该使用哪个其他功能。让我们深入研究一下代码...
通过 JS 调用 slimbox:
// 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);
这是我动态调用 slimbox 函数的尝试:
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);
最后希望得到以下结果:
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);
或建议将不胜感激!有很多东西需要学习。
更新时间:2011 年 8 月 26 日 根据建议更改了结构。还向数组中添加了更多图像和组,以更好地说明所需的功能。尝试从 img 对象调用图像组 (1, 2, 7) 时出现错误:
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);
更新 8-30-11 最终解决方案修复了从生产代码应用并添加的随机发生器。结果准确。如果您计划使用随机化器,我建议将要附加的图像保留在 getRandomArray 范围之外,除非您希望看到重复项。
感谢大家的大力支持!
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 recommend 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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不要为
img
使用多个变量,而是使用数组或对象。然后,您可以执行以下操作,而不是
eval("var imgCurrent = img" + imgLocate + ";");
: 您可以执行相同的操作:
创建一个对象并将数组放入其中:
编辑:尝试将
for(var i=1; i<=arrayGiven.length; i++){
内的var imgLocate = i;
更改为var imgLocate = arrayGiven[i];
。Instead of having multiple vars for
img
, use an array or an object.Then instead of
eval("var imgCurrent = img" + imgLocate + ";");
, you can do:You can do the same sort of thing for:
Create an object and put the arrays in there:
EDIT: Try changing
var imgLocate = i;
insidefor(var i=1; i<=arrayGiven.length; i++){
tovar imgLocate = arrayGiven[i];
.全局变量是 window 对象的成员,因此您可以这样做:
但是,使用这样的动态变量名称并不是一个好的做法。您应该将值放入数组中:
现在您可以访问数组项:
但请注意,数组索引从 0 开始,而不是 1。
The global variables are members of the
window
object, so you can just do:However, using dynamic variable names like that is not a good practice. You should just put the values in an array:
Now you can just access the array items:
Note however that the array indices start at 0, not 1.
一些简短的说明:
请不要使用
eval()
。需要它的情况非常非常少,并且它会影响性能和安全性。您已经发现 JavaScript 没有“变量”(通过名称获取或设置变量的能力),这就是您必须求助于
eval()
的原因。当您需要从集合中查找某些内容时,不要使用一堆编号变量。尝试使用数组或对象。当您将 JavaScript 中的对象分配给变量时,它们不会被复制。线路
不会复制
arrayGiven
-arrayExtended
最终成为指向同一数组的变量。因此,当您更改arrayExtended
中的某些内容时,它也会更改arrayGiven
中的内容。如果您需要在 JavaScript 中复制数组,请使用不带参数的.slice()
:JavaScript 中的一些其他内容(例如对象)复制起来比较困难。
你想在这里做什么? (
mainArray
已经是一个数组)这将创建一个字符串,它是一个“[”,后跟mainArray
的字符串表示形式(数组中的每个项目由逗号),后跟“]”。 Slimbox 不知道如何处理它。如果您确实想将某些内容包装在数组中,只需像上面那样用括号括起来即可:
<前><代码>[mainArray];
我认为您的主要问题是
"[" + mainArray + "]"
。有了这些技巧,您应该能够使您的代码正常工作(并且无需eval()
)。但是,我也想向您展示我解决这个问题的方法。就在下面。我将所有图像的名称和描述存储在一个数组中。由于 JavaScript(以及许多其他编程语言)中的数组从 0 而不是 1 开始,因此我从数组中指定顺序的所有图像编号中减去 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
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: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 commas), followed by “]”. Slimbox won’t know what to do with it.If you do want to wrap something in an array, just put brackets around it like you did up above:
I think your main problem is
"[" + mainArray + "]"
. With those tips, you should be able to make your code work (and, withouteval()
). 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.
有什么理由你不能这么做
?从脚本中动态生成/执行代码基本上从来都不是一个好主意。调试几乎是不可能的,而且你甚至没有真正做任何没有 eval 就无法完成的事情。
any reason you can't just do
? 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.