meaning - script type= text/javascript




تحقق مما إذا كان العنصر مرئيًا في DOM (11)

هل هناك أي طريقة لأتمكن من التحقق مما إذا كان العنصر مرئيًا في JS (لا jQuery)؟

لذلك ، على سبيل المثال ، في هذه الصفحة: Performance Bikes ، إذا قمت بالمرور فوق الصفقات (في القائمة العلوية) ، تظهر نافذة الصفقات ، ولكن في البداية لم يتم عرضها. هو في HTML لكنه غير مرئي.

إذاً ، في ضوء عنصر DOM ، كيف يمكنني التحقق مما إذا كان مرئيًا أم لا؟ لقد حاولت: window.getComputedStyle(my_element)['display']); لكن يبدو أنه لا يعمل. أتساءل ما هي الصفات التي يجب أن أتحقق منها. يتبادر إلى ذهني:

display !== 'none'
visibility !== 'hidden'

أي شخص آخر قد أكون في عداد المفقودين؟


إذا كان العنصر مرئيًا بشكل منتظم (العرض: block و visibillity: visible) ، ولكن تم إخفاء بعض الحاويات الرئيسية ، فيمكننا استخدام العميل والعميل للتحقق من ذلك.

function isVisible (ele) {
  return  ele.clientWidth !== 0 &&
    ele.clientHeight !== 0 &&
    ele.style.opacity !== 0 &&
    ele.style.visibility !== 'hidden';
}

بلانكر (انقر هنا)


إذا كنا نجمع فقط الطرق الأساسية للكشف عن الرؤية ، فلا يجب أن أنسى:

opacity > 0.01; // probably more like .1 to actually be visible, but YMMV

وحول كيفية الحصول على السمات:

element.getAttribute(attributename);

لذلك ، في المثال الخاص بك:

document.getElementById('snDealsPanel').getAttribute('visibility');

لكن وها؟ لا يعمل هنا. ابحث عن أقرب وستجد أن مستوى الرؤية لا يتم تحديثه على أنه سمة على العنصر ، ولكن باستخدام خاصية style . هذا هو واحد من العديد من المشاكل في محاولة القيام بما تفعلونه. من بين أمور أخرى: لا يمكنك ضمان أن هناك بالفعل شيء يمكن رؤيته في عنصر ، فقط لأن الرؤية ، والعرض ، والعتامة تحتوي جميعها على القيم الصحيحة. قد يفتقر إلى المحتوى ، أو قد ينقصه ارتفاع وعرض. كائن آخر قد يحجبها. لمزيد من التفاصيل ، يكشف بحث Google سريع عن this ، ويتضمن حتى مكتبة لمحاولة حل المشكلة. (YMMV)

تحقق من ما يلي ، وهي نسخ مكررة محتملة من هذا السؤال ، مع إجابات ممتازة ، بما في ذلك بعض الأفكار من الأقوياء جون Resig. ومع ذلك ، فإن حالة الاستخدام المحددة الخاصة بك تختلف قليلاً عن الحالة القياسية ، لذلك سأمتنع عن الإبلاغ:

(تحرير: OP يقول صفحات الخاتمة HE ، وليس خلقها ، لذلك لا ينطبق أدناه) خيار أفضل؟ ربط رؤية عناصر لخصائص النموذج ودائما جعل الرؤية متوقفة على هذا النموذج ، مثلما يفعل Angular مع ng-show. يمكنك القيام بذلك باستخدام أي أداة تريدها: JS Angular ، عادي ، أيا كان. والأفضل من ذلك ، يمكنك تغيير تنفيذ DOM بمرور الوقت ، ولكن ستتمكن دائمًا من قراءة الحالة من النموذج ، بدلاً من DOM. قراءة حقيقتك من DOM أمر سيء. وبطيئة. من الأفضل التحقق من النموذج ، والثقة في التنفيذ لضمان أن حالة DOM تعكس النموذج. (واستخدم الاختبار التلقائي لتأكيد هذا الافتراض.)


إضافة صغيرة إلى إجابة ohad navon.

إذا كان مركز العنصر ينتمي إلى عنصر آخر فلن نجده.

لذلك تأكد من أن إحدى نقاط العنصر هي مرئية

