سؤال

هذا إلى حد ما متابعة للإجابة هنا.

لدي عنصر تحكم ActiveX مخصص يقوم برفع حدث ("ReceiveMessage" مع معلمة "msg") يحتاج إلى معالجته بواسطة Javascript في متصفح الويب.تاريخيًا، تمكنا من استخدام صيغة IE التالية فقط لإنجاز ذلك في مشاريع مختلفة:

function MyControl::ReceiveMessage(msg)
{
   alert(msg);
}

ومع ذلك، عندما تكون داخل تخطيط يتم فيه دفن عنصر التحكم، لا يمكن لـ Javascript العثور على عنصر التحكم.على وجه التحديد، إذا وضعنا هذا في صفحة HTML عادية، فسيعمل بشكل جيد، ولكن إذا وضعناه في صفحة ASPX مغلفة بـ <Form> العلامة، نحصل على خطأ "MyControl غير محدد".لقد جربنا الاختلافات في ما يلي:

var GetControl = document.getElementById("MyControl");
function GetControl::ReceiveMessage(msg)
{
   alert(msg);
}

...ولكنه يؤدي إلى خطأ Javascript "GetControl غير محدد."

ما هي الطريقة الصحيحة للتعامل مع حدث يتم إرساله من عنصر تحكم ActiveX؟الآن نحن مهتمون فقط بتشغيل هذا في IE.يجب أن يكون هذا عنصر تحكم ActiveX مخصصًا لما نقوم به.

شكرًا.

هل كانت مفيدة؟

المحلول

لقد تمكنت من تنفيذ هذا باستخدام تنسيق كتلة البرنامج النصي التالي، ولكن لا يزال لدي فضول لمعرفة ما إذا كانت هذه هي أفضل طريقة:

<script for="MyControl" event="ReceiveMessage(msg)">
    alert(msg);
</script>

نصائح أخرى

لقد استخدمت activex في تطبيقاتي من قبل.أضع علامات الكائنات في نموذج ASP.NET ويعمل جافا سكريبت التالي لصالحي.

function onEventHandler(arg1, arg2){
    // do something
}

window.onload = function(){
    var yourActiveXObject = document.getElementById('YourObjectTagID');
    if(typeof(yourActiveXObject) === 'undefined' || yourActiveXObject === null){
        alert('Unable to load ActiveX');
        return;
    }

    // attach events
    var status = yourActiveXObject.attachEvent('EventName', onEventHandler);
}

حسنًا، ولكن إذا كنت تستخدم C# (.NET 2.0) مع UserControl (ActiveX) الموروث...الطريقة الوحيدة لإنجاحها هي من خلال "توسيع" وظيفة معالج الحدث:http://www.codeproject.com/KB/dotnet/extend_events.aspx?display=Print

رابط المشروع أعلاه من صديقنا السيد.لقد أنقذ Werner Willemsens مشروعي.إذا لم تفعل ذلك، فلن يتمكن جافا سكريبت من الارتباط بمعالج الأحداث.

لقد استخدم "الامتداد" بطريقة معقدة نظرًا للمثال الذي اختاره، ولكن إذا جعلت الأمر بسيطًا، عن طريق ربط المقبض مباشرة بالحدث نفسه، فإنه يعمل أيضًا.يجب أن يدعم C# ActiveX "ScriptCallbackObject" لربط الحدث بوظيفة جافا سكريبت كما هو موضح أدناه:

  var clock = new ActiveXObject("Clocks.clock");
  var extendedClockEvents = clock.ExtendedClockEvents();
  // Here you assign (subscribe to) your callback method!
  extendedClockEvents.ScriptCallbackObject = clock_Callback; 
  ...
  function clock_Callback(time)
  {
    document.getElementById("text_tag").innerHTML = time;
  }

بالطبع يتعين عليك تطبيق IObjectSafety وعناصر الأمان الأخرى لجعله يعمل بشكل أفضل.

