5

を介してページをロードし、結果の一部をページの対応する部分に挿入$.ajax()しています。

$.ajax({
  url: '/whole_page.html',
  success: function (data, status, xhr) {
    $result = $(xhr.responseText);
    $('#menu').html($('#menu', $result).html());
    $('#content').html($('#content', $result).html());
  }
});

チャームのように機能しますが、問題が発生しました。

これで、私のページには、結果をフェッチして挿入するときに実行する必要のあるページ固有のJSが含まれています。私の知る限り、scriptHTMLテキストからjQueryオブジェクトを作成し、それに対してクエリを実行した場合、jQueryは要素を返しません(私はデモンストレーションのためにフィドルを作成しました)。したがって、jQueryを介して必要なスクリプトのみを選択的に挿入する方法はありません。

scriptしたがって、応答テキストから要素を自分で取得する必要があるように思われます。基本的に、私はこれを行う正しい方法を探しています。これが私がこれまでに思いついたものです:

function pullScripts(text) {
  var frag = document.createDocumentFragment()
    , div = document.createElement('div')
    , scriptElements
    ;

  // This is roughly how jQuery finds the scripts when cleaning text
  frag.appendChild(div);
  div.innerHTML = text;

  scriptElements = div.getElementsByClassName('class-for-scripts-that-we-want');

  $('head').append(scriptElements);
}

これは十分に機能しますが、私はまだくだらないブラウザでテストしていません。scriptとにかく、jQueryの機能の1つ(特別な処理)を回避するためだけに、jQueryのそのような基本的な機能を複製することは不快に感じます。フィドルに見られるように、jQueryオブジェクトには実際にはsが含まれていますが、またはscriptのようなものでそれらを返すことはありません。私はこれを行うためのいくつかの明白な方法を逃していますか?.html().get()

注:jQueryの内部parseHTML関数が公開されると、このトピック全体は議論の余地があります

注2:jQuery ajax get responseからスクリプトタグを選択しようとしていますが、受け入れられる答えは「できません」の後に「正規表現を使用する」です。どちらも物足りない

4

3 に答える 3

3

jQuery 1.8.0b1では、$.parseHTML()このメソッドを使用してこれを簡単に行えるようになりました。

$.parseHTML(xhr.responseText,true)スクリプト要素を含むjQueryオブジェクトを提供します。次に、スクリプトタグを抽出し、htmlを追加した後にそれらを追加または実行できます。

$.ajax({
  url: '/whole_page.html',
  success: function (data, status, xhr) {
    var $result = $.parseHTML(xhr.responseText,true),
        $scripts = $result.find("script").add($result.filter("script")).detach();

    $('#menu').html($('#menu', $result).html());
    $('#content').html($('#content', $result).html());
    $('head').append($scripts);
  }
});

ただし、ケースバイケースでjQueryを二重に含めることを避けるために、スクリプトをフィルタリングする必要がある場合があります。ロードするコンテンツによって異なります。

jQueryをアップグレードするオプションがない場合は、実装を取得し$.parseHTMLて、現在のjQueryへのプラグインとして含めることができます。

(function($) {
    if (!$.parseHTML) {
        var rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/;
        // data: string of html
        // context (optional): If specified, the fragment will be created in this context, defaults to document
        // scripts (optional): If true, will include scripts passed in the html string
        $.parseHTML = function( data, context, scripts ) {
            var parsed;
            if ( !data || typeof data !== "string" ) {
                return null;
            }
            if ( typeof context === "boolean" ) {
                scripts = context;
                context = 0;
            }
            context = context || document;

            // Single tag
            if ( (parsed = rsingleTag.exec( data )) ) {
                return [ context.createElement( parsed[1] ) ];
            }

            parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
            return jQuery.merge( [],
                (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
        }
    }
})(jQuery);
于 2012-07-09T18:09:25.300 に答える
2

昨夜jsFiddleでjQuery(edge)で遊んでいたとき.find()、の結果で友達を使うことができませんでし$.parseHTML()た。問題は$.parseHTML、jQueryオブジェクトではなく要素の配列を返すことでした。それを使用して作成すると$()、元の問題に戻ります。したがって、セレクターを実際に使用することはできません。ただし、それほど面倒なことではありません。

$.ajax({
  url: '/some_page.html',
  success: function (data, text, xhr) {
    var result = $.parseHTML(data, true)
      , scripts = []
      , i;

    // filter the scripts somehow
    for (i = 0; i < result.length; i++) {
        if (result[i].getAttribute('class') === 'good') {
            scripts.push(result[i]);
        }
    }

    $('head').append(scripts);
  }
});​

私はこれのために働くフィドルを作りました。

于 2012-07-10T16:37:05.707 に答える
0

前に述べたように、ノードの配列を返す$.parseHTMLを使用する必要があります。

スクリプトタグにクラス「append-on-ajax-script」を追加しました。これは、ajaxリクエストで追加する必要があります。

また、getAttribute('class')関数に問題があったため、私の例にはクラスチェックの回避策がいくつかあります。

<script type="text/javascript" class="append-on-ajax-script">
$.post(
    $(this).prop('href'),
    {'some_data':'some_value'},
    function(data) {
        var script = $.parseHTML(data, true);
        for (var i = 0; i < script.length; i++) {
            //console.log(i, (' ' + script[i].className + ' ').indexOf(' append-on-ajax-script ') > -1 );
            if ((' ' + script[i].className + ' ').indexOf(' append-on-ajax-script ') > -1) {
                // console.log(i, script[i]);
                $('body').append(script[i]);
            }
        }

    }
);
</script>

<script type="text/javascript" class="append-on-ajax-script">
    alert('repeat me on ajax');
</script>
于 2018-05-07T18:54:15.527 に答える