2010-05-09 5 views
13

के साथ जांच करते समय window.external पर नो-तर्क विधि लागू की जाती है, मैं System.Windows.Forms.WebBrowser नियंत्रण के अंदर एम्बेडेड जावास्क्रिप्ट कोड वाला एक HTML पृष्ठ प्रदर्शित करने का प्रयास कर रहा हूं। जावास्क्रिप्ट कोड window.external ऑब्जेक्ट के माध्यम से एम्बेडिंग वातावरण के साथ बातचीत करने की उम्मीद है। window.external पर एक विधि का आह्वान करने से पहले, जावास्क्रिप्ट को विधि के अस्तित्व की जांच करनी होगी। यदि यह वहां नहीं है, तो कोड को सामान्य फ़ॉलबैक विधि का आह्वान करना चाहिए।टाइपफ

// basic idea 
if (typeof(window.external.MyMethod) != 'undefined') { 
    window.external.MyMethod(args); 
} else { 
    window.external.Generic("MyMethod", args); 
} 

हालांकि, typeof साथ नो-तर्क विधि के लिए जाँच पहले से ही विधि आह्वान करने के लिए लगता है। यही है, अगर MyMethod तर्कों की किसी भी सकारात्मक संख्या को स्वीकार करता है, तो ऊपर दिया गया कोड पूरी तरह से काम करेगा; लेकिन, यदि MyMethod एक गैर-तर्क विधि है, तो अभिव्यक्ति typeof(window.external.MyMethod) इसके प्रकार की जांच नहीं करेगा बल्कि इसे भी आमंत्रित करेगी।

क्या इस व्यवहार के लिए कोई काम है? विधि कॉल होने से रोकने के लिए क्या मैं किसी भी तरह अभिव्यक्ति window.external.MyMethod से बच सकता हूं?

+0

क्या आपने फ़ंक्शन के बजाए ऑपरेटर के रूप में टाइपफ़ोफ़ का उपयोग करने का प्रयास किया है? 'टाइपोफ विंडो.एक्सनेट। MyMethod! == "अपरिभाषित" ' –

+0

इस प्रश्न का उत्तर देने वाले किसी भी व्यक्ति को ** ** पर' window.external' के साथ अपने समाधान का प्रयास करने की आवश्यकता है ** - जावास्क्रिप्ट पर किसी ऑब्जेक्ट के अस्तित्व के परीक्षण के नियमित तरीके 'window.external' के लिए काम नहीं करते हैं। – funkybro

उत्तर

9

मैं अपने सटीक स्थिति डिबग नहीं किया है में से एक का प्रयास करें, लेकिन मेरा मानना ​​है कि मेरी मानसिक शक्तियों काम कर सकते हैं यहाँ क्या चल रहा है।

JScript भाषा एक समारोह के उपयोग और मात्र उल्लेख इसके बारे में के बीच एक अंतर बना देता है। जब आप

x = f; 

कहते हैं, "चर द्वारा एक्स द्वारा पहचाने गए फ़ंक्शन को संदर्भ निर्दिष्ट करें"। यह उल्लेख करता है एफ। इसके विपरीत,

x = f(); 

का उपयोग करता च। इसका मतलब है "एफ द्वारा पहचाने गए फ़ंक्शन को कॉल करें और लौटाए गए मान को x पर असाइन करें।"

संक्षेप में, जेस्क्रिप्ट में कार्य अनिवार्य रूप से हम प्रतिनिधि के गुणों के रूप में सी # में सोचेंगे।

कुछ भाषाएं इस भेद को नहीं बनाती हैं। वीबीस्क्रिप्ट में, यदि आप x = f कहते हैं और f एक फ़ंक्शन है, तो इसका मतलब है कि फ़ंक्शन को कॉल करना, x = f() जैसा ही है। वीबीस्क्रिप्ट एक समारोह के उपयोग और उल्लेख के बीच वाक्यगत रूप से एक मजबूत भेद नहीं करता है।

