Nano Hash - криптовалюты, майнинг, программирование

Использование пользовательского интерфейса jQuery в букмарклете

В CoffeeScript этот код почти идентичен JavaScript:

tabs_html = "<div id='nm-container'><ul><li><a href='#tabs-1'>Guidelines</a></li><li><a href='#tabs-2'>Test</a></li></ul>
            <div id='tabs-1'><p>something1</p></div><div id='tabs-2'><p>something2</p></div></div>"
$("#nm-toolbar").append(tabs_html)
$("#nm-container").tabs()

Это не работает. Забавно то, что это работает при попытке последней строки: $("#nm-container").tabs() из консоли. Я прилагаю полный код ниже. Обратите внимание, что я использую CoffeeMarklet для создания букмарклета, который работает только в Chrome.

s1 = window.document.createElement('script')
s1.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js'
window.document.body.appendChild(s1)

$ ->

    s2 = window.document.createElement('script')
    s2.src = 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js'
    window.document.body.appendChild(s2)

    jqueryUIcss = window.document.createElement('link')
    jqueryUIcss.rel = 'stylesheet'
    jqueryUIcss.type = 'text/css'
    jqueryUIcss.href = 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/blitzer/jquery-ui.css'
    window.document.head.appendChild(jqueryUIcss)

    if $("#nm-toolbar").length == 0
        toolbar = "<div id='nm-toolbar'></div>"
        $("body").append(toolbar)
        $("#nm-toolbar").css({
            'background':               '#fafafa',
            'height':                   '500px',
            'width':                    '400px',
            'position':                 'fixed',
            'bottom':                   '0px',
            'right':                    '20px',
            'padding':                  '5px'
        })

        tabs_html = "<div id='nm-container'><ul><li><a href='#tabs-1'>Guidelines</a></li><li><a href='#tabs-2'>Test</a></li></ul>
            <div id='tabs-1'><p>something1</p></div><div id='tabs-2'><p>something2</p></div></div>"
        $("#nm-toolbar").append(tabs_html)
        $("#nm-container").tabs()

  • Похоже, что инструмент CoffeeMarklet использует решение для загрузки jQuery Бена Алмана, которое можно увидеть в несжатом виде здесь: benalman.com/code/javascript/jquery/ 01.07.2011
  • Это странно. Когда я использую только автоматическое добавление jQuery, он не работает, а когда я использую свой собственный код, он все еще не работает, но вместе он загружает jquery. странный. 01.07.2011
  • Я думаю, вам нужно изменить код Бена Алмана, чтобы пользовательский интерфейс jQuery загружался перед выполнением .noConflict. 01.07.2011

Ответы:


1

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

window.document.body.appendChild(s2)

начинает загрузку пользовательского интерфейса jQuery, но ваш код продолжает работу до того, как пользовательский интерфейс jQuery обязательно будет загружен. Это объясняет, почему вызов tabs() в вашем коде завершается неудачно, но успешно выполняется, когда вы выполняете его из консоли, после того как скрипт успел загрузиться.

Вы должны быть в состоянии исправить это, запустив остальную часть кода из обратного вызова.

s2.onreadystatechange = ->
  return unless @readyState is 'complete'
  # the rest of the code goes here

Редактировать: И если на то пошло, вы действительно должны сделать то же самое с s1, иначе вызов $ -> может завершиться ошибкой. Тот факт, что это удается, предполагает, что либо у вас есть кешированный jQuery в вашем браузере, либо на странице уже есть jQuery. Вы также должны использовать noConflict, чтобы избежать перезаписи существующей версии jQuery страницы. букмарклет Run jQuery Code, на который ссылается Acorn делает все это (и более кроссбраузерно, чем код в этом ответе).

