2013-03-08 19 views
9

Sitemizin SEO'su için sunucu tarafında nodejs ve phantomjs kullanmaya çalışıyorum. Ajax iyi çalışıyor olsa da, kodumda kullandığım özel sözleri yürütemiyorum. Sözler çözülene kadar phantomJS'yi nasıl beklerim? Aşağıda kodladığım şey var.phantomJS'de jQuery vaatlerini nasıl uygularım?

$('body').addClass('before-dom-ready'); 

$(function() { 
    $('body').addClass('after-dom-ready'); 

    var dfrd = $.Deferred(), 
      promise = dfrd.promise(); 

    setTimeout(function() { 
     dfrd.resolve(); 
    }, 5000); 

    promise.done(function() { 
     $('body').addClass('promise-executed'); 
    }); 

}); 

phantomJS 'önce-dom-hazır' ve sınıf '-dom hazır sonra' ama vücut üzerinde 'söz-infaz' sınıfı alamıyor ekler.

+0

Tam phantomJS komut dosyanızı (ayrıca bağlı olduğu diğer dosyaların tam kodunun yanı sıra) görmeniz mümkün mü? Yani Böylece sorunu kolayca yeniden üretebiliriz. –

+0

Hangi noktada, ve ne zaman, 'vadeden-idam' sınıfının eklenip eklenmediğini kontrol ediyor musunuz? Ne tür bir hata ayıklama işlemi yaptınız, örneğin, dfrd.resolve() 'den sonra bir' console.log' çağrısını yerleştirmeyi denediniz mi? Bu kodu normal bir tarayıcıda denediniz mi, başka bir deyişle, bir PhantomJS problemi olduğunu düşündüren nedir? –

cevap

4

PhantomJs, bekleyen tüm komut dosyalarının sonunu otomatik olarak beklemez. Webload # onLoadFinished, onload olayında çağrılır.

Komut dosyalarının çoğuna gelince, burada "bir şey" yapılıncaya kadar beklemek doğrudur. waitfor.js'u sınamanızı öneririm. Bu örneği PhantomJs'de anlamak gerçekten önemlidir.

Örneğinizin bir örnek olduğunu varsayalım, ama bir cevap önereyim. Vücut 'promise-executed' adında bir sınıf varsa

Html

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script> 
    <title>Test</title> 
</head> 
<body id="body"> 

    <script type="text/javascript"> 
     //alert('hello'); 
     $('body').addClass('before-dom-ready'); 

     $(function() { 
      $('body').addClass('after-dom-ready'); 

      var dfrd = $.Deferred(), 
        promise = dfrd.promise(); 

      setTimeout(function() { 
       dfrd.resolve(); 
      }, 5000); 

      promise.done(function() { 
       $('body').addClass('promise-executed'); 
       $('body').text('Hello World !'); 
      }); 

     }); 
    </script> 
</body> 
</html> 

PhantomJs Senaryo

var page = require('webpage').create(); 
var system = require('system'); 

function waitFor(testFx, onReady, timeOutMillis) { 
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10000, //< Default Max Timout is 10s 
     start = new Date().getTime(), 
     condition = false, 
     interval = setInterval(function() { 
      if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { 
       // If not time-out yet and condition not yet fulfilled 
       condition = (typeof (testFx) === "string" ? eval(testFx) : testFx()); //< defensive code 
      } else { 
       if (!condition) { 
        // If condition still not fulfilled (timeout but condition is 'false') 
        //console.log("'waitFor()' timeout"); 
        typeof (onReady) === "string" ? eval(onReady) : onReady(); 
        clearInterval(interval); 
        //phantom.exit(1); 
       } else { 
        // Condition fulfilled (timeout and/or condition is 'true') 
        console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); 
        typeof (onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled 
        clearInterval(interval); //< Stop this interval 
       } 
      } 
     }, 500); //< repeat check every 500ms 
}; 

if (system.args.length != 1) { 
    console.log('invalid call'); 
    phantom.exit(1); 
} else { 
    //adapt url to your context 
    page.open('http://localhost:9231/demo.html', function (status) { 
     if (status !== 'success') { 
      console.log('Unable to load the address!'); 
      phantom.exit(); 
     } else { 
      waitFor(
       function() { 
        return page.evaluate(function() { 
         return $('body').hasClass('promise-executed'); 
        }) > 0; 
       }, 
       function() { 
        page.render('page.png'); 
        phantom.exit(); 
       }, 10000); 
     } 
    }); 
} 

Temelde, waitFor her 500 ms kontrol edecektir.

+0

Ayrıntılı yanıt için teşekkürler .. Testlerime dahil edilmeden önce biraz daha fazla okuma yapmam gerekecek, ama bu makul ve iyi belgelenmiş görünüyor .. –

+0

evet, bu benim için çalışıyor. Umarım bu da size yardımcı olur. – Cybermaxs

İlgili konular