English 中文(简体)
Why doesn t the shim for watch() and unwatch() at https://gist.github.com/384583 work in phantomjs?
原标题:

I m doing some server-side javascript bits and pieces that essentially need both access to websites full DOMs and the ability to open sites cross-domain, and at least so far, PhantomJS seems the best tool for the job.

However, it lacks an Object.watch() method, which I d rather like to have. As such, I m trying to use the shim posted as an answer elsewhere on Stackoverflow (available here: https://gist.github.com/384583) to give me access to just such methods.

It isn t working.

It s also well beyond my level of JavaScript understanding - so I m wondering if anyone could help me understand both exactly what it s doing, and why it might not be working?

Thanks for the help,

Toby

(Code quoted below:

// Cross-browser object.watch and object.unwatch

// object.watch
if (!Object.prototype.watch) {
    Object.prototype.watch = function (prop, handler) {
        var oldval = this[prop], newval = oldval,
        getter = function () {
            return newval;
        },
        setter = function (val) {
            oldval = newval;
            return newval = handler.call(this, prop, oldval, val);
        };
        if (delete this[prop]) { // can t watch constants
            if (Object.defineProperty) { // ECMAScript 5
                Object.defineProperty(this, prop, {
                    get: getter,
                    set: setter,
                    enumerable: true,
                    configurable: true
                });
            } else if (Object.prototype.__defineGetter__ &&     Object.prototype.__defineSetter__) { // legacy
                Object.prototype.__defineGetter__.call(this, prop, getter);
                Object.prototype.__defineSetter__.call(this, prop, setter);
            }
        }
    };
}

// object.unwatch
if (!Object.prototype.unwatch) {
    Object.prototype.unwatch = function (prop) {
        var val = this[prop];
        delete this[prop]; // remove accessors
        this[prop] = val;
    };
}

And my test code:

tO = {
    "v":0,
    "vplus":function(){this.v ++}
};
tO.watch("v", function(prop, oldval, newval) {
    console.log("The property "+prop+" is now "+tO.v+". Newval is "+newval+" and oldval     "+oldval+".");
    if (newval == 5){phantom.exit()};
});
tO.v = 1;
var i = 0
for(i=0; i<10; i++) {
    tO.v = i; 
    console.log(tO.v);
    if(tO.v == 9){
        console.log("got to 9");
    };
};
最佳回答

To answer my own question: the provided shim seems to put a broken setter function in place. In particular, unless the handler function returns something meaningful (which it may well not), the property gets set to undefined. Replacing

return newval = handler.call(this, prop, oldval, val);

with

var newval = handler.call(this, prop, oldval, val) || val;
return newval;

seemed to do the job.

As a side note, this particular shim is ingenious but includes a couple of limitations:

  • Code relying on a watched value may take a while to work, so it s good to change watched values after critical operations if using them as flags.

  • You can t add multiple handlers to a value.

问题回答

暂无回答




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签