Jsdom: offsetWidth و offsetHeight و offsetTop و offsetLeft

تم إنشاؤها على ١ فبراير ٢٠١١  ·  32تعليقات  ·  مصدر: jsdom/jsdom

أحاول تطبيق عارض من جانب الخادم لـ HighCharts. يبدو أن كل شيء يعمل بشكل جيد باستثناء علامات SVG الناتجة التي تفتقد قيم x و y و width و height في كل مكان. من خلال بعض التصحيح أعتقد أنني حددت المشكلة إلى حقيقة أن offsetWidth و offsetHeight و offsetTop و offsetLeft كلها غير محددة لكل عنصر.

هل من المقرر تضمين هذه الخصائص في إصدار مستقبلي؟ أيضًا ، هل هناك حل بديل يمكنني تنفيذه في الوقت الحالي؟

css feature layout needs tests

التعليق الأكثر فائدة

أستخدم هذا المقتطف للدعم ، والذي يعمل مع حالتي. ضع في اعتبارك أنه بعيد كل البعد عن التنفيذ السليم. لاحظ أن window يجب أن يكون document.parentWindow الخاص بك.

إذا كنت بحاجة إلى تطبيق أفضل ، فقم بتوسيع الكود باستخدام المواصفات:
http://dev.w3.org/csswg/cssom-view/#dom -htmlelement-offsetleft

Object.defineProperties(window.HTMLElement.prototype, {
  offsetLeft: {
    get: function() { return parseFloat(window.getComputedStyle(this).marginLeft) || 0; }
  },
  offsetTop: {
    get: function() { return parseFloat(window.getComputedStyle(this).marginTop) || 0; }
  },
  offsetHeight: {
    get: function() { return parseFloat(window.getComputedStyle(this).height) || 0; }
  },
  offsetWidth: {
    get: function() { return parseFloat(window.getComputedStyle(this).width) || 0; }
  }
});

ال 32 كومينتر

أعتقد أن http://www.w3.org/TR/cssom-view/ ، يجب أن يتم تنفيذه.

لقد بدأنا في دمج ملف cssom والذي يجب أن يحل بعض مشكلات SVG.

سيكون رائعًا حقًا إذا تمكنا من الوصول إلى خصائص الإزاحة * ، التي سنحتاج إليها لمشروع متعلق بالقماش.

كيف هو التقدم في هذه القضية؟ سأكون ممتنًا أيضًا لمثل هذه الميزة لتقديم الخلفية المتأرجحة باستخدام Highcharts.

أحب أن أحصل على هذا أيضًا :)

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

tmpvar : أود المساعدة ، لكنني جديد جدًا على عناصر JS من جانب الخادم.
ربما يمكنك أن تلمحني من أين أبدأ ويمكنني أن أبذل قصارى جهدي للحصول على شيء ما :)

أنا مهتم جدًا بـ SVG 1.1 أيضًا ، لتمكين الرسوم البيانية العالية على الخادم. أود تقديم المساعدة ، لكن أولاً يجب أن أتعرف على SVG 1.0 وتطبيقه الحالي في jsdom ، والذي قد يستغرق بعض الوقت ؛)

