14 Replies - 315 Views - Last Post: 02 February 2012 - 06:03 AM

Topic Sponsor:

#1 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Why does this need eval?

Posted 31 January 2012 - 08:07 PM

Hi everyone. I have a javascript object, that has a function called clickSlide. The object has a property called changeEffectDuration, which I can access within clickSlide going this.changeEffectDuration...

Now, I'm trying to use a jquery effect... animate, but when I try to access this.changeEffectDuration in my jquery function parameters it won't work unless I eval it., so it looks likes this....

cObjs.eq(B).animate(
						{left:slideDistance},
						{
							duration:eval(this.changeEffectDuration),


Is there anyway to get this.changeEffectDuraction in there without eval?

Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: Why does this need eval?

#2 codeprada  Icon User is offline

  • Changed Man With Different Priorities
  • member icon

Reputation: 876
  • View blog
  • Posts: 2,250
  • Joined: 15-February 11

Re: Why does this need eval?

Posted 31 January 2012 - 09:14 PM

this.changeEffectDuration would have to be a string since it's being passed to eval. You can create a Function by passing the code to it's constructor.

Example
var str = 'alert("Hello World")';

eval(str);

var func = new Function(str);
func();


Was This Post Helpful? 0
  • +
  • -

#3 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Re: Why does this need eval?

Posted 31 January 2012 - 09:24 PM

But according to the docs, it can be a string or a number ... http://api.jquery.com/animate/
Was This Post Helpful? 0
  • +
  • -

#4 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 3755
  • View blog
  • Posts: 9,707
  • Joined: 16-October 07

Re: Why does this need eval?

Posted 01 February 2012 - 05:41 AM

It would entirely depend what this.changeEffectDuration is. If it's a really a function, you should just be able to stick it in there. You'd use eval if it wasn't.
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 3755
  • View blog
  • Posts: 9,707
  • Joined: 16-October 07

Re: Why does this need eval?

Posted 01 February 2012 - 05:47 AM

PS: Though about this for half a second. The second parameter for animate isn't a function, it's a number.

Perhaps:
var d = this.changeEffectDuration();
cObjs.eq(B).animate( {left:slideDistance}, d, ...

Was This Post Helpful? 0
  • +
  • -

#6 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Re: Why does this need eval?

Posted 01 February 2012 - 06:01 AM

I knoowww. this.changeEffectDuration is a number. Its 5000. Its weird.

BTW I'm using the .animate( properties, options ) way, so my options are an object as well.
Was This Post Helpful? 0
  • +
  • -

#7 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 3755
  • View blog
  • Posts: 9,707
  • Joined: 16-October 07

Re: Why does this need eval?

Posted 01 February 2012 - 07:22 AM

View Postdameon51, on 01 February 2012 - 09:01 AM, said:

I knoowww. this.changeEffectDuration is a number. Its 5000. Its weird.


Good. Now instead of this.changeEffectDuration, try assigning a var to that right before and passing that instead.

I know that sounds crazy, but "this" in javascript is kind of crazy and can change contexts on you when you least expect it. The easiest way to deal with it is to make a local var reference to a this property before going anywhere the context may change.

Try it.
Was This Post Helpful? 0
  • +
  • -

#8 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Re: Why does this need eval?

Posted 01 February 2012 - 08:25 PM

When you're creating an object, I'm assuming the this keyword then belongs to the object you're creating?
Was This Post Helpful? 0
  • +
  • -

#9 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Re: Why does this need eval?

Posted 01 February 2012 - 08:38 PM

Well this is weird...

Now i'm doing this....

var tempChangeEffectDuration = this.changeEffectDuration;

					cObjs.eq(B).animate(
						{left:"+=" + slideDistance},
						{
							duration:tempChangeEffectDuration,


And it STILL doesn't work without and eval!?
Was This Post Helpful? 0
  • +
  • -

#10 Atli  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1759
  • View blog
  • Posts: 2,693
  • Joined: 08-June 10

Re: Why does this need eval?

Posted 01 February 2012 - 08:44 PM

Could you post more of the surrounding code? Perhaps the entire function or object that this is in?
Was This Post Helpful? 0
  • +
  • -

#11 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Re: Why does this need eval?

Posted 01 February 2012 - 08:50 PM

Here ya go

stealthOutPutCommon.prototype.clickSlide = function(slideDir,childSlide,thisThumb){

	if(this.slideFinished){
		this.slideFinished = false;					
		var mf = $s("mfmcc-" + this.moduleClassName); //main module frame
		var ms = $s("clss-" + this.moduleClassName); //storage container
		var cObjs = $("#mfmcc-" + this.moduleClassName + " .mi-" + this.moduleClassName); //current visible objects
		var stObjs = $("#clss-" + this.moduleClassName + " .mi-" + this.moduleClassName); //objects in storage		
		var baseObj = cObjs[0]; //current CSBaseContainer to get our sliding and offset dimenions
		var tempModClass = this.moduleClassName;
		var tempModChildClass = this.childClassName;
		var tempChangeEffectDuration = this.changeEffectDuration;
		var tempEffectEasing = this.effectEasing;

		if(this.slideAxis == 0){
			//how far it should be offset
			var baseObjMargins, baseObjPadding = 0; 
			var bS = baseObj.style;
			
			if(bS.marginLeft && bS.marginLeft.length > 0) baseObjMargins += bS.marginLeft;			
			if(bS.marginRight && bS.marginRight.length > 0) baseObjMargins += bS.marginRight;		
			if(bS.paddingLeft && bS.paddingLeft.length > 0) baseObjPadding += bS.paddingLeft;		
			if(bS.paddingRight && bS.paddingRight.length > 0) baseObjPadding += bS.paddingRight;
			
			var baseObjSize = baseObj.offsetWidth + baseObjMargins + baseObjPadding;
			var slideDistance = mf.offsetWidth;
			
			if(slideDir) slideDistance = slideDistance * -1;
						
			for(var i = 0; i < this.holdQty; i++){//we're always accessing the first item, since we're removing them
				if(!stObjs[0]){//create temp objs if stObjs is empty
					var tmpSObj = buildHtml.createDOMElement(
									"div",
									{
										className:cObjs[i].className + " tmpObj",
										id:this.moduleClassName + "tmpObj" + i
									}
								);
				}
				else if(slideDir) tmpSObj = stObjs[0];
				else tmpSObj = stObjs[stObjs.length-1];
				
				var tSt = tmpSObj.style; //style of the object we're sliding
				
				if(slideDir){
					tSt.position = "absolute";
					tSt.top = cObjs[i].offsetTop - parseInt(cObjs.eq(i).css("marginTop")) + "px";
					//how far it should be offset
					tSt.left = mf.offsetWidth + cObjs[i].offsetLeft - parseInt(cObjs.eq(i).css("marginLeft"))  + "px";
					mf.appendChild(tmpSObj); //place the element in the module frame
				}
				else{
					tSt.position = "absolute";
					tSt.top = cObjs[i*2].offsetTop - parseInt(cObjs.eq(i*2).css("marginTop")) + "px";
					//how far it should be offset
					tempoffsetRight = mf.offsetWidth - cObjs[i*2].offsetLeft + parseInt(cObjs.eq(i*2).css("marginLeft"));
					tSt.left = tempoffsetRight * -1 + "px";
					mf.insertBefore(tmpSObj,cObjs[i]); //place the element in the module frame
				}
				
				var cObjs = $("#mfmcc-" + this.moduleClassName + " .mi-" + this.moduleClassName); 
				var stObjs = $("#clss-" + this.moduleClassName + " .mi-" + this.moduleClassName);	
			}	
			
			/*when we are doing multiple images at once, the callback of the first ones
			  finish before the later effects even start. use use this counter to keep track 
			  of where we're at so we can do what we need in the callback on the last effect*/
			var tempCount = tempHq = this.holdQty * 2;

			for(var b = 0; b < tempHq; b++){
				if(cObjs[b]){
					cObjs[b].style.position = "absolute";
					cObjs.eq(B).animate(
						{left:"+=" + slideDistance},
						{
							duration:tempChangeEffectDuration,
							easing:tempEffectEasing,
							complete:function(){
								tempCount--; //counter to keep track of what effect we're on
								
								if(!tempCount){ //reset styling, push elements back into storage
									var cObjs = $("#mfmcc-" + tempModClass + " .mi-" + tempModClass); 
									var stObjs = $("#clss-" + tempModClass + " .mi-" + tempModClass);

									for(var s = 0; s < tempHq; s++){
										if(s < window[tempModClass].holdQty){//elements going into storage
											if(slideDir){
												var tempCoStyle = cObjs[0].style;
												tempCoStyle.left = "auto";
												tempCoStyle.right = "auto";
												tempCoStyle.top = "auto";
												tempCoStyle.position = "relative";
												ms.appendChild(cObjs[0]);
											}
											else{
												var thisObjLoc = cObjs.length-1;
												var tempCoStyle = cObjs[thisObjLoc].style;
												tempCoStyle.left = "auto";
												tempCoStyle.right = "auto";
												tempCoStyle.top = "auto";
												tempCoStyle.position = "relative";
												
												//the storage container might be empty if the holdQty is the 
												//same as the number of elements in the storage container
												if(stObjs[0]) ms.insertBefore(cObjs[thisObjLoc],stObjs[0]);														
												else ms.appendChild(cObjs[thisObjLoc]);
											}
											var cObjs = $("#mfmcc-" + tempModClass + " .mi-" + tempModClass); 
											var stObjs = $("#clss-" + tempModClass + " .mi-" + tempModClass);
										}
										else{//visible items
											var thisObjLoc = s-window[tempModClass].holdQty;
											var tempCoStyle = cObjs[thisObjLoc].style;											
											tempCoStyle.left = "auto";
											tempCoStyle.right = "auto";
											tempCoStyle.top = "auto";
											tempCoStyle.position = "relative";
											//last item
											if(s===tempHq-1){											
												window[tempModClass].slideFinished = true;

												//if a child thumb nail is clicked
												if(childSlide) window[tempModChildClass].parentSlide(thisThumb);
											}
										}
									}//loop through pushing hidden elements
								}//counter for what effect we're on																						
							}//jquery call back function
						}//jquery animate options
					);//jquery animate effect
				}//if the element exists
				else break;
			}//if element in for loop exists
		}//for loop
	}//if slideFinished
} //clickSlide function closer


Was This Post Helpful? 0
  • +
  • -

#12 Atli  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1759
  • View blog
  • Posts: 2,693
  • Joined: 08-June 10

Re: Why does this need eval?

Posted 01 February 2012 - 10:21 PM

One thing that jumps out at me is the for loop uses a lower case b, but your .eq() call uses an upper case B. Javascript is case-sensitive, so you should be getting an error at that point.

The way you set the duration should not cause any problems. You are creating a local variable well before any changes to which object this may be referencing. - However, if you are creating a lot of local variables to reference the core object's properties, you may as well just create a reference to the object itself instead.
MyObject.prototype.myFunction = function() {
    var self = this;
    // Now "self" will always refer to the MyObject instance,
    // even if the target of "this" changes.

    $("p").each(function(index) {
        // "this" now refers to the DOM element for this iteration
        // through the "p" element list.
        $(this)
            .css("position", "absolute")
            .animate({
                left: "+=" + self.slideDistance
            }, {
                duration: self.changeEffectDuration,
                easing: self.effectEasing
            });
    });
}


Was This Post Helpful? 0
  • +
  • -

#13 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Re: Why does this need eval?

Posted 01 February 2012 - 10:25 PM

That capital B... I have no idea where that came from. It isn't in my code, but its a straight copy and paste... Good idea about the var self. Still not sure whats up with it needing eval though
Was This Post Helpful? 0
  • +
  • -

#14 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 3755
  • View blog
  • Posts: 9,707
  • Joined: 16-October 07

Re: Why does this need eval?

Posted 02 February 2012 - 05:56 AM

Wow, that a lot of code just all right there. I'd recommend breaking up the jobs in smaller functions. While anonymous functions in javascript are cool, don't hurt yourself.

e.g.
// because you do this a lot
function getCObjs(modClass) { return $("#mfmcc-" + modClass + " .mi-" + modClass); }
function getStObjs(modClass) { return $("#clss-"  + modClass + " .mi-" + modClass); }

// you also do this several times; avoid copy paste
function setCoAutoStyle(obj) {
	var tempCoStyle = obj.style;
	tempCoStyle.left = "auto";
	tempCoStyle.right = "auto";
	tempCoStyle.top = "auto";
	tempCoStyle.position = "relative";
	return obj;
}

// A large chunk of your animate.  Not sure if I caught all the vars...
function processComplete(tempModClass, tempHq, ms){
	var cObjs = getCObjs(tempModClass); 
	var stObjs = getStObjs(tempModClass);

	for(var s = 0; s < tempHq; s++){
		if(s < window[tempModClass].holdQty){//elements going into storage
			if(slideDir){
				ms.appendChild(setCoAutoStyle(cObjs[0]));
			} else {
				var obj = setCoAutoStyle(cObjs[cObjs.length-1]);
				//the storage container might be empty if the holdQty is the 
				//same as the number of elements in the storage container
				if(stObjs[0]) {
					ms.insertBefore(obj,stObjs[0]);
				} else {
					ms.appendChild(obj);
				}
			}
			// I doubt you meant for this to be var...
			cObjs = getCObjs(tempModClass); 
			stObjs = getStObjs(tempModClass);
		} else{ //visible items
			var thisObjLoc = s-window[tempModClass].holdQty;
			setCoAutoStyle(cObjs[thisObjLoc]);
			//last item
			if(s===tempHq-1){											
				window[tempModClass].slideFinished = true;

				//if a child thumb nail is clicked
				if(childSlide) window[tempModChildClass].parentSlide(thisThumb);
			}
		}
	}
}

// in prototype, complete function looks like
complete:function(){
	tempCount--; //counter to keep track of what effect we're on
	if(!tempCount){ //reset styling, push elements back into storage
		processComplete(tempModClas, tempHq, ms);
	}
}




It might seem silly to break things up into smaller chunks and then have to pass around all the variables again; it's not. This is a tool to let you see what code is doing what you think it is. Once you're satisfied that a function is working properly, then you can move on to other parts of the code more easily. It also makes you very aware of which part of your program is using which values. The fewer variables you're juggling at any given time, the better.

One bug that jumped out at me, you never initialize baseObjMargins.

The capital B is a known forum bug. Don't worry about it. It's kind of an awkward smilie appendix that they've never managed to remove.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#15 dameon51  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 07-June 10

Re: Why does this need eval?

Posted 02 February 2012 - 06:03 AM

Thats awesome! Thats for the info!

baseObjMargins is initialized, but I don't give it a value. Line 17 of the copied and pasted code.

The function is pretty big, but is working besides the bug I originally mentioned. But I'll definitely look into breaking it down the way you mentioned.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1