2009-12-03 5 views
27

В настоящее время я расширяю lavalamp plugin, чтобы работать с выпадающими меню, но у меня возникла небольшая проблема. Мне нужно знать offsetWidth скрытого элемента. Теперь ясно, что этот вопрос не имеет смысла, скорее то, что я ищу, это элемент offsetWidth элемента, если он не скрыт.Найти «потенциальную» ширину скрытого элемента

Это решение, чтобы показать его, захватить ширину, а затем снова спрятать? Должен быть лучший способ ...

ответ

34

Единственное, что я могу придумать, это показать его (или его клон), чтобы разрешить поиск offsetWidth.

Для этого шага измерения просто сделайте свое положение абсолютным, а его значение x или y - большим отрицательным, поэтому оно будет отображаться, но не быть видимым для пользователя.

+0

Nice один, Питер. Благодарю. – Gausie

+0

Вот сообщение в блоге по этой теме. Одной из проблем, с которой может столкнуться этот метод, является возврат позиции обратно к исходному значению. Использование метода подкачки хорошо работает в этой ситуации. http://bit.ly/6KwGzm –

+1

Вам не нужно возвращать его обратно в исходное положение, если вы клонируете элемент. Просто удалите клон после того, как вы восстановили его положение. – ajbeaven

27

Ширина элемента с CSS visibility: hidden измерима. Только когда это display: none, он не отображается вообще. Поэтому, если это определенно, элементы будут абсолютно позиционированы (поэтому они не вызывают изменение макета при отображении), просто используйте css('visibility', 'hidden'), чтобы скрыть свой элемент вместо hide(), и вы должны быть в порядке, измеряя ширину.

В противном случае да, шоу-мера-скрыть действительно работает.

0

это потому, что его скрытый экран: нет; Что было сделано в прошлом, так это сделать «приемник», который я использую для абсолютного позиционирования, чтобы вытащить его из страницы. Затем я загружаю новый элемент в это, захватываю размеры и затем удаляю его, когда им сделали - затем удалите приемник, когда он сделан.

Другая вещь, которую вы можете сделать, - не использовать hide(); но вместо этого установить видимость: hidden; display:; Однако это означает, что пустая область будет отображаться везде, где прикреплен узел.

2

два варианта:

  1. положение элемента вне видового экрана (например: left:-10000px)
  2. использование visibility: hidden или opacity: 0 вместо hide().

В любом случае это будет работать как скрывающий элемент, но все же способный вычислить ширину. Будьте осторожны с Safari на thi, это ужасно быстро, а иногда и слишком быстро ...

11

Вы можете использовать следующую функцию, чтобы получить внешнюю ширину элемента, который равен внутри скрытого контейнера.

$.fn.getHiddenOffsetWidth = function() { 
    // save a reference to a cloned element that can be measured 
    var $hiddenElement = $(this).clone().appendTo('body'); 

    // calculate the width of the clone 
    var width = $hiddenElement.outerWidth(); 

    // remove the clone from the DOM 
    $hiddenElement.remove(); 

    return width; 
}; 

Вы можете изменить .outerWidth() к .offsetWidth() для вашей ситуации.

Функция сначала клонирует элемент, копируя его в место, где оно будет видно. Затем он извлекает ширину смещения и, наконец, удаляет клон. Следующий фрагмент кода иллюстрирует ситуацию, когда эта функция была бы идеальным:

<style> 
    .container-inner { 
     display: none; 
    } 

    .measure-me { 
     width: 120px; 
    } 
</style> 

<div class="container-outer"> 
    <div class="container-inner"> 
     <div class="measure-me"></div> 
    </div> 
</div> 

Пожалуйста, обратите внимание, что если есть CSS применяется к элементу, который изменяет ширину элемента, который не будет применяться, если это является прямым потомком тела, то этот метод не будет работать.Так что-то, как это будет означать, что функция не работает:

.container-outer .measure-me { 
    width: 100px; 
} 

Вы будете должны:

  • изменения специфичности, т.е. селектора CSS. .measure-me { width: 100px; }
  • изменить appendTo(), чтобы добавить клон в место, где ваш CSS также будет применен к клону. Убедитесь в том, что когда-либо вы выразились, что элемент будет виден: .appendTo('.container-outer')

Опять же, эта функция предполагает, что элемент скрыт только потому, что внутри скрытого контейнера. Если сам элемент равен display:none, вы можете просто добавить некоторый код, чтобы сделать клон видимым, прежде чем извлекать его ширину смещения. Что-то вроде этого:

$.fn.getHiddenOffsetWidth = function() { 
    var hiddenElement $(this) 
     width = 0; 

    // make the element measurable 
    hiddenElement.show(); 

    // calculate the width of the element 
    width = hiddenElement.outerWidth(); 

    // hide the element again 
    hiddenElement.hide(); 

    return width; 
} 

Это будет работать в такой ситуации, как это:

<style> 
    .measure-me { 
     display: none; 
     width: 120px; 
    } 
</style> 

<div class="container"> 
    <div class="measure-me"></div> 
</div> 
+1

Интересно, но это не сработает с каким-либо унаследованием стиля, или спроектированным контейнером. –

+0

Да, как упоминалось в моем ответе. Есть несколько предложений, чтобы обойти это, но я согласен, это не идеально. – ajbeaven

0

Я пытаюсь найти рабочую функцию для скрытого элемента, но я понимаю, что CSS гораздо сложен, чем все думают. В CSS3 существует много новых методов компоновки, которые могут не работать для всех предыдущих ответов, таких как гибкая коробка, сетка, столбец или четный элемент внутри сложного родительского элемента.

пример flexibox enter image description here

Я думаю, что единственное устойчивое & простое решение рендеринг в реальном времени. В то время браузер должен предоставить вам правильный размер элемента.

К сожалению, JavaScript не предоставляет никаких прямых уведомлений о том, когда элемент отображается или скрыт. Однако я создаю некоторую функцию, основанную на DOM Attribute Modified API, которая будет выполнять функцию обратного вызова при изменении видимости элемента.

$('[selector]').onVisibleChanged(function(e, isVisible) 
{ 
    var realWidth = $('[selector]').width(); 
    var realHeight = $('[selector]').height(); 

    // render or adjust something 
}); 

Для получения дополнительной информации, пожалуйста, посетите мой проект GitHub.

https://github.com/Soul-Master/visible.event.js

демо: http://jsbin.com/ETiGIre/7

0

То, что я сделал; , скрывая этот элемент, сохранил его ширину в своем наборе данных. Это будет работать только для вас, если вы можете скрыть программно.

ie.

Когда скрывается;

var elem = $("selectorOfElement"); 

elem.dataset.orgWidth = elem.clientWidth; 

Позже при получении;

var elem = $("selectorOfElement"); 

var originalWidthWas = elem.dataset.orgWidth; 
1

Actual jQuery plugin!

Использование:

console.log('width without actual: ' + $('#hidden').width()); 
 

 
console.log('width with actual: ' + $('#hidden').actual('width'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.actual/1.0.19/jquery.actual.min.js"></script> 
 

 
<div style="width: 100px; display: none;"> 
 
    <div id="hidden"></div> 
 
</div>

Смежные вопросы