JavaScript - Not Understanding Exactly What Prototype
Anyone wanna give me some pointers on how prototypes work exactly? ;o
Especially in the context of this code: Code: var chatscroll = new Object(); chatscroll.Pane = function(scrollContainerId){ this.bottomThreshold = 20; this.scrollContainerId = scrollContainerId; this._lastScrollPosition = 100000000; } chatscroll.Pane.prototype.activeScroll = function(){ var _ref = this; var scrollDiv = document.getElementById(this.scrollContainerId); var currentHeight = 0; var _getElementHeight = function(){ var intHt = 0; if(scrollDiv.style.pixelHeight)intHt = scrollDiv.style.pixelHeight; else intHt = scrollDiv.offsetHeight; return parseInt(intHt); } var _hasUserScrolled = function(){ if(_ref._lastScrollPosition == scrollDiv.scrollTop || _ref._lastScrollPosition == null){ return false; } return true; } var _scrollIfInZone = function(){ if( !_hasUserScrolled || (currentHeight - scrollDiv.scrollTop - _getElementHeight() <= _ref.bottomThreshold)){ scrollDiv.scrollTop = currentHeight; _ref._isUserActive = false; } } if (scrollDiv.scrollHeight > 0)currentHeight = scrollDiv.scrollHeight; else if(scrollDiv.offsetHeight > 0)currentHeight = scrollDiv.offsetHeight; _scrollIfInZone(); _ref = null; scrollDiv = null; } It's code to make the scrollbars autoscroll down. Full article and extra info he http://radio.javaranch.com/pascarell...837038219.html I sort of understand it but I'm not clear on what prototypes are. Similar TutorialsHi, all~..According to ECMAScript, the root of the prototype chain is Object.Prototype. Each object has an internal property [[Prototype]] that could be another object or NULL.... However, it also says that every function has the Function prototype object: Function.Prototype, it confused me, because a function is an object, for a function object, what is its function prototype and object prototype..For example: Code: var x = function (n) {return n+1;}; what is the relationships of x, Object.Prototype and Function.Prototype Thx a lot !!!!!!!!! hi, i'm currently stumped by the following code. what's the point of using x.constructor.prototype? (highlighted in red) why not directly use x.prototype.classname to check whether 'classname' property is in this class? thx in advance Code: function getType(x) { // If x is null, return "null" if (x == null) return "null"; // Next try the typeof operator var t = typeof x; // If the result is not vague, return it if (t != "object") return t; // Otherwise, x is an object. Use the default toString( ) method to // get the class value of the object. var c = Object.prototype.toString.apply(x); // Returns "[object class]" c = c.substring(8, c.length-1); // Strip off "[object" and "]" // If the class is not a vague one, return it. if (c != "Object") return c; // If we get here, c is "Object". Check to see if // the value x is really just a generic object. if (x.constructor == Object) return c; // Okay the type really is "Object" // For user-defined classes, look for a string-valued property named // classname, that is inherited from the object's prototype if ("classname" in x.constructor.prototype && // inherits classname typeof x.constructor.prototype.classname == "string") // its a string return x.constructor.prototype.classname; // If we really can't figure it out, say so. return "<unknown type>"; } hi, I'm trying to inherit with prototype but I'm not able to do so. The problem is that I have a few functions which use some common variables and common functions and I want to inherit a Resource object with all these parameters. I also whant this inheritance to be done when I load the function, so no extra functions are loaded unless I need them. Here's the code Code: function Resource(){ this.url=''; this.object=new Object(); this.id=''; this.categories=new Array(); } function Users(){ Users.prototype=new Resource(); this.url='user/'; this.name=''; this.email=''; }; function test(){ var users = new Users(); alert(users.id); }; When I run the test function for the first time I get an undefined. a second time works fine. I I get the prototype definition outside the User() function it also works fine, but I want the inherited function to be loaded when I need it. Any ideas? As always, thank you for your help. im currently using a prototype add on for one of my sites and id like to convert it to mootools... problem is, i dont know the first thing about prototype! i stumbled upon this before i learned any javascript and ive gotten to know mootools and like using it... heres the code, let me know if anyone can help! Code: /** * @author Bruno Bornsztein <bruno@missingmethod.com> * @copyright 2007 Curbly LLC * @package Glider * @license MIT * @url http://www.missingmethod.com/projects/glider/ * @version 0.0.3 * @dependencies prototype.js 1.5.1+, effects.js */ /* Thanks to Andrew Dupont for refactoring help and code cleanup - http://andrewdupont.net/ */ Glider = Class.create(); Object.extend(Object.extend(Glider.prototype, Abstract.prototype), { initialize: function(wrapper, options){ this.scrolling = false; this.wrapper = $(wrapper); this.scroller = this.wrapper.down('div.scroller'); this.sections = this.wrapper.getElementsBySelector('div.section'); this.options = Object.extend({ duration: 1.0, frequency: 3 }, options || {}); this.sections.each( function(section, index) { section._index = index; }); this.events = { click: this.click.bind(this) }; this.addObservers(); if(this.options.initialSection) this.moveTo(this.options.initialSection, this.scroller, { duration:this.options.duration }); // initialSection should be the id of the section you want to show up on load if(this.options.autoGlide) this.start(); }, addObservers: function() { var controls = this.wrapper.getElementsBySelector('div.controls a'); controls.invoke('observe', 'click', this.events.click); }, click: function(event) { this.stop(); var element = Event.findElement(event, 'a'); if (this.scrolling) this.scrolling.cancel(); this.moveTo(element.href.split("#")[1], this.scroller, { duration:this.options.duration }); Event.stop(event); }, moveTo: function(element, container, options){ this.current = $(element); Position.prepare(); var containerOffset = Position.cumulativeOffset(container), elementOffset = Position.cumulativeOffset($(element)); this.scrolling = new Effect.SmoothScroll(container, {duration:options.duration, x:(elementOffset[0]-containerOffset[0]), y:(elementOffset[1]-containerOffset[1])}); return false; }, next: function(){ if (this.current) { var currentIndex = this.current._index; var nextIndex = (this.sections.length - 1 == currentIndex) ? 0 : currentIndex + 1; } else var nextIndex = 1; this.moveTo(this.sections[nextIndex], this.scroller, { duration: this.options.duration }); }, previous: function(){ if (this.current) { var currentIndex = this.current._index; var prevIndex = (currentIndex == 0) ? this.sections.length - 1 : currentIndex - 1; } else var prevIndex = this.sections.length - 1; this.moveTo(this.sections[prevIndex], this.scroller, { duration: this.options.duration }); }, stop: function() { clearTimeout(this.timer); }, start: function() { this.periodicallyUpdate(); }, periodicallyUpdate: function() { if (this.timer != null) { clearTimeout(this.timer); this.next(); } this.timer = setTimeout(this.periodicallyUpdate.bind(this), this.options.frequency*1000); } }); Effect.SmoothScroll = Class.create(); Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), { initialize: function(element) { this.element = $(element); var options = Object.extend({ x: 0, y: 0, mode: 'absolute' } , arguments[1] || {} ); this.start(options); }, setup: function() { if (this.options.continuous && !this.element._ext ) { this.element.cleanWhitespace(); this.element._ext=true; this.element.appendChild(this.element.firstChild); } this.originalLeft=this.element.scrollLeft; this.originalTop=this.element.scrollTop; if(this.options.mode == 'absolute') { this.options.x -= this.originalLeft; this.options.y -= this.originalTop; } }, update: function(position) { this.element.scrollLeft = this.options.x * position + this.originalLeft; this.element.scrollTop = this.options.y * position + this.originalTop; } }); G'day, How would I go about copying all the prototype functions AND the constructor from one object into another object, and then call them? Code: function myOriginal() { alert('Hello'); } myOriginal.prototype.example = function() { alert('In example '+this.test); } function myNewThing() { // Copy myOriginal into this object here this.oldconstructor(); // Should now display "Hello" this.test = 'from myNewThing'; this.example(); // Should now display "In example myNewThing" } I know I can use this.example.call(this), but that's not an acceptable solution. I want to deploy this style over dozens, potentially hundreds of objects. Thanks muchly, Your friend from server-side... Code: /** * @class TestInheritance * * This is a class and it's constructor all in one but the constructor is not set yet */ function TestInheritance(){ this.testName; return this; } /** * @extends Util * Make sure this is called after the constructor/class declaration */ TestInheritance.prototype = new Util(); /** * @ctor TestInheritance * Set it to itself if there isn't an explicit constructor */ TestInheritance.prototype.constructor = TestInheritance; /** * @extends Util * This specifically is set to allow TestInheritance to access it's parent's identity */ TestInheritance.prototype.parent = new Util(); /** * @extends Util * @argument testName String * All functions are called after setting the prototype */ TestInheritance.prototype.setTestName = function(testName){ this.testName = testName; } How would I reference the same Util class on both the prototype and the parent? Hi I am using a program called aptabs which uses the Protoype framework. The problem is that when I create a new tab and refresh the page, the newly created tab disappears. How can I resolve this ? NOTE: The zip file for aptabs is attached. Thanks Hi, I'm trying to use a javascript tabstrip script called aptabs, which uses prototype.js. However, prototype.js won't load properly, because the following error occurs in prototype.js: destination is undefined on the following line (3042): destination[property] = value.methodize(); The function this line is in is: Code: function copy(methods, destination, onlyIfAbsent) { onlyIfAbsent = onlyIfAbsent || false; for (var property in methods) { var value = methods[property]; if (!Object.isFunction(value)) continue; if (!onlyIfAbsent || !(property in destination)) destination[property] = value.methodize(); } } I've tried using versions 1.6.0 all the way up to 1.6.1, but I still get the same error. Can someone suggest what this error could be caused by and possible fixes? Debbie Hi there I am trying to retrieve xml data using the prototype Ajax.Request. I think I am getting the xml though I am unsure as to how to retrieve the text from the nodes here is the function I am using to try and populate a text field Code: function makeMarkerXml() { new Ajax.Request('coords.xml', { method:'post', onSuccess: function(transport){ ////this will not work///////// var coord = transport.responseXML.childNodes(0).childNodes(0).firstChild.text; /////////////////////////////// }, onFailu function(){ alert('Call failed') } }); } can anyone help? Array.prototype.each = function (fn) { this.map(fn) } This is my each function that works great in every other browser but IE. UGH! What am I doing wrong? the error points to the this in the function. Is it that IE doesn't like map? Has anyone seen this before? I thought my code was correct. Works perfect in FF, chrome and opera. the canvas text doesn't work in opera, but it does render the features so the each function is working. I'll post the code if needed, but it's huge. here's the script running. http://www.pdxbusiness.com/canvas/golf/ The code below looks elementary, but it gives absurd results. Can you tell how I should have written it? I am slowly beginning to understand why it fails. But I do not understand why the JavaScript tutorials I've studied never warned against this trap. Any ship needs a list of crew members. The total number of persons onboard must be known too, for the case the ship sinks. We place these two properties in a prototype, so that we won't have to repeat them for each kind of ship. A passenger list is needed only if the ship is a passenger ship, so we decide not to place the passenger list in a prototype. Code: function Ship() { this.crew = []; this.persons = 0; } function PassengerShip(name) { this.name = name; this.passengers = []; } PassengerShip.prototype = new Ship; Passengers and crew arrive one by one shortly before departure. The first thing they do onboard is to check in: Code: Ship.prototype.checkin = function(list, person) { this[list].push(person); ++this.persons; } (Instead of the push function, we could as well have used a statement such as Code: this[list][ this[list].length ] = person; I have tried. Same wrong result.) Let us launch two passenger ships and check some persons in. Code: var msFloat = new PassengerShip("M/S Float"); msFloat.checkin("crew", "Captain"); msFloat.checkin("crew", "Cook"); msFloat.checkin("passengers", "Alice"); msFloat.checkin("passengers", "Bob"); var msFlawed = new PassengerShip("M/S Flawed"); msFlawed.checkin("crew", "Capt'n"); msFlawed.checkin("crew", "Sailor"); msFlawed.checkin("passengers", "Charlie"); The shipping company wants a report when everybody has checked in. But I'm not sure they will like it: Code: Ship.prototype.report = function() { function makeList(ship, list) { if (!ship[list]) return (ship.name + " has no list of " + list + ".\n"); if (!ship[list].length) return (ship.name + " has no " + list + ".\n"); return (list + ": " + ship[list].join(", ") + "\n"); } alert("\nPre-Departure Report For '" + this.name + "'\n\n" + makeList(this, "passengers") + makeList(this, "crew") + "\nNumber of persons onboard: " + this.persons + "\n\n"); } msFloat.report(); // OK: Alice, Bob as passengers; Captain, Cook as crew msFlawed.report(); // WRONG CREW: Captain, Cook, Capt'n, Sailor The number of persons (passengers + crew) is reported correctly for both ships, and so is the passenger list. But the "M/S Flawed" reports four crew members. Two of those never checked in on that ship. How can such a thing happen? What kind of blunder did I make? An "edit+execute" version of the code is available at bjarne.altervista.org/sailor.html together with a little testoutput, some considerations based on that testoutput, and a workaround (which is not the same as a solution - it looks ridiculous). It seems as if arrays placed in prototypes do not always work as expected. Can that be true? The testoutput suggests that JavaScript sometimes forgets to create a much-needed own property in the this object, and instead changes the prototype. But that sounds incredible, doesn't it? I am not too familiar with the deeper theory of JavaScript, and I hope to get a response. Here is the code concatenated and embedded: Code: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>Array In JavaScript Prototype</title></head> <body> <script type="text/javascript" language="JavaScript"> function Ship() { this.crew = []; this.persons = 0; } function PassengerShip(name) { this.name = name; this.passengers = []; } PassengerShip.prototype = new Ship; Ship.prototype.checkin = function(list, person) { this[list].push(person); ++this.persons; } Ship.prototype.report = function() { function makeList(ship, list) { if (!ship[list]) return (ship.name + " has no list of " + list + ".\n"); if (!ship[list].length) return (ship.name + " has no " + list + ".\n"); return (list + ": " + ship[list].join(", ") + "\n"); } alert("\nPre-Departure Report For '" + this.name + "'\n\n" + makeList(this, "passengers") + makeList(this, "crew") + "\nNumber of persons onboard: " + this.persons + "\n\n"); } var msFloat = new PassengerShip( "M/S Float" ); msFloat.checkin("crew", "Captain"); msFloat.checkin("crew", "Cook"); msFloat.checkin("passengers", "Alice"); msFloat.checkin("passengers", "Bob"); msFloat.report(); // OK: Alice, Bob as passengers; Captain, Cook as crew var msFlawed = new PassengerShip( "M/S Flawed" ); msFlawed.checkin("crew", "Capt'n"); msFlawed.checkin("crew", "Sailor"); msFlawed.checkin("passengers", "Charlie"); msFlawed.report(); // WRONG CREW: Captain, Cook, Capt'n, Sailor </script> </body> </html> I have spent much time struggling with this kind of error, which is reproducible in 5 different browsers. This is the first time I have been able to reproduce it in a form that can be presented to others. Is there a well-established programming practice that can prevent it? What do experienced JavaScript programmers do? Regards Bjarne Pagh Byrnak Hey All - I asked this a few days ago.. what I came up with works just fine, but I feel it doesn't take advantage of "classes". If you think I could make this better by turning it into a class or using some other notation, that would be great. Keep in mind, ALL this does is rewrite a pagination.... for a search return in a lightbox. I have this function called in the return function... Code: var srcpagParams = $H(); function buildPagi(param, currdsplyNum){ var temDsply = new Template('<strong>[#{total_display}<span id="count">#{prevImg} #{links} #{nextImg}</span>'), crnt_link = srcpagParams.set('crnt_link', param), // the page we want to see dsplyNum = srcpagParams.get('paginateNum'), // what is the number of returns per page ttl_lnks = Math.ceil( srcpagParams.get('numFound') / srcpagParams.get('paginateNum')), // total pages data_template = new Hash(); data_template.set('total_display',srcpagParams.get('numFound')); bldImg = function() { var prvB = '<a href="#content" id="pagiPrev" onclick="firesrc(this)">Prev<img src="blank.gif" /></a>'; var nxtB = '<a href="#content" id="pagiNext" onclick="firesrc(this)">Next<img src="blank.gif" /></a>'; data_template.set('prvImg',(crnt_link > 1) ? prvB : ""); data_template.set('nxtImg',(crnt_link < ttl_lnks) ? nxtB : ""); } bldLk = function(){ var holder = ""; if(ttl_lnks > 1){ var linkStr = new Template(' <a href="#content" onclick="firesrc(#{pos});"> Go to page #{pos}</a> '); $R(1,ttl_lnks).each(function(n) { var posit = {pos : n} holder += (crnt_link == n) ? " " + n + " " : linkStr.evaluate(posit); }); data_template.set('links',linkholder); } } bldRng = function(){ var currPaneRg = (dsplyNum * crnt_link) - (dsplyNum - currdsplyNum); data_template.set('range',((crnt_link - 1) * (dsplyNum) + 1 ) + " - " + currPaneRg); $('pages').update(temDsply.evaluate(data_template)).show(); } firesrc = function(cl){ var pagiPane = (typeof cl === "number") ? cl : (cl.id == "pagiNext") ? crnt_link + 1 : crnt_link - 1; var start = crnt_link * srcpagParams.get('paginateNum'); Alertsrc( $F('query') ,(pagiPane)) // pass the query to the json to return the current search request } bldImg(); buildLnk(); bldRng(); }; Since some of the data declared at the top changes depending on the return, I didn't know if I could "initialize" it in a class. But could I turn this into a class and if so - what I just use: var buildPagi = create.Class({ initialize: object.extend({ }) }) Call the function when we are passed some data: Code: buildPagi(somevalue, somevalue2) ** NOTE: I use the libraries prototype and jquery.. so use Create.Class and new Template are within the libraries... etc.. so, is there a more eloquent, or robust way to write what I did above? Hello, I'm trying to write my class with member properties and functions like below. What I want to learn is that is there any problem to use prototype object in the class that we want to use with it? I asked because I generally see that prototype object definition and member functions and properties created outside of the class unlike my class that I wrote like below. Is there any problem writing my class like below? Thanks. Code: function Point() { Point.prototype.x = this._x; Point.prototype.y = this._y; function _setX(x) { this.x = x; } Point.prototype.setX = _setX; function _setY(y) { this.y = y; } Point.prototype.setY = _setY; function _show() { alert(this.x + this.y); } Point.prototype.Show = _show; } function callMyClass() { var p = new Point(); p.setX(3); p.setY(5); p.Show(); } Hello all I have been trying in vain for many days to resolve a conflict between javascript libraries. I have read far and wide and still have failed to fix this problem, most likely because my programming skills are just about copy and pasting. My homepage uses jquery horizontal css menubar + a combined mootool and prototype accordian type sliding information box in the middle of the webpage. I find that the highlighter of the css menubar does not work when prototype.js is also loaded on the same page. I have read somewhere that $ should be replaced however I have tried every possible option and none works. I have jquery loading first as it is on my template, with this <script type='text/javascript' src='../Web/Templates/jquery-1.3.2.js'></script> <script type='text/javascript' src='js/example.js'></script> And my mootool and prototype loades further below like this <script type="text/javascript" src="scripts/intro/prototype.lite.js"></script> <script type="text/javascript" src="scripts/intro/moo.fx.js"></script> <script type="text/javascript" src="scripts/intro/moo.fx.pack.js"></script> <script type="text/javascript"> function init(){ var stretchers = document.getElementsByClassName('box'); var toggles = document.getElementsByClassName('tab'); var myAccordion = new fx.Accordion( toggles, stretchers, {opacity: false, height: true, duration: 600} ); //hash functions var found = false; toggles.each(function(h3, i){ var div = Element.find(h3, 'nextSibling'); if (window.location.href.indexOf(h3.title) > 0) { myAccordion.showThisHideOpen(div); found = true; } }); if (!found) myAccordion.showThisHideOpen(stretchers[0]); } </script> Could someone please offer me further assistance and enlighten me what other information you require to assist me further. I have attached the example.js inside example.zip file if someone could kindly edit it for myself. Looking forward to your assistance. Sincerely, Lex I'm still a beginner in js core so please forgive if the question is too fundamental. In the following example PositionedRectangle is a subclass of Rectangle, all 3 methods of prototype inheritance seem to produce the same results, method 1 is from the authors book (Flanagan's Definitive Guide 5ed) example 9-3, and method 2 is from his website example 9-3, and method 3 is my own; Code: // method 1 seems most complicated function heir(p) { function f(){}; f.prototype =p; return new f(); } PositionedRectangle.prototype = heir(Rectangle.prototype); //method 2 PositionedRectangle.prototype = new Rectangle(); //method 3 seems most straight forward (I don't know if it's correct but works ok) PositionedRectangle.prototype = Rectangle.prototype; Thank you Gents, J. I use this code to clone an object. At the end I test the properties: Code: //cloning codes function Clone(){} function clone(obj) { Clone.prototype = obj; return new Clone(); } // var Orange={natu 'fruit',color:'orange'} var Banana=clone(Orange); for(a in Banana){ alert(a) } So far so good. I see: nature - > color But now I want to change a property of the Banana object, the color, then test again the properties: Code: Banana.color='green'; for(a in Banana){ alert(a) } Surprisingly, the changed property becomes the first in the loop, which is curious. I see now: color - > nature Can anyone explain me why? I understand that the last new created property comes always first (which I don't like, but I take it as it is), but I suppose that, in the case above, the property was already defined, and I did nothing but changing its value. Is there a way to keep the order within the prototype? I am trying to use a javascript plugin for jQuery library that transforms a regular select html element into a dropdown checkbox list (Dropdown Check List, see http://code.google.com/p/dropdown-check-list/), however I believe that the prototype library that I am loading immediately after the jquery library is still conflicting with it somehow even though I modified my code to reflect the following changes (which is supposed to allow the use of prototype with jquery): http://docs.jquery.com/Using_jQuery_...ther_Libraries (Including jQuery before Other Libraries) My code (in a cold fusion environment, which should be irrelevant) looks like this: Code: <html> <head> <SCRIPT LANGUAGE="JavaScript" SRC="js/jQuery/jquery.js" TYPE="text/javascript"></SCRIPT> <SCRIPT LANGUAGE="JavaScript" SRC="js/prototype.js" TYPE="text/javascript"></SCRIPT> <script language="javascript" type="text/javascript" src="js/jQuery/ui.core.js"></script> <script language="javascript" type="text/javascript" src="js/jQuery/ui.dropdownchecklist.js"></script> <script language="javascript" type="text/javascript"> jQuery(document).ready(function() { jQuery("#cbo_status").dropdownchecklist({ width: 200, maxDropHeight: 120 }); }); </script> </head> <body> <select id="cbo_status" name="cbo_status" multiple="multiple"> <option value="-1">All</option> <option value="1" SELECTED>Assigned</option> <option value="2" SELECTED>In Progress</option> <option value="3" SELECTED>Complete</option> <option value="4" SELECTED>Verified Resolved</option> <option value="5" SELECTED>Will not be addressed</option> <option value="6" SELECTED>Wishlist</option> </select> </body> </html> When I run the debugger, here's the error I'm still receiving: Error: Object doesn't support this property or method (pointing to the line below, character 3) jQuery("#cbo_status").dropdownchecklist({ width: 200, maxDropHeight: 120 }); Does anyone have any idea why this might still be failing? The following code works find in firefox and chrome. In IE, it only works the first time I click on a link. Any ideas? Thanks in advance, // I have some div's where help is, which I make non-viewable <div id='help_guides'> <div id='issue1'>Help with issue 1</div> <div id='issue2'>Help with issue 2</div> </div> <a href="#" id="issue_1_link">Help with issue #1</a> <a href="#" id="issue_2_link">Help with issue #2</a> <div id='help'></div> // I grab the help guide div into a variable var issue_1_help = $('issue_1').remove(); var issue_2_help = $('issue_2').remove(); // When the help link is clicked, the help DIV displays the help guide Event.observe( $('issue_1_link'), 'click', function() { $('help').update( issue_1_help ); }); Event.observe( $('issue_2_link'), 'click', function() { $('help').update( issue_2_help ); }); I'm pretty new to Javascript and just started with some OOP concepts, so this might be an obvious one and I apologize if the question is much longer than it should be... Basically I am trying to create a reusable class object with several internal functions, that is completely abstracted, meaning the class object itself should never have to reference the global declarations or window object. This class should be aware of itself at any point in the execution of it's own functions, and that is what I'm having trouble with at the moment. What I'm trying to do is create reusable javascript "Apps" for my HTML web application, where multiple instances can be instantiated and used independently from one another. My main problem is "this" loses context in the Ajax callback and onclick handlers. I'm not sure how to persist the context of "this", or at least keep a reference to prototype instance itself. Let's set up a simple class called "App" to demonstrate what I mean... Code: var myApp = new App("MyFirstApp"); function App(argName) { this.name = argName; this.GetDirectory("C:\Program Files"); } App.prototype.GetDirectory = function(argPath) { // "this" equals the App object instance (good!), meaning this.name should equal "MyFirstApp" Ajax.GetDirectory(argPath, this.GetDirectoryCallback, this.GetDirectoryTimeout, this.GetDirectoryError); } App.prototype.GetDirectoryCallback = function(argFilePaths) { // "this" equals the "window" object (bad!), meaning this.name should equal a null reference // argFilePaths contains a string of file paths (delimited using ;) returned by the server var mFilePaths = split(argFilePaths, ";"); // for each file path, add a div to the document body containing that file path, with an onclick handler for (var i in mFilePaths) { var mFilePath = mFilePaths[i]; var mFilePathDiv = document.createElement("div"); mFilePathDiv.innerHTML = mFilePath; mFilePathDiv.setAttribute("onclick", "javascript:this.FilePathDivClickHandler();return false;"); document.getElementById("body").appendChild(mFilePathDiv); } } App.prototype.FilePathDivClickHandler = function() { // I need a reference to the App object instance here, but I'm not sure where to grab it... // what I want to do is call GetDirectory again, referencing the div's innerHTML which contains another file path, like this: this.GetDirectory(event.target.innerHTML); } The onclick handler using "this" is obviously not going to work because "this" is a reference to the "window" object which does not have a function called FilePathDivClickHandler(). So what I can do is nest the GetDirectoryCallback() function inside the GetDirectory() function so that GetDirectoryCallback() can reference the variables in the outer function (GetDirectory). Code: App.prototype.GetDirectory = function(argPath) { // "this" equals the App object instance (good!), meaning this.name should equal "MyFirstApp" // "this" will still lose context inside the callback, so we can set up a variable called "instance" that the callback can reference var instance = this; Ajax.GetDirectory(argPath, GetDirectoryCallback, GetDirectoryTimeout, GetDirectoryError); function GetDirectoryCallback(argFilePaths) { // "this" equals the window object (bad!), meaning this.name should equal a null reference // "instance" equals the App object instance (good!), meaning instance.name should equal "MyFirstApp" // argFilePaths contains a string of file paths (delimited using ;) returned by the server var mFilePaths = split(argFilePaths, ";"); // for each file path, add a div to the document body containing that file path, with an onclick handler for (var i in mFilePaths) { var mFilePath = mFilePaths[i]; var mFilePathDiv = document.createElement("div"); mFilePathDiv.innerHTML = mFilePath; mFilePathDiv.setAttribute("onclick", "javascript:instance.FilePathDivClickHandler();return false;"); document.getElementById("body").appendChild(mFilePathDiv); } } } Even though we have persisted the App object instance through the use of the "instance" variable in the outer function, the onclick event handler still does not work; when it fires, "instance" is an unknown object. Would placing the FilePathDivClickHandler() function inside the GetDirectory() function, much like what was done with the callback, allow me to use "instance" correctly for the onclick handler? uncaught exception: Syntax error, unrecognized expression:
Code: :([rel*=qnt_Rc]) I have this code: Code: grpDiv = $$('div:([rel*=' + txt_val + '])'); Which when operaterated on, we have: Code: grpDiv = $$('div:([rel*=qnt_Rc]) This error: uncaught exception: Syntax error, unrecognized expression: Code: :([rel*=qnt_Rc]) Is new. The code in question has been around for about a year and no issues with prototype 1.6.1. Yet we upgraded to 1.7, and this error started showing. any ideas what this could be and how to fix it? thanks |