SVG تفاعلي باستخدام <object>؟

أحاول تضمين تصور بيانات تفاعلي قائم على SVG. أقوم بتوليد SVG من نظام منفصل (ولكنه لا يزال ضمن نفس النطاق من المستوى الثاني مثل تثبيت Discourse الخاص بي). لقد جربت إدخال SVG باستخدام وسم OBJECT…

<object type="image/svg+xml" data="full_URL_to_foo.svg">
(يظهر إذا فشل تحميل الكائن)
</object>

إذا قمت ببساطة بإحضار ذلك SVG (يتم إنشاؤه ديناميكيًا في كل مرة) باستخدام وسم IMG، يظهر التصور، ولكن (كما توقعت) لا توجد تفاعلية…

<img src="full_URL_to_foo.svg">

أفكار أو إشارات إلى أين يمكنني الحصول على بعض التلميحات بخصوص SVG و Discourse؟ :slight_smile:

إعجاب واحد (1)

الطريقة الأسهل لجعل هذا يعمل هي استخدام إطار مضمن (iframe). أضف نطاق SVG إلى إعداد الموقع allowed_iframes وأضفه إلى منشور باستخدام HTML.

5 إعجابات

هممم، إذن هذه هي الطريقة السهلة.

هل توجد طريقة صعبة يمكنني تجربتها؟

…لأني أريد وجود روابط داخل ملف SVG تُغيّر موقع المتصفح. الروابط داخل ملف SVG، عند وضعها داخل إطار مُضمَّن (IFRAME)، تُغيّر ما يُعرض داخل الإطار…

أشك في أن تضمين كود JavaScript في الموضوع، مباشرة قبل الإطار المُضمَّن، واستدعاء دالة JavaScript في الصفحة عبر حدث onclick في ملف SVG… لن ينجح ذلك أيضًا.

هل أنا واضح؟ هل يجب أن أضيف بعض كود JavaScript بسيطًا على غرار Mitigate XSS Attacks with Content Security Policy ثم أحاول استدعاؤه من داخل ملف SVG الموجود في الإطار المُضمَّن؟ … أم أن عبارة “داخل الإطار المُضمَّن” تعني حصنًا محكم الإغلاق؟

ربما ينبغي أن أسأل كيف يمكنني تضمين ملف SVG مباشرة في الصفحة؟ ثم استخدام كود JavaScript مُحقَن عبر مكون السمة (theme-component) للتفاعل مع خادم آخر لتحديث ملف SVG ديناميكيًا؟

أرجو مساعدة :slight_smile:

إعجابَين (2)

قد ينجح وضع ملف SVG في المشاركة المُميزة بـ div خاص محاط باستخدام عنصر theme-component لتحويله إلى وسم object عبر استدعاء decorateCooked. راجع دليل المطور لمواضيع Discourse

3 إعجابات

في حال كان هناك شخص يتابع، فإن decorateCooked() أصبحت قديمة. أنا أتعامل مع decorateCookedElement() بدلاً من ذلك.

إعجاب واحد (1)

أنا أواجه مشكلة تتعلق بـ CORS/Access-Control-Allow-Origin. لست على دراية بكيفية عمل ذلك…

لدي موقعان: موقع Discourse المستضاف (forum.moversmindset.com) وموقع WordPress مبني على Apache (moversmindset.com). لاحظ أنه لا يوجد محتوى واضح على موقع WordPress؛ فهو يولد تغذيات RSS، ويقدم الوسائط، وما إلى ذلك. إذا ذهبت إلى النطاق، فسيوجهك ببساطة إلى المنتدى.

لدي دليل يقدم ردودًا من نوع SVG لطلبات GET. على سبيل المثال (وليس الرابط الحقيقي) https://moversmindset.com/foo/bar.php

في سمة Discourse الخاصة بي، أقوم بتجربة كود سكريبت (سيصبح في النهاية إضافة رسمية). إنه يستدعي api.decorateCooked() على عناصر DIV محددة تحتوي على data-custom مضافة إليها. لذا، داخل الدالة التي تستدعيها decorateCooked()، أقوم بما يعادل:

