在运行jQuery时,使用eval()在for()中创建动态变量的另一种方法
Alternative way to using eval( ) to creating a dynamic variable within a for( ) while running jQuery?
我对JS相当陌生,对jQuery不太熟悉,但我想尝试动态调用slimbox的多图像函数。
例如,有一个photoslider在我的网站上随机循环3张图片,我希望slimbox在第一张图片上多显示2张,在最后一张图片上多显示1张。这意味着slibox将在幻灯片中显示总共6张图像。
因此,如果您需要它,这里有详细的步骤:当用户访问我的网站时,用户将看到一个div块,每次显示一个图像。photoslider中的图像将旋转到下一个(随机加载的3个中的一个)。当用户点击图像时,用户将触发slimbox(轻量级灯箱),一个更大的幻灯片将占据屏幕(调暗背景)。通过slibox,用户将看到一个多达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);
任何帮助或建议将不胜感激!有很多东西要学。
更新8-26-11 根据建议改变结构。还添加了更多的图像和组到数组中,以更好地说明所需的功能。当尝试从img object:
调用图像组(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最终解决方案修复了生产代码中应用和添加的随机化器。结果是准确的。如果您计划使用随机化器,我建议将要附加的图像保留在gerandomarray范围之外,除非您希望看到重复的图像。
感谢大家的大力支持!
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);
使用数组或对象代替img
的多个变量。
var img = {
1: [4,5],
2: [6]
};
那么你可以这样做,而不是eval("var imgCurrent = img" + imgLocate + ";");
:
var imgCurrent = img[imgLocate];
你可以做同样的事情:
eval("var array" + imgLocate + " = ['img/" + imgAlbum + "/" + imgLocate + ".jpg',desc" + imgLocate + "];");
创建一个对象并把数组放进去:
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:尝试将for(var i=1; i<=arrayGiven.length; i++){
中的var imgLocate = i;
更改为var imgLocate = arrayGiven[i];
。
全局变量是window
对象的成员,所以您可以这样做:
var imgCurrent = window["img" + imgLocate];
然而,使用这样的动态变量名并不是一个好的做法。你应该把这些值放到一个数组中:
var img = [
[4,5],
[6]
];
现在你可以直接访问数组项了:
var imgCurrent = img[imgLocate];
请注意,数组的下标从0开始,而不是1。
几点提示:
-
请不要使用
eval()
。在非常非常少的情况下需要它,并且它具有性能和安全方面的影响。 -
你已经发现JavaScript没有"可变变量"(通过名称获取或设置变量的能力),这就是为什么你不得不求助于
eval()
。当你需要从一个集合中查找一些东西时,不要使用一堆编号的变量。 -
JavaScript中的对象在赋值给变量时不会被复制。行
var arrayExtended = arrayGiven;
不复制
arrayGiven
-arrayExtended
最终成为指向同一个数组的变量。因此,当您在arrayExtended
中更改某些内容时,它也会在arrayGiven
中更改。如果你需要在JavaScript中复制一个数组,使用不带参数的.slice()
:var arrayExtended = arrayGiven.slice();
-
你到底想干什么?(
mainArray
已经是一个数组)这将创建一个字符串,它是一个"[",后跟mainArray
的字符串表示(数组中的每个项目用逗号分隔),后跟"]"。Slimbox不知道该怎么办。jQuery.slimbox("[" + mainArray + "]",startAtImage);
如果你想在数组中包装一些东西,只需像上面那样用括号括起来:
[mainArray];
我认为你的主要问题是"[" + mainArray + "]"
。有了这些技巧,您应该能够使您的代码工作(并且,没有eval()
)。但是,我也想向你们展示我解决这个问题的方法。下面是。
我将所有图像的名称和描述存储在一个数组中。因为JavaScript(以及许多其他编程语言)中的数组从0而不是1开始,所以我从数组中指定顺序的所有图像编号中减去1。
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);
任何你不能做的理由
var imgCurrent = 'img' + imgLocate;
?从脚本中动态生成/执行代码基本上不是一个好主意。它几乎不可能调试,而且您甚至没有真正做任何没有eval就不能做的事情。
- onkeyup无法动态创建多个文本区域
- 如何使用javascript从主svg对象动态创建svg视图框
- 在动态创建的元素上获取对特定选择器的引用
- JQuery对动态创建的对象进行选择
- 使用jquery动态创建ul-li
- 从动态创建的html选择中选择所选选项
- 如何在动态创建的节点上绑定函数
- 动态创建OnClick事件Javascript
- 谷歌地图动态创建的标记点击事件使用相同的标记
- 在动态创建的标记上添加事件
- 动态创建一个javascript/jquery多级数组
- 如何动态创建许多Jquery颜色选择器(eyecon)
- 如何为动态创建的文本区域中输入的值更新ng模型
- 对动态创建的元素运行jQuery.ech()
- 使用jQuery访问动态创建的项
- 动态创建的iframe中的window.onerror在lne 0处给出脚本错误
- 当用户点击动态创建的链接时,如何调用JS方法.JQuery,ASP.NET MVC
- 我想将链接关联到动态创建的p元素上的相应文章
- AngularJs从列表中动态创建指令
- 使用javascript动态创建html内容/元素