Vitalii
Vitalii

Reputation: 1175

Phantomjs Function.prototype.bind

Yes, I know that. Function bind is not supported by Phantomjs. But maybe I can use something else, or say page.open not to use bind? It seems to be OK, but some websites return error

TypeError: 'undefined' is not a function (evaluating 'b.bind(a)')

After that I wrote a simple script, which just opens a page:

var address = phantom.args[0];
if(!address) phantom.exit(1);

page = require("webpage").create();

page.open(address, function(status){
setInterval(
   function () {

   console.log(
       page.evaluate(function() {
            return document.body.innerHTML.length;
       })
   )}, 200)
})

But error is still there. Error is not the main problem, but the problem is to get page content, because after error page content is not loading...

So, I need help.

P.S. Problem website is http://vkrushelnytskiy.wix.com/aaaa

Upvotes: 6

Views: 4538

Answers (4)

abd3721
abd3721

Reputation: 1514

There is an npm package which loads a polyfill for phantomJS's missing .bind method. Copying the installation instructions here for convenience, but follow the link for any updates.

Installation

npm install --save-dev phantomjs-polyfill

Usage

require('phantomjs-polyfill')

Usage with Karma Include the polyfill directly in the files list of your karma.conf

...
files: [
  './node_modules/phantomjs-polyfill/bind-polyfill.js',
  ...
]
...

Upvotes: 7

souparno majumder
souparno majumder

Reputation: 2052

You can mention this bind function just before the test case.

// PhantomJS doesn't support bind yet
Function.prototype.bind = Function.prototype.bind ||
  function (ctx) {
    var fn = this,
      args = [],
      param_length = 0;

  for(var i=0; i<arguments.length; i++) {    
    if(i){
      args[i-1] = arguments[i];
    }
  }
  param_length = args.length;
  return function () {
    for(var i =0; i<arguments.length; i++){
      args[param_length + i] = arguments[i];
    }
    return fn.apply(ctx, args);
  };
};

Upvotes: 1

Rakesh Yembaram
Rakesh Yembaram

Reputation: 433

You can use this code as an alternative

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

Upvotes: 2

Jan Kj&#230;rgaard
Jan Kj&#230;rgaard

Reputation: 31

You can shim Function.bind using the following polyfill.

Just prepend it to the code you are trying to run. There are probably nicer solutions, but this worked great for me.

Upvotes: 1

Related Questions