أعتقد أن الخطوة الأولى هنا هي الحصول على نسخة من مجموعة الاختبار (http://www.w3.org/Graphics/SVG/WG/wiki/Test_Suite_Overview) وتحويلها إلى بدون رأس (وهو ما قد يكون مهمة تمامًا)

ثم يمكننا إضافة level2/svg.js والبدء في التنفيذ.

من المحتمل أن أتطرق إلى هذا في النهاية ، لكنه ليس على رأس قائمة أولوياتي في jsdom في الوقت الحالي.

href فإن تنفيذ svg 1.0 مكشوف تمامًا. يجتاز الاختبارات في level1/core ولكنه لا يقوم بتنفيذ أي شيء محدد svg.

أعتقد أن getBoundingCLientRect لم يتم تنفيذه بشكل صحيح.

لدي هذا الرمز لحساب عنصر svg معين:

var html = '<!DOCTYPE html><html><head><title></title></head><body style="margin: 0; padding: 0;"><svg id="svg" xmlns="http://www.w3.org/2000/svg" version="1.1" style="margin: 0; padding: 0;"><rect style="" x="10" y="10" width="100" height="100" rx="0" ry="0"/></svg></body></html>';

        jsdom.env({
            html : html,
            src: [jquery],
            done: function (errors, window) {
                var $ = window.$;
                var clientBox = $("#svg").find(type)[0].getBoundingClientRect();
                console.log(clientBox);
            }
        });

والنتيجة هي:

{ bottom: 0, height: 0, left: 0, right: 0, top: 0, width: 0 }

ولكن ، إذا اختبرت نفس لغة html في متصفح الويب ، فستكون النتيجة كالتالي:

{ bottom: 110, height: 100, left: 10, right: 110, top: 10, width: 100 }

@ throrin19 : اقرأ حتى # 653.

إذن من المستحيل تحقيقه؟ تمكنت حتى الآن من تجاوز هذا القلق من خلال phantomJS ولكنه بطيء للغاية وإذا كان لدي SVG كبير ، فإنه يتعطل.

أعني ، هذا ليس مستحيلًا ، لكن علينا كتابة محرك تخطيط كامل ، ولم يكن لدى أحد الوقت للقيام بذلك.

لقد فكرت في الأمر ، ولكن بعد ذلك تقلصات دماغي ويجب أن أذهب بعيدًا.

هل هناك اختبارات تتجاوز الحمض يمكن اتباعها؟

+1 في العثور على هذه الميزة المرغوبة للغاية

أستخدم هذا المقتطف للدعم ، والذي يعمل مع حالتي. ضع في اعتبارك أنه بعيد كل البعد عن التنفيذ السليم. لاحظ أن window يجب أن يكون document.parentWindow الخاص بك.

إذا كنت بحاجة إلى تطبيق أفضل ، فقم بتوسيع الكود باستخدام المواصفات:
http://dev.w3.org/csswg/cssom-view/#dom -htmlelement-offsetleft

Object.defineProperties(window.HTMLElement.prototype, {
  offsetLeft: {
    get: function() { return parseFloat(window.getComputedStyle(this).marginLeft) || 0; }
  },
  offsetTop: {
    get: function() { return parseFloat(window.getComputedStyle(this).marginTop) || 0; }
  },
  offsetHeight: {
    get: function() { return parseFloat(window.getComputedStyle(this).height) || 0; }
  },
  offsetWidth: {
    get: function() { return parseFloat(window.getComputedStyle(this).width) || 0; }
  }
});

هل وجد أي شخص آخر النجاح مع ما اقترحه توبيهينلوبين؟

tobyhinloopen :

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

الحل الذي اقترحه tobyhinloopen يبدو جيدًا ولكن عند استخدامه أحصل على "لا يمكن تحسين الخاصية offsetLeft"

zallek أعتقد أن لديك بالفعل دعم offsetLeft ثم :) ماذا يعود window.HTMLElement.prototype.offsetLeft ؟ إذا كان أي شيء غير محدد ، فلن يعمل الحل الخاص بي

أردت فقط أن أقول شكراً tobyhinloopen ، كان

tobyhinloopen شكرا جزيلا لنشر الحل! إنه مفيد للغاية ويعمل طالما أنني أستخدم متغيرًا لتعيين قيمة الإزاحة واستبعاد this . يخرج this غير محدد ، وهو نوع منطقي نظرًا لأن السياق ليس الفئة الفعلية. هل هذا ما تتوقعه؟

jordantomax هذا مرتبط بالعنصر عند استدعاء الوظيفة ، وليس عند تحديد الوظيفة. يجب أن يكون 'this' هو العنصر عند استدعائه من أي عنصر html.

إذا لم يكن الأمر كذلك ، فأنا أحب أن أرى مثالاً.

tobyhinloopen شكرا على الاستجابة السريعة. هذا ما كنت أتوقعه. عندما أحاول إعادة إظهار مشكلتي في codeandbox باستخدام بيئة متصفح حقيقية ، فإنها تعمل بشكل صحيح. ولكن عند استخدام الدعابة ، أرى أن this غير محدد. لقد أنشأت نموذجًا صغيرًا من الريبو لإظهار ما أواجهه ، فربما يكون الإعداد الخاص بي خاطئًا.

https://github.com/jordantomax/jest-htmlelement-prototype-sandbox

ذات صلة ، أواجه أيضًا مشكلات في تجاوز الأساليب مثل scrollIntoView باستخدام jest و jsdom. هل هناك طريقة موصى بها للقيام بذلك؟

شكرا جزيلا لمساعدتكم!

أعتقد أن السبب في ذلك هو أنك تستخدم get: () => {} - يعبث بناء جملة الدالة () => {} مع this . إذا كنت تستخدم get() {} (مستحسن) أو get: function() {} (بديل) بدلاً من ذلك ، فستعمل. تضمين التغريدة

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

