Как загрузить JS API Google для пользовательской поисковой системы (CSE) после загрузки страницы? - PullRequest
3 голосов
/ 08 августа 2011

Я использую систему пользовательского поиска Google с новой функцией автозаполнения.Я хочу, чтобы весь этот JavaScript загружался ПОСЛЕ самой страницы.Оригинальный код Google выглядит следующим образом:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
  google.load('search', '1');
  google.setOnLoadCallback(function() {
    google.search.CustomSearchControl.attachAutoCompletion(
      'some-long-unique-id',
      document.getElementById('q'),
      'cse-search-box');
  });
</script>
<script type="text/javascript" src="http://www.google.com/cse/brand?form=cse-search-box&lang=cs"></script>

Я преобразовал этот код с помощью учебника о динамической загрузке JS в этот код:

(function() {
  var goog = document.createElement('script'); goog.type = 'text/javascript';
  goog.src = 'http://www.google.com/jsapi';
  var cse = document.createElement('script'); cse.type = 'text/javascript';
  cse.src = 'http://www.google.com/cse/brand?form=cse-search-box&lang=cs';
  goog.onload = function() {
    google.load('search', '1');
    google.setOnLoadCallback(function() {
      google.search.CustomSearchControl.attachAutoCompletion(
        'some-long-unique-id',
        document.getElementById('q'),
        'cse-search-box');
    });
  };
  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(cse, s);
  s.parentNode.insertBefore(goog, s);
})();

Хорошо, хотяЯ думаю, что мое решение должно работать (так же, как Google изменил свой асинхронный код Google Analytics по требованию), это не так.Страница загружается нормально, и как только CSE загружается, страница становится пустой.Что-то очищает DOM, я полагаю, что-то вроде "Google вещь"?Может кто-нибудь пролить свет на эту проблему и, возможно, на рабочее решение?

Спасибо

Ответы [ 3 ]

11 голосов
/ 10 августа 2011

ОК, поэтому, проверив Руководство разработчика Google Loader , и путем множества попыток и испытаний я понял, как изменить свой код, чтобы он работал так, как я ожидал в своем вопросе:

(function() {
  var goog = document.createElement('script'); goog.type = 'text/javascript';
  goog.src = 'http://www.google.com/jsapi';
  goog.onload = function() {
    google.load('search', '1', {"callback": function() {}});
    google.setOnLoadCallback(function() {
      google.search.CustomSearchControl.attachAutoCompletion(
        'some-long-unique-id',
        document.getElementById('q'),
        'cse-search-box');
    });
  };
  var cse = document.createElement('script'); cse.type = 'text/javascript';
  cse.src = 'http://www.google.com/cse/brand?form=cse-search-box&lang=cs';
  var s = document.getElementsByTagName('script')[0]; 
  s.parentNode.insertBefore(cse, s);
  s.parentNode.insertBefore(goog, s);    
})()

Главное - эта строка:

google.load('search', '1', {"callback": function() {}});

Если вы не укажете обратный вызов (по крайней мере, пустую функцию, как я), тогда вся страница станет пустой, когда Google CSE загрузится.Я понятия не имею, почему, но теперь он работает нормально с этой фиктивной функцией обратного вызова.

Надеюсь, это поможет кому-то с такой же проблемой.

0 голосов
/ 17 августа 2011

Я не совсем понимаю, чего вы пытаетесь достичь. Вы попросили кого-нибудь предложить, как «исправить» ваш код, но вы не указали никакого контекста или того, что вы действительно хотите, чтобы конечный результат был.

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

Во-первых, я бы предложил использовать jQuery для обертывания JavaScript. Да, Google предоставляет события загрузки и другие помощники для их API, но jQuery будет применяться к любому Javscript, нет смысла использовать две инфраструктуры Javascript, где вам это не нужно.

JQuery может быть таким:

<script type="text/javascript" language="javascript" src="/js/jquery/jquery-1.4.2.min.js"></script>
<script type="text/javascript" language="javascript">
    // Use the jQuery document load functionality.
    $(document).ready(function ()
    {
        // Load the Google API asynchronously.  The callback 'GoogleApiLoaded' will be called when the script is fully-loaded.
        $.getScript("http://www.google.com/jsapi?key=yourkey", GoogleApiLoaded);    
        // Load other scripts, do other init code here (non-Google-dependent).
    });

    function GoogleApiLoaded()
    {
        // Google-related init here.
        // Load the custom search API.
        // (Could make the callback an in-line function).
        $.getScript("http://www.google.com/cse/brand?form=cse-search-box&lang=cs", CustomSearchApiLoaded);
    }

    function CustomSearchApiLoaded()
    {
        google.load('search', '1', LoadCustomSearchControl);
    }

    function LoadCustomSearchControl()
    {
        google.search.CustomSearchControl.attachAutoCompletion('some-long-unique-id', document.getElementById('q'), 'cse-search-box');
    }
</script>

Возможно, было бы полезно разбить код на различные функции, чтобы легче было найти причину проблемы. То, что вы должны добавить необязательный обратный вызов для функции 'google.load ()', странно - это может быть ошибка в коде Google, некоторые всплывают.

Я использовал google.load('search', '1', LoadCustomSearchControl), а не google.setOnLoadCallback, потому что, насколько я понимаю, они должны делать то же самое, и использование обратного вызова на load(), на мой взгляд, более удобно.

Я бы настоятельно рекомендовал вам использовать jQuery (или любой JavaScript-фреймворк), поскольку это значительно облегчает жизнь.

Мне было бы интересно посмотреть, работает ли то, что я предложил, и если нет, то где оно идет не так. (Обязательно добавьте свой собственный ключ JSAPI).

0 голосов
/ 10 августа 2011

Полагаю, вы можете использовать загрузчик js (например, yepnope ), который позволяет загружать js по требованию и добавлять обратный вызов.

...