إذا كان لديك عنصر ActiveX على صفحتك يحتوي على معرف "MyControl"، فإن بناء جملة معالج جافا سكريبت الخاص بك هو كما يلي:

function MyControl::ReceiveMessage(msg)
{
   alert(msg);
}

لقد وجدت أن هذا الرمز يعمل ضمن علامة النموذج.في هذا المثال، رد الاتصال هو معلمة دالة تم تمريرها بواسطة جافا سكريبت إلى عنصر تحكم ActiveX، ومعلمة رد الاتصال هي معلمة لحدث رد الاتصال الذي تم إنشاؤه داخل عنصر تحكم ActiveX.بهذه الطريقة أستخدم نفس معالج الأحداث لأي نوع من الأحداث، بدلاً من محاولة الإعلان عن مجموعة من معالجات الأحداث المنفصلة.

<object id="ActivexObject" name="ActivexObject" classid="clsid:15C5A3F3-F8F7-4d5e-B87E-5084CC98A25A"></object>

<script>
function document.ActivexObject::OnCallback(callback, callbackparam){
callback(callbackparam);
}
</script>

في حالتي، كنت بحاجة إلى طريقة لإنشاء عناصر تحكم ActiveX ديناميكيًا والاستماع إلى أحداثها.لقد تمكنت من الحصول على شيء مثل هذا للعمل:

//create the ActiveX
var ax = $("<object></object>", {
    classid: "clsid:" + clsid,
    codebase: install ? cabfile : undefined,
    width: 0,
    height: 0,
    id: '__ax_'+idIncrement++
})
.appendTo('#someHost');

ثم لتسجيل معالج لحدث ما:

//this function registers an event listener for an ActiveX object (obviously for IE only)
//the this argument for the handler is the ActiveX object.
function registerAXEvent(control, name, handler) {
    control = jQuery(control);

    //can't use closures through the string due to the parameter renaming done by the JavaScript compressor
    //can't use jQuery.data() on ActiveX objects because it uses expando properties

    var id = control[0].id;

    var axe = registerAXEvent.axevents = registerAXEvent.axevents || {};
    axe[id] = axe[id] || {};
    axe[id][name] = handler;

    var script =
    "(function(){"+
    "var f=registerAXEvent.axevents['" + id + "']['" + name + "'],e=jQuery('#" + id + "');"+
    "function document." + id + "::" + name + "(){"+
        "f.apply(e,arguments);"+
    "}"+
    "})();";
    eval(script);
}

يسمح لك هذا الرمز باستخدام عمليات الإغلاق ويقلل من نطاق eval().

عناصر تحكم ActiveX <object> يجب إضافة العنصر بالفعل إلى المستند؛وإلا فلن يعثر IE على العنصر وستحصل على أخطاء في البرنامج النصي.

أعتقد أن مثال MyControl::ReceiveMessage لا يعمل لأنه يتم عرض عنصر تحكم ActiveX باسم مختلف أو في نطاق مختلف.

باستخدام المثال GetControl::ReceiveMessage، أعتقد أنه يتم تحليل تعريف الوظيفة قبل تعيين مرجع GetControl، وبالتالي فهو لا يشير إلى كائن صالح ولا يمكنه ربط الوظيفة بالكائن.

سأهاجم هذه المشكلة باستخدام مصحح أخطاء البرنامج النصي لـ MS ومحاولة تحديد ما إذا كان المرجع الافتراضي لعنصر التحكم موجودًا باسم مختلف أو في نطاق مختلف (ربما كفرع للنموذج).إذا تمكنت من تحديد المرجع الصحيح لعنصر التحكم، فيجب أن تكون قادرًا على ربط الوظيفة بشكل صحيح باستخدام Automagic ::الطريقة التي تحددها مقالة MSDN.

فكرة أخرى، قد يعتمد المرجع على اسم الكائن وليس المعرف، لذا حاول تعيين كليهما :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top