30.06.2011
  • Я не понимаю, зачем нужна вторая строка. (и до сих пор не работает). 01.07.2011
  • @Radagaisus Хм. Если вы добавите console.log @readyState вверху обратного вызова onreadystatechange, что вы увидите в консоли? 01.07.2011
  • Я попробовал это сам, и кажется, что проблема заключается в том, что jQuery загружается внутри анонимной функции, и поэтому при загрузке jQueryUI не может ее найти. Есть ли способ заставить пользовательский интерфейс jQuery выполнять свою работу с определенной переменной, содержащей jQuery? 01.07.2011
  • Любые комментарии по стилю моего решения @Trevor? Я не так давно использую CoffeeScript, было бы здорово узнать, нужно ли что-то делать по-другому. 01.07.2011

  • 2

    Это должно работать:

    ((window, document, requirements, callback) ->
        getScript = (url, callback) ->
            script = document.createElement('script')
            script.src = url
            head = document.documentElement.childNodes[0]
            done = false
            script.onload = script.onreadystatechange = ->
              if not done and (not (readyState = @readyState) or readyState == 'loaded' or readyState == 'complete')
                done = true
                callback()
                script.onload = script.onreadystatechange = null
                head.removeChild script
    
            head.appendChild script
    
        if not ($ = window.jQuery) or requirements['jq'] > $.fn.jquery
            getScript 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js', ->
                getScript 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js', ->
                    callback window.jQuery.noConflict(1)
        else
            if not (jqui_version = window.jQuery.ui.version) or requirements['jqui'] > jqui_version
                getScript 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js', ->
                    callback window.jQuery.noConflict(1)
            else
                callback window.jQuery.noConflict(1)
    
    ) window, document, {jq: '1.6.1', jqui: '1.8.7'}, ($) ->
        # Your code goes here:
        alert "jq: #{$.fn.jquery}, jqui: #{$.ui.version}"
    

    Необходимо снять флажок "Добавить jQuery" на странице CoffeeMarklet, если вы используете приведенный выше код

    Обновление: добавлена ​​проверка наличия jQuery и пользовательского интерфейса jQuery, чтобы он не загружался без необходимости.

    Хотя это можно было бы улучшить, проверив, присутствует ли уже правильная версия jQuery, как это делает код Бена Алманса.

    Атрибуция:

    Бейги дал прекрасный фрагмент для загрузки ресурсов javascript один после другого.

    01.07.2011
  • Поскольку вы спросили, вот как я оформлю ваш код: gist.github.com/1059210 В основном, Я сократил вложенность функций до 1 уровня (2, если считать генератор обратного вызова). Кроме того, вместо того, чтобы иметь переменную done, вы должны просто проверять, не является ли script.onload нулевым. 01.07.2011
  • Скажем, у меня есть jQuery 1.5 на веб-сайте, и я загружаю jQuery 1.6 из букмарклета, не испортит ли это ситуацию или noConflict позаботится об этом? 10.07.2011
  • также обратите внимание на опечатку: окна вместо окна 10.07.2011
  • Спасибо, что указали на опечатку. Нет, версия jQuery, представленная на веб-странице, совершенно не изменится, так как мы используем window.jQuery.noConflict(1). Когда jQuery инициализируется, он сохраняет все, что раньше использовало $. Когда вы вызываете noConflict, он возвращает предыдущую вещь в глобальное пространство имен как $, и тогда у вас есть более новая версия jQuery в локальном пространстве имен. Надеюсь, я объяснил это правильно, и это имеет смысл, так как я понял, что это все равно работает. 10.07.2011
  • Спасибо. дополнительные примечания: если нет (jqui_version = window.jQuery.ui.version) или требования ['jqui'] › jqui_version (а) довольно запутан (б) не работает должным образом. Версия, которая работала у меня, но не всегда, была просто если бы не (window.jQuery.ui == undefined), но я совершенно не понимаю этот код =/ 10.07.2011
  • if not (jqui_version = window.jQuery.ui.version) просто проверяет, определено ли window.jQuery.ui.version, одновременно с присвоением его переменной jqui_version. Просто избегает необходимости ссылаться на window.jQuery.ui.version во второй раз. Что заставляет вас говорить, что это не работает? 10.07.2011
  • @Acorn Хороший код. Просто любопытно: почему вы передаете window и document в основную анонимную функцию? Они будут доступны там как глобальные переменные без передачи в качестве аргументов функции. 29.10.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..