function isElementVisible(elem) {
    if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an element.');
    const style = getComputedStyle(elem);
    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if (style.opacity === 0) return false;
    if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0) {
        return false;
    }
    var elementPoints = {
        'center': {
            x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
            y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
        },
        'top-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().top
        },
        'top-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().top
        },
        'bottom-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().bottom
        },
        'bottom-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().bottom
        }
    }

    for(index in elementPoints) {
        var point = elementPoints[index];
        if (point.x < 0) return false;
        if (point.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
        if (point.y < 0) return false;
        if (point.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
        let pointContainer = document.elementFromPoint(point.x, point.y);
        if (pointContainer !== null) {
            do {
                if (pointContainer === elem) return true;
            } while (pointContainer = pointContainer.parentNode);
        }
    }
    return false;
}

إليك الرمز الذي كتبته للعثور على المرئي الوحيد بين بعض العناصر المتشابهة ، وإرجاع قيمة السمة "class" الخاصة به بدون jQuery:

  // Build a NodeList:
  var nl = document.querySelectorAll('.myCssSelector');

  // convert it to array:
  var myArray = [];for(var i = nl.length; i--; myArray.unshift(nl[i]));

  // now find the visible (= with offsetWidth more than 0) item:
  for (i =0; i < myArray.length; i++){
    var curEl = myArray[i];
    if (curEl.offsetWidth !== 0){
      return curEl.getAttribute("class");
    }
  }

الجمع بين إجابات زوجين أعلاه:

function isVisible (ele) {
    var style = window.getComputedStyle(ele);
    return  style.width !== 0 &&
    style.height !== 0 &&
    style.opacity !== 0 &&
    style.display!=='none' &&
    style.visibility!== 'hidden';
}

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

ولكنه يعتمد أيضًا على ما هو مرئي بالنسبة إليك. على سبيل المثال ، يمكن ضبط ارتفاع div إلى 0px ولكن تظل المحتويات مرئية بناءً على خصائص تجاوز السعة. أو يمكن إنشاء محتويات div بنفس لون الخلفية بحيث لا تكون مرئية للمستخدمين ولكنها لا تزال تظهر على الصفحة. أو يمكن نقل عنصر div من الشاشة أو إخفائه خلف الأقسام الأخرى ، أو قد تكون المحتويات غير مرئية ولكن لا تزال الحدود مرئية. إلى حد ما "مرئية" هو مصطلح ذاتي.


جميع الحلول الأخرى تحطمت لبعض الأوضاع بالنسبة لي ..

انظر الجواب الفائز كسر في:

http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview

في النهاية ، قررت أن أفضل حل هو $(elem).is(':visible') - ومع ذلك ، هذه ليست javascript محض. هذا هو jquery ..

لذلك نظرت إلى منبعهم ووجدت ما أريد

jQuery.expr.filters.visible = function( elem ) {
    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

هذا هو المصدر: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js


لقد حصلت على حل أكثر أداءً مقارنةً بحل getComputedStyle () الخاص بـ AlexZ عندما يكون لدى أحد العناصر "الثابتة" للموضع ، إذا كان أحدهم على استعداد لتجاهل بعض الحواف (راجع التعليقات):

function isVisible(el) {
    /* offsetParent would be null if display 'none' is set.
       However Chrome, IE and MS Edge returns offsetParent as null for elements
       with CSS position 'fixed'. So check whether the dimensions are zero.

       This check would be inaccurate if position is 'fixed' AND dimensions were
       intentionally set to zero. But..it is good enough for most cases.*/
    if (!el.offsetParent && el.offsetWidth === 0 && el.offsetHeight === 0) {
        return false;
    }
    return true;
}

ملاحظة جانبية: بالمعنى الدقيق للكلمة ، يجب تعريف "الرؤية" أولاً. في حالتي ، أفكر في عنصر مرئي ما دام بإمكاني تشغيل جميع أساليب / خصائص DOM عليه دون مشاكل (حتى إذا كانت العتامة 0 أو خاصية رؤية CSS "مخفية" إلخ).


ما وجدته هو الطريقة الأكثر جدوى:

function visible(elm) {
  if(!elm.offsetHeight && !elm.offsetWidth) { return false; }
  if(getComputedStyle(elm).visibility === 'hidden') { return false; }
  return true;
}

هذا يعتمد على هذه الحقائق:

  • display: none عنصر واحد (حتى متداخلة) ليس له عرض أو ارتفاع.
  • يتم hidden visiblity حتى بالنسبة للعناصر المتداخلة.

لذلك لا حاجة إلى اختبار offsetParent أو التكرار في شجرة DOM لاختبار أي من الأبوين لديه visibility: hidden . يجب أن يعمل هذا حتى في IE 9.

يمكنك أن تجادل إذا كانت opacity: 0 والعناصر المنهارة (لها عرض ولكن ليس ارتفاعًا - أو العكس بالعكس) ليست مرئية حقًا أيضًا. ولكن مرة أخرى هم ليسوا كلهم ​​مخفيين القول.


هذه طريقة لتحديدها لجميع خصائص css بما في ذلك الرؤية:

أتش تي أم أل:

<div id="element">div content</div>

المغلق:

#element
{
visibility:hidden;
}

جافا سكريبت:

var element = document.getElementById('element');
 if(element.style.visibility == 'hidden'){
alert('hidden');
}
else
{
alert('visible');
}

يعمل لأي خاصية css وهو متعدد الاستخدامات وموثوق به للغاية.


وفقًا لوثائق MDN هذه ، ستعود خاصية offsetParent للعنصر عندما يتم إخفاءه ، أو أي من والديه ، عبر خاصية نمط العرض. فقط تأكد من عدم إصلاح العنصر. برنامج نصي للتحقق من هذا ، إذا لم يكن لديك "موقف: ثابت" العناصر في صفحتك ، قد تبدو كما يلي:

//Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    return (el.offsetParent === null)
}

من ناحية أخرى ، إذا كان لديك عناصر ثابتة في الموقع قد يتم window.getComputedStyle() في هذا البحث ، فسيكون من المحزن (وببطء) استخدام window.getComputedStyle() . قد تكون الوظيفة في هذه الحالة كما يلي:

//Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    var style = window.getComputedStyle(el);
    return (style.display === 'none')
}

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


قد يساعد هذا في: إخفاء العنصر بوضعه على أقصى اليسار ، ثم تحقق من الخاصية offsetLeft. إذا كنت تريد استخدام jQuery ، فيمكنك ببساطة التحقق من :visible المحدد :visible والحصول على حالة رؤية العنصر.

HTML:

<div id="myDiv">Hello</div>

CSS:

<!-- for javaScript-->
#myDiv{
   position:absolute;
   left : -2000px;
}

<!-- for jQuery -->
#myDiv{
    visibility:hidden;
}

جافا سكريبت:

var myStyle = document.getElementById("myDiv").offsetLeft;

if(myStyle < 0){
     alert("Div is hidden!!");
}

jQuery:

if(  $("#MyElement").is(":visible") == true )
{  
     alert("Div is hidden!!");        
}

jsFiddle







dom