2015-02-12 2 views
1

Я использую PhantomJS v2.0 и CasperJS 1.1.0-beta3. Я хочу запросить определенную часть внутри страницы DOM.Различия при использовании функций для casper.evaluate

Вот код, который не работает:

function myfunc() 
{ 
    return document.querySelector('span[style="color:#50aa50;"]').innerText;  
} 
var del=this.evaluate(myfunc()); 

this.echo("value: " + del); 

А вот код, который сделал работу:

var del=this.evaluate(function() 
{ 
    return document.querySelector('span[style="color:#50aa50;"]').innerText; 
}); 

this.echo("value: " + del); 

Вроде бы то же самое, но это работает разные, я не Понимаю.

А вот код, который сделал также работать:

function myfunc() 
{ 
    return document.querySelector('span[style="color:#50aa50;"]').innerText;  
} 
var del=this.evaluate(myfunc); 

this.echo("value: " + del); 

Разница здесь, я называю MyFunc без '()'.

Может ли кто-нибудь объяснить причину?

ответ

0

Проблема заключается в следующем:

var text = this.evaluate(myfunc()); 

Функции в JavaScript являются первым гражданином класса. Вы можете передать их другим функциям. Но это не то, что вы здесь делаете. Вы вызываете функцию и передаете результат в оценку, но результат не является функцией.

Также casper.evaluate() - это контекст страницы, и только контекст страницы имеет доступ к документу. Когда вы вызываете функцию (с ()) по существу до, исполняя casper.evaluate(), вы ошибочно пытаетесь получить доступ к документу, когда это невозможно.

Разница в casper.evaluate(function(){...}); заключается в том, что анонимная функция определена и передана в функцию evaluate().

Бывают случаи, когда функция должна вызываться вместо переданной. Например, когда выполняется каррирование, но это не относится к casper.evaluate(), поскольку оно изолировано, а функция, которая, наконец, выполняется в casper.evaluate(), не может использовать переменные извне. Он должен быть самодостаточным. Таким образом, следующий код будет также не работает:

function myFunc2(a){ 
    return function(){ 
     // a is from outer scope so it will be inaccessible in `evaluate` 
     return a; 
    }; 
} 
casper.echo(casper.evaluate(myFunc2("asd"))); // null 

Вы должны использовать

var text = this.evaluate(myfunc); 

передать ранее определенную функцию для запуска в контексте страницы.

Это также не рекомендуется использовать зарезервированные ключевые слова, такие как del как имена переменных.

+0

Ах спасибо за хорошее объяснение. Это означает, что когда я пишу 'myfunc' без'() ', тогда функция не будет вызываться до того, как будет вызван метод. Вместо этого 'myfunc' будет обрабатываться как переменная и будет передан в качестве аргумента функции оценки. С эффектом «myfunc» будет вызван после того, как будет вызвана оценка? Правильно ? –

+0

'оценка' * использует * переданную функцию, поэтому вы не можете сказать, что функция выполняется после завершения оценки. Если вы хотите знать, как он его использует, вы можете изучить исходный код PhantomJS. Аргумент 'оценка' не используется как обратный вызов, когда выполнение завершено. Это функция, чтобы оценить, что делать. –

Смежные вопросы