2013-08-29 8 views
6

काम नहीं करता है, मुझे यह काम करने के लिए प्रतीत नहीं होता है।window.opener.focus()

एक क्लिक के जवाब में, विंडो ए विंडो बी खोलता है (जो तब फोकस करता है)। फिर, बी पर एक क्लिक के जवाब में, खिड़की window.opener.focus() कहता है, लेकिन ध्यान देने करता ए

के लिए वापस नहीं मैं क्रोम के लिए एक अजीब, अजीब वैकल्पिक हल (29, संभवतः अन्य) मिल गया है। अगर मैं चलाएँ:

window.opener.name = 'somename'; 
window.open(window.opener.location.href, window.opener.name); 
window.opener.focus(); 

यह काम करता है (और खिड़की एक को फिर से लोड नहीं है)। लेकिन यह फ़ायरफ़ॉक्स के लिए काम नहीं करता है, और यह शायद वैसे भी एक झलक है।

यह मेरे लिए बहुत स्पष्ट लगता है क्या opener और focusचाहिए करने के लिए हैं, लेकिन window.opener.focus() काम नहीं करता। मैं क्या खो रहा हूँ?

उत्तर

5
fine manual से

:

एक अनुरोध सामने खिड़की लाने के लिए बनाता है। यह उपयोगकर्ता सेटिंग्स के कारण असफल हो सकता है और इस विधि के रिटर्न से पहले खिड़की को सबसे आगे होने की गारंटी नहीं है।

जोर मेरा। कॉलिंग focus() सिर्फ एक अनुरोध है और ब्राउज़र आपको अनदेखा करने के लिए स्वतंत्र है और आपको आम तौर पर अनदेखा होने की उम्मीद करनी चाहिए। इस बात पर विचार करें कि आप एक छोटे से खिड़की पर ध्यान केंद्रित करके कितनी परेशान चीजें प्राप्त कर सकते हैं, जबकि कोई आपको लिख रहा है अगर आपको कुछ कारणों की आवश्यकता है कि ब्राउज़र आपके अनुरोध को अनदेखा क्यों करेगा।

यदि आपको अपने आवेदन के लिए काम करने के लिए focus() की आवश्यकता है तो आपको अपने आवेदन को फिर से डिजाइन करना होगा ताकि उसे focus() पर कॉल करने की आवश्यकता न हो।

+1

(1) क्या उपयोगकर्ता सेटिंग्स इस कारण हैं? (2) "इस विधि के रिटर्न से पहले विंडो को सबसे आगे होने की गारंटी नहीं है।" मुझे परवाह नहीं है कि यह कॉल के अंत में सामने है; मैं बस इसे अंत में चाहता हूँ। –

+1

@PaulDraper यदि यह एक सार्वजनिक वेबसाइट के लिए है, तो आप बस (विश्वसनीय रूप से) चाहते हैं कि आप चाहते हैं कि आप पूछ रहे हों। –

1

वेब-फेस या निजी इंट्रानेट?

विंडो प्रबंधन ब्राउज़र और ओएस पर है। एचटीएमएल & ईसीएमएस्क्रिप्ट के बारे में कुछ भी कहना नहीं है।

यदि यह सार्वजनिक-सामने वाली वेबसाइट के लिए है, तो बस परेशान न करें - जैसा कि वे कहते हैं, "वेब को तोड़ें नहीं।"

लेकिन मैं वास्तव में चाहता हूं!

यदि यह किसी तरह का कड़ाई से प्रबंधित (इंट्रानेट कहें) एप्लिकेशन के लिए है तो आपको एडॉन्स/एक्सटेंशंस लिखने का सहारा लेना होगा। यह निश्चित रूप से आसान है यदि आप स्वयं को एक ब्राउज़र & प्लेटफ़ॉर्म पर सीमित कर सकते हैं।

संपादित: फ़ायरफ़ॉक्स Win32 पर के लिए उदाहरण ...

