سؤال

من المفترض أن يقوم JavaScript التالي بقراءة العلامات الشائعة من ملف XML وتطبيق ورقة أنماط XSL والإخراج على المتصفح بتنسيق HTML.

function ShowPopularTags() {
   xml = XMLDocLoad("http://localhost/xml/tags/popular.xml?s=94987898");
   xsl = XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");
   if (window.ActiveXObject) {
      // code for IE
      ex = xml.transformNode(xsl);
      ex = ex.replace(/\\/g, "");
      document.getElementById("popularTags").innerHTML = ex;
   } else if (document.implementation && document.implementation.createDocument) {
      // code for Mozilla, Firefox, Opera, etc.
      xsltProcessor = new XSLTProcessor();
      xsltProcessor.importStylesheet(xsl);
      resultDocument = xsltProcessor.transformToFragment(xml, document);
      document.getElementById("popularTags").appendChild(resultDocument);
      var ihtml = document.getElementById("popularTags").innerHTML;
      ihtml = ihtml.replace(/\\/g, "");
      document.getElementById("popularTags").innerHTML = ihtml;
   }
}
ShowPopularTags();

المشكلة في هذا البرنامج النصي هي أنه في بعض الأحيان يتمكن من إخراج كود HTML الناتج، وفي أحيان أخرى لا يفعل ذلك.هل يعرف أحد أين يحدث الخطأ؟

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

المحلول

هل أنت مجبر على استخدام الحل المتزامن الذي تستخدمه الآن، أم أن الحل غير المتزامن يعد خيارًا أيضًا؟أذكر أن Firefox كان لديه نصيبه من المشكلات المتعلقة بالمكالمات المتزامنة في الماضي، ولا أعرف مقدار ما لا يزال يحمله معه.لقد رأيت حالات يتم فيها قفل واجهة Firefox بأكملها طالما كان الطلب قيد التشغيل (والذي قد يستغرق وقتًا طويلاً جدًا، اعتمادًا على إعدادات المهلة).

قد يتطلب الأمر المزيد من العمل من جانبك، ولكن الحل سيكون كالتالي.هذا هو الكود الذي أستخدمه للتعامل مع عناصر XSLT مع Ajax (أعد كتابته قليلاً لأن الكود الخاص بي موجه للكائنات ويحتوي على حلقة تقوم بتوزيع مستند XSL المناسب من مستند XML الذي تم تحميله لأول مرة)

ملحوظة:تأكد من إعلان إصدار oCurrentRequest وoXMLRequest الخاص بك خارج الوظائف، حيث سيتم ترحيله.

if (window.XMLHttpRequest)
{
  oCurrentRequest = new XMLHttpRequest();
  oCurrentRequest.onreadystatechange = processReqChange;
  oCurrentRequest.open('GET', sURL, true);
  oCurrentRequest.send(null);
}
else if (window.ActiveXObject)
{
  oCurrentRequest = new ActiveXObject('Microsoft.XMLHTTP');
  if (oCurrentRequest)
  {
    oCurrentRequest.onreadystatechange = processReqChange;
    oCurrentRequest.open('GET', sURL, true);
    oCurrentRequest.send();
  }
}

بعد ذلك ستحتاج فقط إلى وظيفة تسمى ProcessReqChange تحتوي على شيء مثل ما يلي:

function processReqChange()
{
  if (oCurrentRequest.readyState == 4)
  {
    if (oCurrentRequest.status == 200)
    {
      oXMLRequest = oCurrentRequest;
      oCurrentRequest = null;
      loadXSLDoc();
    }
  }
}

وبالطبع ستحتاج إلى إنتاج مجموعة ثانية من الوظائف للتعامل مع تحميل XSL (بدءًا منloadXSLDoc، على سبيل المثال).

ثم في نهاية عملية معالجةXSLReqChange، يمكنك الحصول على نتيجة XML ونتيجة XSL وإجراء التحويل.

نصائح أخرى

حسنًا، يتبع هذا الرمز مسارات مختلفة تمامًا لـ IE وكل شيء آخر.أعتقد أن المشكلة تقتصر على واحد منهم.ما هي المتصفحات التي جربتها وما هي المتصفحات التي تظهر هذا الخطأ؟

الشيء الآخر الوحيد الذي يمكنني التفكير فيه هو أن عنصر PopularTags قد لا يكون موجودًا عندما تحاول القيام بأشياء به.كيف يتم تنفيذ هذه الوظيفة؟في حدث onload/domready؟

دان.يقوم IE بتنفيذ البرنامج النصي دون أي مشكلة.أواجه المشكلة في فايرفوكس.يوجد عنصر PopularTags في مستند HTML الذي يستدعي الوظيفة.

<div id="popularTags" style="line-height:18px"></div>
<script language="javascript" type="text/javascript">
    function ShowPopularTags()
    {
        xml=XMLDocLoad("http://localhost/xml/tags/popular.xml?s=29497105");
        xsl=XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");

        if (window.ActiveXObject){
            // code for IE
            ex=xml.transformNode(xsl);
            ex = ex.replace(/\\/g, "");
            document.getElementById("popularTags").innerHTML=ex;
        }
        else if (document.implementation && document.implementation.createDocument){
            // code for Mozilla, Firefox, Opera, etc.
            xsltProcessor=new XSLTProcessor();
            xsltProcessor.importStylesheet(xsl);
            resultDocument = xsltProcessor.transformToFragment(xml,document);
            document.getElementById("popularTags").appendChild(resultDocument);

            var ihtml = document.getElementById("popularTags").innerHTML;
            ihtml = ihtml.replace(/\\/g, "");
            document.getElementById("popularTags").innerHTML = ihtml;
         }
    }

    ShowPopularTags();
</script>    

لتجنب مشاكل تحميل الأشياء بالتوازي (كما ألمح دان)، من الجيد دائمًا استدعاء مثل هذه البرمجة النصية فقط عندما يتم تحميل الصفحة بالكامل.

من الناحية المثالية، يمكنك وضع علامات البرنامج النصي في رأس الصفحة واستدعاء ShowPopularTags();في الجسم Onload البند.أي.

<BODY onLoad="ShowPopularTags();">

بهذه الطريقة تكون متأكدًا تمامًا من أن document.getElementById("popularTags") الخاص بك لن يفشل لأنه يتم استدعاء البرمجة النصية قبل تحميل HTML الذي يحتوي على العنصر بالكامل.

أيضًا، هل يمكننا رؤية وظيفة XMLDocLoad الخاصة بك؟إذا كان ذلك يحتوي على عناصر غير متسلسلة أيضًا، فقد تواجه مشكلة حيث يحدث تحويل XSLT قبل تحميل الكائنات xml وxsl بالكامل.

التالية هي الدالة XMLDocLoad.

function XMLDocLoad(fname)
{
    var xmlDoc;

    if (window.ActiveXObject){
        // code for IE
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async=false;
        xmlDoc.load(fname);

        return(xmlDoc);
    }
    else if(document.implementation && document.implementation.createDocument){
        // code for Mozilla, Firefox, Opera, etc.
        xmlDoc=document.implementation.createDocument("","",null);

        xmlDoc.async=false;
        xmlDoc.load(fname);

        return(xmlDoc);

    }
    else{
        alert('Your browser cannot handle this script');
    }


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