เหตุใด google.load จึงทำให้หน้าของฉันว่างเปล่า


103

มันดูแปลก ๆ แต่ฉันหาทางแก้ไขไม่ได้

ทำไมซอนี้ในโลกนี้http://jsfiddle.net/carlesso/PKkFf/แสดงเนื้อหาของเพจแล้วเมื่อเกิด google.load หน้าจะว่างเปล่า?

ใช้งานได้ดีถ้า google.load เสร็จสิ้นทันที แต่การล่าช้าไม่ได้ผลเลย

นี่คือแหล่งที่มาของหน้าสำหรับคนขี้เกียจ (หรือฉลาดกว่า) ของคุณ:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Ciao</title>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
  </head>
  <body>
    <h1>Test</h1>
    <div id="quicivanno">
      <p>ciao</p>
    </div>
  </body>
  <script type="text/javascript">
       setTimeout(function() {google.load('visualization', '1.0', {'packages':['corechart']});}, 2000);
  </script>
</html>​

1
คำถามที่ดีนี่คือลิงค์: friendlybit.com/js/lazy-loading-asyncronous-javascript (หรืออีกนัยหนึ่ง: ยังไม่มีเงื่อนงำ)
mindandmedia

ฉันสังเกตว่า document.write ('อะไรก็ได้') จะล้าง html ก่อนหน้าด้วยเช่นกันบางทีเอกสารอาจไม่ทำงานในบริบทของ settimeout?
mindandmedia

คำตอบ:


109

ดูเหมือนว่า google.load กำลังเพิ่มสคริปต์ลงในเพจโดยใช้ document.write () ซึ่งหากใช้หลังจากโหลดเพจแล้วให้ล้าง html ออก

ข้อมูลนี้จะอธิบายเชิงลึกเพิ่มเติม: http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/e07c2606498094e6

ใช้แนวคิดอย่างใดอย่างหนึ่งคุณสามารถใช้การเรียกกลับสำหรับการโหลดเพื่อบังคับให้ใช้การผนวกแทน doc.write:

setTimeout(function(){google.load('visualization', '1', {'callback':'alert("2 sec wait")', 'packages':['corechart']})}, 2000);

นี่แสดงให้เห็นถึงการรอ 2 วินาทีพร้อมกับหน้าต่างแจ้งเตือนล่าช้า


ฉันไม่ต้องการให้แสดงหน้าต่างแจ้งเตือนมีงานที่ต้องทำหรือไม่?
Shoib Mohammed A

4
การแจ้งเตือนเป็นเพียงตัวอย่างโค้ด มันสามารถเป็นอะไรก็ได้
คลื่น

นี่มันเยี่ยมมาก สิ่งเดียวที่ฉันเปลี่ยนให้ทำงานได้ตามที่คาดไว้คือเรียกใช้ฟังก์ชัน drawChart แทนฟังก์ชันแจ้งเตือน
chiurox

เพียงแค่เพิ่มพารามิเตอร์การโทรกลับที่ว่างเปล่าก็แก้ไขให้ฉัน
Adam B

32

คุณต้องกำหนดการโทรกลับและจะไม่ล้างหน้า (อาจเป็นรุ่นเก่าของ google.load () แต่ดูเหมือนว่าเวอร์ชันใหม่จะไม่ใช้กับการโทรกลับ) นี่คือตัวอย่างที่ง่ายขึ้นเมื่อฉันกำลังโหลด lib "google.charts":

if(google) {
    google.load('visualization', '1.0', {
        packages: ['corechart'],
        callback: function() {
            // do stuff, if you wan't - it doesn't matter, because the page isn't blank!
        }
    } )
}

เมื่อทำการโทรกลับเล็กน้อย () ฉันยังคงได้รับหน้าว่างด้วย - แต่ด้วยการโทรกลับมันได้รับการแก้ไขสำหรับฉัน


5

หมายเหตุ: สิ่งต่อไปนี้เป็นสิ่งที่ดีในการหลีกเลี่ยงการหน่วงเวลา - ทันเวลา ตัวอย่างสามารถใช้ได้โดยสคริปต์ทั้งหมด (จำเป็นต้องใช้) แต่ใช้กับ Greasemonkey เป็นพิเศษ นอกจากนี้ยังใช้ Google chart API เป็นตัวอย่าง แต่โซลูชันนี้ไปไกลกว่า Google APIs อื่น ๆ และสามารถใช้ได้ทุกที่ที่คุณต้องรอให้สคริปต์โหลด

