2017-01-16 3 views
0

J'utilise ce plugin pour créer un montage horizontal. Vous pouvez utiliser les flèches gauche et droite pour naviguer entre les dates. Cliquer sur une date changera le pied de page à celui correspondant à cette même date.Comment puis-je vérifier la visibilité des éléments lors de leur affichage/masquage avec scaleX()?

Mon problème est le suivant: J'essaie de savoir si certaines dates sont visibles dans la fenêtre courante. Ainsi, pour les instances où le plugin est chargé pour la première fois, les dates suivantes sont affichées: "16 Jan", "28 Feb", "20 Mar", "20 mai". Lorsque je clique sur la flèche droite, ces dates sont remplacées par les dates suivantes: "09 juil", "30 août", "15 sept", "01 nov". Maintenant, à ce stade, je voudrais savoir, par exemple, si la date "16 Jan" est visible ou non (Dans ce cas, il n'est pas visible).

Comme chaque date est ajoutée à l'élément a qui correspond à chaque date sous la forme d'un attribut data-date je peux obtenir l'élément que je veux vérifier avec le sélecteur suivant (exemple pour « 16 Jan »):

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

maintenant, afin de vérifier la visibilité que j'ai essayé deux approches différentes:

première approche (comme on le voit dans cette answer)Cette approche me renvoie toujours vrai et ne fonctionne donc pas.

Deuxième approche (comme on le voit dans cette 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() */ 
    ); 
} 

Et après:

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

Cette approche me retourne toujours vrai et donc ne fonctionne pas non plus. Je peux comprendre que ces approches peuvent ne pas fonctionner parce que la façon dont les éléments apparaissent et disparaissent après chaque clic flèche est due à l'utilisation de la fonction CSS scaleX(), dont je n'ai aucune idée de l'impact dans cette situation spécifique. Donc, après tout cela, ma question est la suivante: Est-il même possible de vérifier la visibilité des éléments dans ce cas précis? Et si oui, comment puis-je le faire?

+0

Pouvez-vous simplement ajouter un indicateur de variable sur clic qui dit 'isDateOpen = true'? ou quelque chose comme ça? Puisque vous avez déjà quelques fonctionnalités autour d'elle. – ntgCleaner

+0

@ntgCleaner Je pourrais mais pour faire cela je devrais calculer la largeur qui est montrée par page, la largeur totale de la chronologie, calculer le nombre de pages, faire une structure de données qui associe les dates à la page correspondante et puis quand je clique sur la flèche, ajoute une propriété aux dates comme tu l'as suggéré. Ceci est cependant mon dernier recours. Je cherchais quelque chose de plus simple. –

Répondre

1

La première approche ne fonctionne pas parce que les éléments sont en réalité « visible ». La ligne suivante vérifie simplement la valeur de l'attribut css visibility qui est 'visible' (la valeur par défaut) pour chacun des éléments de date.

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

Toutefois, vous ne pouvez toujours pas voir certains des éléments de date. C'est parce que ces éléments cachés se trouvent réellement à l'extérieur de leur conteneur. La seconde approche vous dirige vers l'une des solutions possibles.La fonction suivante prend un élément et détermine s'il se trouve dans le port de vue.

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() */ 
    ); 
} 

Notez que dans le code au-dessus du port de vue est supposé être fenêtre. Cela sera utile si vous voulez savoir si un élément est en dehors de la zone d'écran. Mais votre exigence est légèrement différente. Dans votre exemple, le port d'affichage doit être le conteneur de ces éléments de date. Si vous inspectez le calendrier sur votre navigateur, vous trouverez un div avec la classe événement-wrapper en dehors de laquelle toutes les dates sont cachées. Ainsi, vous pouvez modifier la fonction ci-dessus comme suit:

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 
    ); 
} 

Je l'ai testé sur quelques éléments du example que vous aviez partagé et il semble fonctionner très bien. J'espère que ça t'aide.

+0

Merci, c'était exactement ce que je cherchais. Cela a fonctionné parfaitement. –

0

Un moyen serait de comparer les positions horizontales:

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"));