يمكنك أيضًا استخدام => في مجموعة الاختبار الخاصة بك it / describe . لا أعرف شيئًا عن JEST ، لكن في MOCHA لا يُنصح بذلك ، نظرًا لأن this في it / test / describe يحتوي على جميع أنواع الأدوات التي لا يمكنك الوصول إليها إذا كنت تستخدم وظائف الأسهم. على سبيل المثال ، تحتوي المخاوي على أشياء مثل this.slow() ، this.timeout(4000) إلخ.

https://mochajs.org/#arrow -الوظائف

ذات صلة ، أواجه أيضًا مشكلات في تجاوز الأساليب مثل scrollIntoView باستخدام jest و jsdom. هل هناك طريقة موصى بها للقيام بذلك؟

عادة ما يكون هناك نوع من polyfill متاح على MDN. بخلاف ذلك ، حاول فقط تنفيذه بناءً على المواصفات بطريقة تناسب احتياجاتك. إذا فشل كل شيء ، فما عليك سوى استخدام بيئة اختبار مختلفة. JSDom له مكانه ، ولكن في مرحلة ما قد ترغب في التفكير في متصفح حقيقي بدلاً من ذلك. تسمح العديد من بيئات الاختبار بالاختبار في المتصفحات الحقيقية (حتى المضاعفات في نفس الوقت) مع الإبلاغ أيضًا عن الوقت الفعلي لجهاز التطوير الخاص بك. يقوم IIRC Karma بهذا -> https://karma-runner.github.io/latest/index.html

لقد فتحت عدة متصفحات (متصفح Firefox chrome safari internet explorer edge + mobile في أجهزة محاكاة) مرة واحدة على جهازي ، وقد أبلغوا جميعًا في الوقت الفعلي باستخدام Karma + Mocha.

tobyhinloopen صحيح أنت على جميع الحسابات! شكرا لك!! ما زلت غير واضح قليلاً حول سبب ضرورة استخدام getComputedStyle ، وهل من الممكن كتابة أداة ضبط في ضوء هذه الطريقة. بالنسبة لي يبدو أن هذا يعمل:

Object.defineProperties(window.HTMLElement.prototype, {
  offsetTop: {
    get () {
      return this.marginTop
    },
    set (offset) {
      this.marginTop = offset
    }
  }
})

شكرا مرة أخرى 🙏

يجلبjordantomax getComputedStyle النمط المحسوب الحقيقي لجميع خصائص CSS ، بغض النظر عن مكان تطبيقه (ورقة الأنماط ، أو سمة style أو من JS). لست متأكدًا مما إذا كان this.marginTop يفعل الشيء نفسه ، لكنني أعتقد أنه يفعل (ولكن للهامش فقط بوضوح ، وليس لجميع دعائم CSS)

tobyhinloopen آه ، فهمت. شكرا لك!

شكرا tobyhinloopen . أنا أستخدم نسخة أقصر. أعتقد أن getComputedStyle ليس مطلوبًا حقًا لأنني شخصيًا لا أضيف أي css إلى اختبارات الوحدة الخاصة بي ما لم تكن مضمنة ، وهذا هو السبب في أن .style جيد بما فيه الكفاية وأسرع.

Object.defineProperties(window.HTMLElement.prototype, {
  offsetLeft: {
    get () { return parseFloat(this.style.marginLeft) || 0 }
  },
  offsetTop: {
    get () { return parseFloat(this.style.marginTop) || 0 }
  },
  offsetHeight: {
    get () { return parseFloat(this.style.height) || 0 }
  },
  offsetWidth: {
    get () { return parseFloat(this.style.width) || 0 }
  }
})

هل تم إصلاح هذا ، سأحصل على offsetWidth = 0

   const dom = new JSDOM(`<!DOCTYPE html><body></body>`);
    let document = dom.window.document
    let span = document.createElement("span");
    span.innerHtml = 'test
    span.style.fontSize = 150 + 'px';
    span.style.fontFamily = 'Arial'
    document.body.appendChild(span)
    console.log(span.offsetWidth) // 0

هل تم إصلاح هذا ، سأحصل على offsetWidth = 0

petran ، ليس من الواقعي توقع jsdom لحساب عرض SPAN الخاص بك ، لأنه يتطلب معرفة حجم الخط وجميع خصائص CSS الموروثة. لا أعتقد أن هذا هو هدف JSDOM. إذا كنت تريد محاكاة أكثر دقة للمتصفح ، ففكر في استخدام متصفح حقيقي.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات