13

DOM オブジェクトの (画面の左上隅を基準とした) 正確な画面座標をどうにか取得できますか? NPAPI\FireBreath または JavaScript を介して。(私が FireBreath で書いているプラ​​グインにはこれが必要です)

4

3 に答える 3

7

PS: 私はずっと前にこの質問をしたことを知っていますが、最後に得たものを要約したいと思います.

element.offsetLeft\Top問題の意図したとおりに機能しません。
HTML から、ユーザー画面自体ではなく、ページのスペースの左上隅に相対的な座標を取得できます。

また、プラグインからは、GetWindowRect()winAPI 関数を使用して、ユーザー画面に対するブラウザ ウィンドウの左上隅の座標を取得できますGetClientRect() 。また、クライアントの長方形の左上隅の座標を取得できます。

しかし、それはページの左上と同じポイントではありません。ページのスペースの隅とクライアント四角形またはウィンドウ四角形の間に常に何かがあります。これには、トップ ブラウザー バーやその他のものが含まれます。

何ができる?100% 制御可能な簡単な方法はないようです。

これらのブラウザ バーを考慮して、ページの四角形の間のスペースを計算することはできますClient rectが、これらのブラウザ バーはユーザーごとに一定ではなく、複数のバーを使用したり、別のバーを使用したりすると、すべての座標系が台無しになります。次に、インストールされたバーと追加機能の量を何らかの方法でブラウザに登録し、それに従って、それらによって消費されるスペースの量を計算しますが、バーと追加機能は同じではなく、考慮すべき変数が多すぎます.

少し簡単な方法があります。上からではなく、下から行くことができます-四角形の下端の座標を取得し、HTML を使用していくつかの計算を行いますelement.offset-座標系をウィンドウの左下の点にバインドします。
下部にユーザー ブラウザー バーがないため、ページとウィンドウ コーナーの間のスペースにもう少し自信を持つことができます。

もう 1 つのオプションは、モーダル ウィンドウを使用することです。つまり、JavaScript からモーダル ウィンドウでページを開きますwindow.open()。これらのウィンドウのブラウザ コントロールとバーの量を制御できます。これらのすべてのユーザーバーを取り除き、アドレス バーのみのクリア ウィンドウを作成できます。そしてページ。これで、より詳細に制御できるようになり、コーナー間のこのスペースがすべてのユーザーに対して同じになることをほぼ確実に確認できます...ほぼ.
言及する必要がある2つのことがあります:

1) 一部のブラウザー (Google chrome など) では、これらのカスタム ブラウザーの追加機能 (Firebug など) がアドレス バーの近くに小さなアイコンとして表示され、モーダル ウィンドウのアドレス バーの近くに引き続き表示されます。
あなたが尋ねることができる違いは何ですか - 違いは、何らかの理由で、それらのアイコンの1つでもある場合、ブラウザウィンドウの上部が約5ピクセル太くなるということです.ユーザーのブラウザーにインストールされている
かどうか) そして、とにかく、これらの 5px があなたにとって重要ではない場合 - それは行く方法になる可能性があります.. 次のことで問題がなければ.

2) 明らかな 1 つ - モーダル ウィンドウを使用することは、エンド ユーザーにとって不快な場合があります。これは、ブラウザー ユーザーが慣れている一部のブラウザー コントロールとメカニズムが削減されるためです。

于 2014-01-22T05:11:20.140 に答える
5

jQuery について触れていないことは承知していますが、例としてhttp://api.jquery.com/offset/を使用できます。offsetLeft/topすべての親とスクロールのアカウントを組み合わせて、ネストされたノードの正確な x、y (ボディに関連する) を提供します。

イベントを処理している場合、イベント オブジェクトは常にhttp://api.jquery.com/event.pageX/およびhttp://api.jquery.com/event.pageY/を使用してイベントが発生した場所を通知することに注意してください。

繰り返しますが、jQuery について言及するのは、それを使用したくない場合にのみインスピレーションを得るためです。

これがjQueryのやり方です

$.fn.offset = function (options) {
    var elem = this[0],
        doc = elem && elem.ownerDocument;

    if (!doc) {
        return null;
    }

    if (elem === doc.body) {
        return jQuery.offset.bodyOffset(elem);
    }

    return getOffset(elem, doc, doc.documentElement);
}

function getOffset(elem, doc, docElem, box) {
    try {
        box = elem.getBoundingClientRect();
    } catch(e) {}

    // Make sure we're not dealing with a disconnected DOM node
    if (!box || !jQuery.contains(docElem, elem)) {
        return box ? {
            top: box.top,
            left: box.left
        } : {
            top: 0,
            left: 0
        };
    }

    var body = doc.body,
        win = getWindow(doc),
        clientTop = docElem.clientTop || body.clientTop || 0,
        clientLeft = docElem.clientLeft || body.clientLeft || 0,
        scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
        scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
        top = box.top + scrollTop - clientTop,
        left = box.left + scrollLeft - clientLeft;

    return {
        top: top,
        left: left
    };
}
于 2013-03-29T16:09:52.293 に答える