Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 339
Vitalii Avatar asked Dec 26 '14 16:12

Vitalii


4 Answers

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',
  ...
]
...
like image 74
abd3721 Avatar answered Nov 06 '22 05:11

abd3721


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;
  };
}
like image 2
Rakesh Yembaram Avatar answered Nov 06 '22 05:11

Rakesh Yembaram


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.

like image 1
Jan Kjærgaard Avatar answered Nov 06 '22 06:11

Jan Kjærgaard


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);
  };
};
like image 1
isnvi23h4 Avatar answered Nov 06 '22 05:11

isnvi23h4