การใช้ google.load กับการโทรกลับไม่สามารถแก้ปัญหาได้เมื่อใช้ Greasemonkey เพื่อเพิ่มแผนภูมิ Google ในกระบวนการ (แทรก Greasemonkey ลงในหน้า) โหนดสคริปต์ www.google.com/jsapi จะถูกเพิ่ม หลังจากเพิ่มองค์ประกอบนี้สำหรับ jsapi javascript ของ Google สคริปต์ที่แทรก (หรือเพจ) พร้อมที่จะใช้คำสั่ง google.load (ซึ่งจำเป็นต้องโหลดในโหนดที่เพิ่ม) แต่สคริปต์ jsapi นี้ยังไม่โหลด การตั้งค่าการหมดเวลาใช้งานได้ แต่การหมดเวลาเป็นเพียงวิธีแก้ปัญหาสำหรับการแข่งขันเวลาในการโหลดสคริปต์ jsapi ของ Google ด้วยสคริปต์แทรก / เพจ การย้ายไปรอบ ๆ ที่สคริปต์เรียกใช้งาน google.load (และอาจเป็น google.setOnLoadCallback) อาจส่งผลต่อสถานการณ์การแข่งขันเวลา ต่อไปนี้เป็นโซลูชันที่รอให้องค์ประกอบสคริปต์ของ Google โหลดก่อนที่จะเรียกใช้ google.load นี่คือตัวอย่าง:

// ********* INJECTED SCRIPT *********//
// add element
var gscript = document.createElement('script');
gscript.setAttribute("type", "application/javascript");
gscript.setAttribute("id", "XX-GMPlusGoogle-XX");
document.body.appendChild(gscript);

// event listener setup     
gscript.addEventListener("load",    
    function changeCB(params) {
        gscript.removeEventListener("load", changeCB);
        google.load("visualization", "1", {packages:["corechart"], "callback": 
            function drawChart() {
                var data;
                // set the durationChart data (not in example)
                data = new google.visualization.arrayToDataTable(durationChart);

                var options = {
                    title:"Chart Title",
                    legend: {position:"none"},
                    backgroundColor:"white",
                    colors:["white","Blue"],
                    width: window.innerWidth || document.body.clientWidth,
                    height: window.innerHeight || document.body.clientHeight,
                    vAxis: {title: "Durations", baselineColor: "black", textStyle:{fontSize:12}},
                    hAxis: {title: "Days Since First Instance"},
                    height: ((cnt > 5)? cnt * 50 : 300),
                    isStacked: true
                }; // options


                // put chart into your div element
                var chart = new google.visualization.BarChart(document.getElementById('XX-ChartDiv-XX'));
                chart.draw(data, options);
            } // drawChart function
        }); //packages within google.load & google load
    } // callback changeCB
);

// can use SSL as "https://www.google.com/jsapi";
gscript.src = "http://www.google.com/jsapi";

2

คุณไม่จำเป็นต้องตั้งค่าระยะหมดเวลา มีอีกวิธีหนึ่ง:

$.getScript("https://www.google.com/jsapi", function () {
     google.load('visualization', '1', { 'callback': 'alert()', 'packages': ['corechart'] });
});

คำอธิบาย:

 function () {
     google.load('visualization', '1', { 'callback': 'alert()', 'packages': ['corechart'] });
 }

จะดำเนินการหลังจากโหลดสคริปต์ JSAPI สำเร็จจากนั้น alert () จะดำเนินการหลังจาก google.load () สำเร็จ


2

ฉันพบปัญหานี้เมื่อพยายามย้ายgoogle.load(…)ภายใน jQuery $(document).ready(…)wrapper การย้ายgoogle.load(…) ด้านหลังออกนอกฟังก์ชันที่พร้อมใช้งานเพื่อดำเนินการแก้ไขปัญหาได้ทันที

ตัวอย่างเช่นไม่ได้ผล:

$(document).ready(function() {
    google.load('visualization', '1', {packages: ['corechart']});
});

แต่สิ่งนี้ทำ:

google.load('visualization', '1', {packages: ['corechart']});
$(document).ready(function() {
    // …
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.