यह समाधान जो jsctypes आंतरिक रूप से उपयोग करता है एक Win32 DLL लोड करने के लिए Firefox के लिए एक कस्टम ऐड-ऑन के रूप में काम करता है। window_focus() जावास्क्रिप्ट फ़ंक्शन उजागर किया गया है जो आप चाहते हैं जो करता है।

इस समाधान के लिए 3 भागों के होते हैं:

  1. विशेषाधिकार प्राप्त जावा स्क्रिप्ट कोड लोड करने के लिए/Win32 एपीआई
  2. हमारे बाहरी DLL के लिए सीपीपी हेडर फाइल बाँध
  3. हमारे बाहरी DLL के लिए सीपीपी स्रोत फ़ाइल

मैं बाद में दो फ़ाइलों & wmctrl.dll संकलित साथ MSVC में एक साधारण जीयूआई DLL परियोजना ++ बनाया गया है, पर msvcr100.dll निर्भर करता है, और Dependency Walker इस्तेमाल किया लगता है "के लिए सादा सी "जेएस-सीटीपीएस द्वारा उपयोग के लिए डीएलएल द्वारा निर्यात किए गए प्रतीकों। उदा। [email protected]@[email protected] सी ++ एपीआई फ़ंक्शन के लिए "सादा सी" प्रतीक है जिसे wmctrl_find_window कहा जाता है।

एक चेतावनी के रूप में, यह कोड अस्थायी रूप से उस विंडो के शीर्षक को बदलने में सक्षम है जिस पर ध्यान केंद्रित करने की आवश्यकता है ताकि Win32 API सही फ़ायरफ़ॉक्स विंडो खोजने के लिए आपके डेस्कटॉप पर सभी विंडो की जांच कर सके।

आप यानी विशेषाधिकार प्राप्त मोज़िला मंच API तक पहुंच, की आवश्यकता है: एक Firefox Addon अंदर जावास्क्रिप्ट।

अपने विशेषाधिकार प्राप्त जावा स्क्रिप्ट कोड में:

// get API constants (might already be available) 
const {Cc,Ci,Cu} = require("chrome"); 

// import js-ctypes 
var file=null, lib=null, ctypes = {}; 
Cu.import("resource://gre/modules/ctypes.jsm", ctypes); 
var ctypes = ctypes.ctypes; 

// build platform specific library path 
var filename = ctypes.libraryName("wmctrl"); // automatically adds '.dll' 
var comp = "@mozilla.org/file/directory_service;1"; 
var file = Cc[comp].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile); 
file.append("browser_code"); // or whereever you put your DLL 
file.append(filename); 

// get the JavaScript library interface (load the library) 
var lib = ctypes.open(file.path); 

// wmctrl_find_window: returing unsigned 32bit (long) "window handle" 
// takes string "window title". 
var find_window = lib.declare(
    "[email protected]@[email protected]",  /* plain "C" DLL symbol */ 
    ctypes.stdcall_abi, ctypes.uint32_t, /* return type: uint32 */ 
    ctypes.char.ptr);     /* parameter: string  */ 

// wmctrl_window_focus: takes unsigned 32bit (long) "window handle". 
var window_focus = lib.declare(
    "[email protected]@[email protected]",  /* plain "C" DLL symbol */ 
    ctypes.stdcall_abi, ctypes.void_t, /* return type: void  */ 
    ctypes.uint32_t);     /* parameter: uint32  */ 

wmctrldll.h

#ifdef WMCTRLDLL_EXPORTS 
#define WMCTRLDLL_API __declspec(dllexport) 
#else 
#define WMCTRLDLL_API __declspec(dllimport) 
#endif 

WMCTRLDLL_API void wmctrl_window_focus (unsigned long wid); 
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title); 

wmctrldll.cpp