जिस तरह से यह सब लागू किया गया है, हम COM का उपयोग करते हैं; विशेष रूप से, हम ओएलई ऑटोमेशन का उपयोग करते हैं। किसी ऑब्जेक्ट के किसी क्षेत्र को अपना मूल्य प्राप्त करने के लिए प्रेषण करते समय, जेस्क्रिप्ट इंजन उस झंडे को पास करता है जिसका मतलब है कि "संपत्ति मिलती है" या "विधि आती है", इस पर निर्भर करता है कि इसका उपयोग या उल्लेख किया गया था या नहीं।

लेकिन मान लीजिए कि आपकी वस्तु को प्रेषित किया गया था, यह उम्मीद के साथ लिखा गया था कि इसे वीबी से बुलाया जाएगा। शायद यह वीबी में लिखा गया था। यह एक वीबी ऑब्जेक्ट के लिए पूरी तरह से उचित और कानूनी है "ओह, मुझे लगता है कि आप मुझे इस विधि के मूल्य के लिए पूछ रहे हैं।चूंकि मैं किसी विधि का उल्लेख करने और इसका उपयोग करने के बीच अंतर को समझ नहीं पा रहा हूं, इसलिए मैं इसे किसी भी फर्क नहीं पड़ता कि आप किस ध्वज को पास करते हैं "

मुझे नहीं पता कि कोई कामकाज है या नहीं, लेकिन मैं एक डॉलर है कि क्या हो रहा है है लागू वस्तु मानते हुए किया जाता है कि फोन करने वाले वीबी अर्थ विज्ञान चाहता है के रूप में के रूप में ज्यादा यकीन करने को तैयार।

+0

