3

AJAX ( jQueryではなくプレーンJavaScript)を使用して、ページ(同じドメイン)を取得し、特定のDOM要素のみを表示するにはどうすればよいですか?(「bodyContent」のIDでマークされたDOM要素など)。

私はMediaWiki1.18を使用しているので、私の方法は少し慣習的ではない必要があります(jQueryのバージョンをMediaWikiで有効にできることは知っていますが、それを行うためのアクセス権がないため、他のオプションを調べる必要があります)。コードが乱雑である場合はお詫びしますが、この方法でビルドする必要がある理由があります。私は主に、Javascriptで何ができるかを知りたいと思っています。

HTMLコードは次のとおりです。

<div class="mediaWiki-AJAX"><a href="http://www.domain.com/whatever"></a></div>

これが私がこれまでに持っているJavascriptです:

var AJAXs = document.getElementsByClassName('mediaWiki-AJAX');
if (AJAXs.length > 0) {
    for (var i = AJAXs.length - 1; i >= 0; i--) {
        var URL = AJAXs[i].getElementsByTagName('a')[0].href;
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                AJAXs[i].innerHTML = xmlhttp.responseText;
            }
        }
        xmlhttp.open('GET',URL,true);
        xmlhttp.send();
    }
}


編集:

lbstrの回答のおかげで、私は次のことを思いつくことができました。不要な要素を削除するために、追加の手順を追加したことに気付くでしょう。何らかの理由で、getElementById()はresponseTextで機能しませんでしたが、getElementsByClassName()は機能しました。これは、AJAX呼び出しが実行される前に、「bodyContent」のIDがwikiページにすでに存在しているためだと思います。

//This function is necessary to read the response text correctly.
function outerHTML(node){
    // if IE, Chrome take the internal method otherwise build one
    return node.outerHTML || (
    function(n){
        var div = document.createElement('div'), h;
        div.appendChild( n.cloneNode(true) );
        h = div.innerHTML;
        div = null;
        return h;
    })(node);
}

// This code deals with populating the AJAX divs within a wiki page.
var AJAXs = document.getElementsByClassName('mediaWiki-AJAX');
if (AJAXs.length > 0) {
    for (var i = AJAXs.length - 1; i >= 0; i--) {
        (function(index){
            var URL = AJAXs[index].getElementsByTagName('a')[0].href;
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    var tempDiv = document.createElement('div');
                    tempDiv.innerHTML = xmlhttp.responseText;
                    var AJAXContent = tempDiv.getElementsByClassName('mw-content-ltr')[0];

                    //Remove unnecessary "fixed" items to avoid clutter.
                    var hiddenItems = AJAXContent.getElementsByClassName('hidden-item');
                    if (hiddenItems.length > 0) {
                        for (var j = hiddenItems.length - 1; j >= 0; j--) {
                            AJAXContent.removeChild(hiddenItems[j]);
                        }
                    }
                    var protectedItems = AJAXContent.getElementsByClassName('protected-item');
                    if (protectedItems.length > 0) {
                        for (var j = protectedItems.length - 1; j >= 0; j--) {
                            AJAXContent.removeChild(protectedItems[j]);
                        }
                    }

                    //Insert the AJAX content and rerun Javascript on it.
                    if (AJAXContent !== null && AJAXContent !== undefined) {
                        AJAXs[index].innerHTML = outerHTML(AJAXContent);
                        assign_Popup_Functions(AJAXs[index]);
                        fix_External_Links(AJAXs[index]);
                        assign_iFrame_Functions(AJAXs[index]);
                    }
                }
            }
            xmlhttp.open('GET',URL,true);
            xmlhttp.send();
        })(i);
    }
}
4

2 に答える 2

4

コールバックでこれを行うことができるようです:

var temp = document.createElement("div");
temp.innerHTML = xmlhttp.responseText;
var bodyContent = temp.getElementById("bodyContent");
if (bodyContent !== null && bodyContent !== undefined) {
    AJAXs[i].innerHTML = outerHTML(bodyContent);
}

このSO投稿からこのouterHTML関数を考えると:

function outerHTML(node){
    // if IE, Chrome take the internal method otherwise build one
    return node.outerHTML || (
    function(n){
        var div = document.createElement('div'), h;
        div.appendChild( n.cloneNode(true) );
        h = div.innerHTML;
        div = null;
        return h;
    })(node);
}

これを複数のAJAXsコンテナに対して行う場合、同じID()を持つ複数のアイテムが作成される可能性があることに注意してくださいbodyContent。それを回避する方法を考え出すようにしてください。代わりにinnerHTMLが必要ですか?

編集:

また、セットアップで発生するバグを指摘するのを忘れました。ループが完了したにコールバックに到達するため、の値iは常にになり0、正しいコンテナーを更新しません。次のようなことをする必要があります。

for (var i = AJAXs.length - 1; i >= 0; i--) {
    (function(index){
        var URL = AJAXs[index].getElementsByTagName('a')[0].href;
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                AJAXs[index].innerHTML = xmlhttp.responseText;
            }
        }
        xmlhttp.open('GET',URL,true);
        xmlhttp.send();
    })(i);
}
于 2012-11-19T17:12:28.367 に答える
0

iframeはこれを行うための便利な方法です。高レベルの手順は次のとおりです。

  1. 非表示のiframeを作成する
  2. リモートURLをロードします
  3. onloadはiframeコンテンツにアクセスします
  4. 特定の要素を取得する

iframeは、リモートページにページコンテンツを変更するJavaScriptが含まれている場合に特に役立ちます(単純なajaxリクエストではスクリプトは実行されません)。

これは間違いなく、jQueryのようなライブラリが本当に役立つ状況です。これにより、すべてが透過的になります。

于 2012-11-20T04:54:21.663 に答える