$.get(‘https://moversmindset.com/foo/bar.php’ … bla bla blah

لذا، أريد استرجاع ملف SVG ثم إضافته إلى DOM. لكن وحدة تحكم متصفح الخطأ تقول:

السؤال:

هل هذا يعني أنه عليّ تكوين CORS على تثبيت Discourse أم على Apache/WordPress؟

أنا أقوم بالفعل بتكوين https://moversmindset.com كعنوان مسموح به في CORS على Discourse.

إعجابَين (2)

أعتقد أنه على الجانب الآخر. هل يمكنك إلقاء نظرة على Access-Control-Allow-Origin header - HTTP | MDN إذا لم تكن قد فعلت ذلك بعد، ورؤية ما إذا كان ذلك يمنحك أي تلميحات؟

4 إعجابات

خطوات صغيرة جدًا، لكن نعم!

اضطررت إلى إضافة رأس Access-Control-Allow-Origin على خادم Apache/WordPress. وهذا جعل الجافا سكريبت (المستمدة من منصة Discourse) سعيدة. شكرًا لك.

3 إعجابات

استمررتُ في فهم هذا الأمر ببطء. يتطلب هذا السؤال إعدادًا كبيرًا:

SVG

لدي خادم ويب يولد ملفات SVG. وفي هذا السؤال، يولد ملف SVG بسيط جدًا للتجربة…

<svg xmlns="http://www.w3.org/2000/svg" stroke-linejoin="round" viewBox="0 0 100 100">
<path d="M50,4L4,50L50,96L96,50Z" stroke="#40638C" stroke-width="3"></path>
<path d="M50,5L5,50L50,95L95,50Z" stroke="#333" fill="#40638C" stroke-width="3"></path>
<path d="M37,42c-1,0,11-20,13-20c1,0,15,20,13,20h-9c0,8,9,22,12,25l-4,4l-8,-7v13h-10v-35z" stroke="#40495E" fill="#40495E"></path>
<path d="M35,40c-1,0,11-20,13-20c1,0,15,20,13,20h-9c0,8,9,22,12,25l-4,4l-8,-7v13h-10v-35z" stroke="#333" fill="#555"></path>
</svg>

إنه مجرد رمز “دمج” بمظهر فخم. لاحظ أنه يحتوي على أربعة عناصر PATH.

التضمين (Inlining)

لدمج ملف SVG في منشور، أستخدم بعضًا من كود JavaScript المضاف عبر قالب موقعي.

الهدف النهائي هو إنشاء إضافة (plugin) مناسبة. لكنني أحاول فقط بناء نموذج أولي (proof-of-concept). لذا فقد تم لصقه ببساطة في قسم <head> من تخصيص القالب الخاص بي:

<script type="text/discourse-plugin" version="0.8">
var UMB = {
    svgload: function(base, target) {
        var url = base + $(target).text();
        $(target).html('');
        $.ajax({
            method: "GET",
            url: url,
            async: false,
            dataType: "text",
            success: function(data) { $(target).append(data); }
        });
        alert('تم التحميل!');
        $(target).children('path').each(function(){alert('هنا عنصر path');});
    },
}
$.fn.umbdv = function() {
    this.each(
        function() {
            UMB.svgload('__URL_REDACTED__', this);
        }
    );
    return this;
};
api.decorateCooked(
  $elem => $elem.children('.cooked div[data-custom="umbdv"]').umbdv(),
  { id: 'umbdv' }
);
</script>

حيث…

var UMB = { هو مجرد متغير عام (global variable) لتجنب وجود دوال مجهولة ضخمة في كل مكان.

$.fn.umdv = هي ما أعتقد أنه يُسمى “إضافة” (plugin) توسع مكتبة JQuery.

api.decorateCooked( تتيح لي التلاعب بالمنشور قبل إرساله إلى المتصفح.

العبارة السحرية (Incantation)

في موضوع ما، أكتب بعد ذلك…

<div data-custom="umbdv">/vtest</div>

يتم استدعاء UMB.svgload('__URL_REDACTED__', this) لهذا الـ DIV.

تفهم UMB.svgload() بشكل صحيح سلسلة /vtest، وتكوّن عنوان URL وتقوم بطلب AJAX. تنجح في تنفيذ append(data) وboop يظهر ملف SVG مدمجًا داخل المنشور…

ثم يتم تشغيل alert() الخاص بي داخل UMB.svgload()، تمامًا كما هو متوقع. (من الواضح أنها حيلة تصحيح أخطاء، أليس كذلك؟ :))

السؤال (أخيرًا)

لدي موضوع خاص بالموظفين فقط في منتدى Discourse المضيف لدي حيث يمكنك رؤية هذا في العمل. (أتحدث إلى موظفي دعم Discourse الذين يمكنهم الدخول إلى تثبيتتي كمسؤولين.)

https://forum.moversmindset.com/t/svg-experimentation-in-progress/1109

لماذا لا…

$(target).children('path').each(function(){alert('هنا عنصر path');});

…يحدد أيًا من عناصر PATH؟

لا يفعل شيئًا—لا توجد أخطاء. لا شيء.

الخطوة التالية

إلى أين سأذهب إذا نجحت في جعل هذا alert() البسيط كنموذج أولي يعمل…

أدرك أن جزء الـ DOM الذي أعمل عليه “ليس بعد” متصلًا بـ DOM المستند الفعلي (في النقطة التي يتم فيها استدعاء UMB.svgload()). لهذا السبب أتوقع أن يكون $(target)… هو ما أحتاجه.

في النهاية، سأقوم بتضمين ملفات SVG أكثر تعقيدًا بكثير، وسأحتاج إلى استخدام محددات JQuery أكثر تعقيدًا. أريد العثور على العديد من العناصر داخل $(target) وإضافة معالجات للأحداث (مثل onclick) التي ستدعو وظائف عامة أخرى UMB.….

إعجاب واحد (1)

يمكن للإطارات المضمنة (Iframes) تغيير التنقل على المستوى الأعلى إذا أردت ذلك

http://w3c-test.org/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation_by_user_activation-manual.html

3 إعجابات

شكرًا على النصيحة!

لكنني أفضل الآن استخدام SVG المضمن.

بغضّ النظر. بعد أسابيع، هذا لا يعمل.

لا يبدو من الممكن التلاعب بعناصر SVG في DOM بمجرد تضمينها في المستند الرئيسي. لذا لا أستطيع معرفة كيفية إضافة محفزات أو إجراءات للأحداث (وهو ما يمكن فعله بسهولة عبر onclick وما شابه إذا تم تحميل SVG داخل إطار iframe).

((لم يكن استخدام إطار iframe هو هدفي أصلاً.))

¯\_(ツ)_/¯

إعجاب واحد (1)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.