हाय एरिक, आपके उत्कृष्ट उत्तर के लिए धन्यवाद। मुझे उम्मीद है कि दृश्यों के पीछे ऐसा कुछ ऐसा होगा क्योंकि मैंने कल 2004 से आपकी ब्लॉग टिप्पणी पढ़ी है (http://discuss.techinterview.org/default.asp?joel.3.18644.7)। मुझे लगता है कि COM सामान WebBrowser नियंत्रण के अंदर कहीं भी लागू किया गया है, है ना? मैं एक और लुकअप हैंडलिंग में पैच करने में सक्षम नहीं होगा?या क्या मैं एक विधि को स्पष्ट रूप से "विधि के रूप में दृश्यमान और संपत्ति नहीं" के रूप में चिह्नित कर सकता हूं? – janko

+0

यदि ऐसा है, तो आप अपने सी # कक्षा में 'आईडीस्पैच' कार्यान्वयन के साथ खेलने का प्रयास कर सकते हैं। सबसे पहले, मैं 'IDispatchImpl' विशेषता का प्रयास करूंगा - इसे 'संगत Ipl' और' InternalImpl 'पर सेट करने का प्रयास करें और देखें कि कोई भी तरीका काम करता है या नहीं। या, आप 'आईडीस्पैच' का अपना कार्यान्वयन प्रदान कर सकते हैं - अपनी ऑब्जेक्ट को चिह्नित करें '[क्लासइंटरफेस (क्लासइंटरफेस टाइप.ऑन)]' और इसे स्पष्ट रूप से 'आईडीस्पैच' लागू करें। मुझे संदेह है (वास्तव में नहीं पता) कि .NET 4.0 के 'IDynamicObject' का उपयोग' IDispatch' मैपिंग के लिए किया जा सकता है। –

-1

मुझे वास्तव में यकीन नहीं है कि यह मदद करेगा, लेकिन window.external["MyMethod"] आज़माएं।

यदि यह मदद नहीं करता है, तो इस मान को एक चर में संग्रहीत करने का प्रयास करें, और उसके बाद केवल उस चर का प्रकार जांचें। देखें कि क्या मदद करता है।

+0

दुर्भाग्य से, कोई भी संस्करण काम नहीं करता है। 'window.external [" MyMethod "] 'इसे आमंत्रित करता है, साथ ही' var f = window.external ["MyMethod"] '। – janko

0

इन

/* Methods for feature testing 
* From http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting 
*/ 
function isHostMethod(object, property){ 
    var t = typeof object[property]; 
    return t == 'function' || 
    (!!(t == 'object' && object[property])) || 
    t == 'unknown'; 
} 

function isHostObject(object, property){ 
    return !!(typeof(object[property]) == 'object' && object[property]); 
} 

if (isHostObject(window.external, "MyMethod")) {.... 
+0

हाय सीन, आपका 'isHostMethod' या तो काम नहीं करता है। लाइन 'ऑब्जेक्ट [प्रॉपर्टी]' अभी भी विधि को आमंत्रित करती है। – janko

6

मैं इस

if ('MyMethod' in window.external) 

पाया MyMethod

+0

लेकिन इससे ज्यादा मदद नहीं मिलती है, तो 'window.external' मौजूद नहीं होने पर स्क्रिप्ट विफल हो जाएगी। – funkybro

+0

@funkybro उस स्थिति में, आपको बस एक अतिरिक्त जांच जोड़ना है, उदा। 'if (window.external 'में window.external &&' MyMethod ')। – erdomke

+0

सच है, हालांकि यदि आप नीचे मेरा जवाब देखते हैं कि बस 'window.external' कर रहे हैं तो IE पर भी असफल हो जाएगा। – funkybro

0

इस आशय आह्वान नहीं है हो सकता है डेस्कटॉप इंटरनेट एक्सप्लोरर में देखा। एक स्क्रिप्ट जैसे:

for (var i in window) { 
    console.log('window.' + i + ' = ' + window[i]); 
} 

जैसे ही external तक पहुँच जाता है असफल हो जायेगी।

ऐसा प्रतीत होता है कि window.external एक नियमित जावास्क्रिप्ट ऑब्जेक्ट नहीं है, यह एक वीबीस्क्रिप्ट ऑब्जेक्ट है।

ऐसे window.external और window['external'] रूप

तो बयान इसलिए VBScript बयान हैं - और, एरिक एल कहते हैं, VBScript में window.externalwindow.external() के बराबर है।

ताकतवर भ्रमित। ऐसा लगता है कि यह इंटरनेट एक्सप्लोरर पर इस तरह से व्यवहार करने का एकमात्र उद्देश्य है।

जो विंडोज फोन 8 पर देशी के साथ संवाद करने IE मोबाइल के window.external.Notify() का इस्तेमाल करते हैं पार ब्राउज़र मोबाइल वेब एप्लिकेशन के लिए

, लेकिन जो भी iOS पर document.location स्थापित करने के लिए, window.external.Notify के अस्तित्व तार्किक प्रतीत होता है के लिए परीक्षण चाहेगा - लेकिन इस कारण से काम नहीं करता है।

मुझे इसे रोकने का कोई तरीका नहीं मिला है; script टैग में type="text/javascript" निर्दिष्ट करते समय यह तब भी होता है।

0

तो वास्तव में केवल एकमात्र विकल्प कामकाज है: 1) बस 0 पैरामीटर फ़ंक्शंस का उपयोग न करें। 2) किसी बाहरी कॉल करने के लिए पता लगाने के लिए एक जांच फ़ंक्शन (पैरामीटर लेना) बनाएं।

if (typeof(window.external.HasExternal(null)) != 'undefined') 

और बाहरी कार्यों को या तो वहां या नहीं तो फ़ंक्शन के बजाय जांचें। 3) प्रत्येक पैरामीटर रहित फ़ंक्शन के लिए, या तो इसे एक बोगस पैरामीटर का उपयोग करें या इसके लिए 1 पैरामीटर जांच फ़ंक्शन जोड़ें यदि बाहरी कोड यह किस प्रकार के कार्यों में भिन्न होता है।