2017-01-16 3 views
0

Я использую этот plugin для создания горизонтальной шкалы времени. Вы можете использовать стрелки влево и вправо, чтобы перемещаться между датами. Щелчок по дате изменит нижний колонтитул на тот, который соответствует той же дате.Как проверить видимость элемента, когда он отображается/скрыт с помощью scaleX()?

Моя проблема заключается в следующем: Я пытаюсь узнать, видны ли определенные даты в текущем окне просмотра. Таким образом, в тех случаях, когда первый плагин загружается, отображаются следующие даты: «16 января», «28 февраля», «20 марта», «20 мая». Когда я нажимаю на стрелку вправо, эти даты заменяются следующими датами: «09 июля», «30 августа», «15 сентября», «01 ноября». Теперь, на данный момент, я хотел бы узнать, например, если дата «16 Ян» видна или нет (в этом случае она не видна).

Поскольку каждая дата добавляется в a элемент, который соответствует каждой дате в виде атрибута data-date можно получить элемент, который я хочу, чтобы проверить с помощью следующего селектора (например, для «16 января»):

$("a[data-date='16/01/2014'");

Теперь для того, чтобы проверить видимость я пытался два различных подхода:

Первый подход (как показано в этом answer)

$("a[data-date='16/01/2014'").is(':visible'); 

Этот подход всегда возвращает меня истине и, следовательно, не работает.

Второй подход (как показано в этом answer)

function isElementInViewport (el) { 

    //special bonus for those using jQuery 
    if (typeof jQuery === "function" && el instanceof jQuery) { 
     el = el[0]; 
    } 

    var rect = el.getBoundingClientRect(); 

    return (
     rect.top >= 0 && 
     rect.left >= 0 && 
     rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ 
     rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ 
    ); 
} 

И потом:

var a = $("a[data-date='16/01/2014'"); 
var b = isElementInViewport(); 

Этот подход всегда возвращает меня истинным и, таким образом, также не работает.

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

Итак, после всего этого мой вопрос заключается в следующем: возможно ли проверить видимость элементов в этом конкретном случае? И если да, то как я могу это сделать?

+0

Можете ли вы добавить флаг переменной на клик, который говорит 'isDateOpen = true'? или что-то типа того? Поскольку у вас уже есть некоторые функции вокруг него. – ntgCleaner

+0

@ntgCleaner Я мог бы, но для этого мне нужно было бы рассчитать ширину, показанную на странице, общую ширину временной шкалы, рассчитать количество страниц, создать структуру данных, которая связывает даты с соответствующей страницей и тогда, когда я нажимаю на стрелку, добавьте свойство к датам, как вы предлагали. Это, однако, мое последнее средство. Я искал что-то более простое. –

ответ

1

Первый подход не работает, потому что элементы фактически «видимым». Следующая строка просто проверяет значение атрибута css visibility, который является «видимым» (значением по умолчанию) для каждого из элементов даты.

$ ("a [data-date = '16/01/2014 '"). Is (': visible ');

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

function isElementInViewport (el) { 

    //special bonus for those using jQuery 
    if (typeof jQuery === "function" && el instanceof jQuery) { 
     el = el[0]; 
    } 

    var rect = el.getBoundingClientRect(); 

    return (
     rect.top >= 0 && 
     rect.left >= 0 && 
     rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ 
     rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ 
    ); 
} 

Обратите внимание, что в приведенном выше коде предполагается, что порт зрения, чтобы быть окно. Это будет полезно, если вы хотите узнать, находится ли элемент за пределами области экрана. Но ваше требование немного отличается. В вашем примере порт представления должен быть контейнером этих элементов даты. Если вы проверите временную шкалу в своем браузере, вы найдете div с классом event-wrapper, на котором все даты скрыты. Таким образом, вы можете изменить вышеуказанную функцию следующим образом:

function isElementReallyInViewport (el) { 

    //special bonus for those using jQuery 
    if (typeof jQuery === "function" && el instanceof jQuery) { 
     el = el[0]; 
    } 

    var rect = el.getBoundingClientRect(); 
    var container = $('.events-wrapper')[0].getBoundingClientRect(); 

    return (
     rect.top >= container.top && 
     rect.left >= container.left && 
     rect.bottom <= container.bottom && 
     rect.right <= container.right 
    ); 
} 

Я испытал это на пару элементов в example, что вы разделили и, кажется, работает хорошо. Надеюсь, это поможет вам.

+0

Спасибо, это именно то, что я искал. Он отлично работал. –

0

Одним из способов было бы сравнить горизонтальные позиции:

function isElementVisible($elOrDate) { 

    var $el = (typeof $elOrDate === "string") ? $("a[data-date='" + $elOrDate + "'") : $elOrDate; 

    // We need the .event-wrapper element of the timeline 
    let $eventWrapper = $el.closest('.event-wrapper'); 

    // Get the position of the timeline: 
    var timelinePosition = $eventWrapper[0].getBoundingClientRect(); 

    // Then get the position of the element you're interested in:  
    var targetPosition = $el.getBoundingClientRect(); 

    var targetIsNotOffToTheLeft = targetPosition.right > timelinePosition.left; 
    var targetIsNotOffToTheRight = targetPosition.left < timelinePosition.right; 

    // The timeline is not scrollable vertically, so we only need to worry 
    // about the horizontal position 
    return targetIsNotOffToTheLeft && targetIsNotOffToTheRight; 

} 

// Usage: 

console.log(isElementVisible($("a[data-date='16/01/2014'"))); 

// Or with just the date: 

console.log(isElementVisible("16/01/2014")); 
Смежные вопросы