typedef struct { 
    HWND hWnd; 
    char title[255]; 
} myWinSpec; 

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { 
    char String[255]; 
    myWinSpec* to_find = (myWinSpec*) lParam; 

    // not a window 
    if (!hWnd) return TRUE;         

    // not visible 
    if (!IsWindowVisible(hWnd)) return TRUE; 

    // no window title     
    if (!GetWindowTextA(hWnd, (LPSTR)String, 255)) return TRUE; 

    // no title match 
    if (strcmp(String, to_find->title) != 0) return TRUE;  

    to_find->hWnd = hWnd; 
    return FALSE; 
} 

WMCTRLDLL_API void wmctrl_window_focus(unsigned long wid) { 
    SetForegroundWindow((HWND) wid); 
} 

WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title) { 
    myWinSpec to_find; 

    sprintf_s(to_find.title, sizeof(to_find.title), "%s", find_title); 
    to_find.hWnd = 0; 

    EnumWindows(EnumWindowsProc, (LPARAM)&to_find); 
    return (unsigned long) to_find.hWnd; 
} 
+0

"विंडो प्रबंधन ब्राउज़र और ओएस तक है।" तो हमें 'window.open() ',' window.blur() ', और' window.focus() 'के बारे में क्या करना चाहिए? –

+0

'window.open() 'आपकी वर्तमान ब्राउज़र विंडो की एक नई * बच्ची * विंडो खोलना है। विंडो का प्रबंधन अभी भी ब्राउज़र/ओएस तक है। अन्य डॉम ऑब्जेक्ट्स की तुलना में '.blur() 'और'। फ़ोकस() 'विधियां वास्तव में इंटरफ़ेस की पूर्णता के लिए हैं - वे उपयोगकर्ता सेटिंग्स और न ही ऑपरेटिंग सिस्टम को ओवरराइड नहीं कर सकते हैं और नहीं करेंगे। –

+1

@PaulDraper: जावास्क्रिप्ट काफी पुराना है और हमने कुछ सबक सीखा है कि क्या है और यह एक अच्छा विचार नहीं है। हम बहुत सारे बुरे विचारों का समर्थन करने का नाटक कर रहे हैं। –

3

मैं देख सकता हूँ क्यों एक ब्राउज़र/OS एक बच्चे की अनुमति नहीं होगी खिड़कियों पर ध्यान केंद्रित करने के लिए खिड़कियां (शक्ति का दुरुपयोग)। यहां एक वर्कअराउंड है:

  1. पैरेंट विंडो में, "window.external" में एक फ़ंक्शन घोषित करें जो जावास्क्रिप्ट "अलर्ट()" या "पुष्टिकरण()" को ट्रिगर करेगा।
  2. उस फ़ंक्शन को बच्चे विंडो से आमंत्रित करें।
  3. ब्राउज़र उस बच्चे की खिड़की से अनुरोध को अनदेखा कर सकता है जो फोकस को नियंत्रित करना चाहता है (उदाहरण के लिए window.opener.focus()), लेकिन ब्राउजर को एक मूल विंडो से अनुरोध का सम्मान करना चाहिए जो एक चेतावनी() या पुष्टि करता है() कार्रवाई, जिसे पैरेंट विंडो पर ध्यान केंद्रित करने की आवश्यकता है।

जे एस जनक:

var child = window.open('child.html', 'child'); 
    window.external.comeback = function() { 
     var back = confirm('Are you sure you want to comback?'); 
     if(back) { 
      child.close(); 
     } else { 
      child.focus(); 
     } 
    } 

जे एस बाल:

// assuming you have jQuery 
    $('.btn').click() { 
     window.opener.external.comeback(); 
    }; 

--I एक वास्तविक दुनिया आवेदन में इस कोड का उपयोग कर रहा एक चेकआउट अनुरोध है कि चाइल्ड विंडो में चलता है संभाल करने के लिए, और मुझे अभिभावक खिड़की पर कृपापूर्वक लौटने की ज़रूरत है।

देखें: "। यह उपयोगकर्ता सेटिंग के कारण विफल हो सकता है" SimplifySites.com