2015-07-13 30 views
6

PURE JS kullanarak bir div (değil pencerenin) İÇİNDE konumlandırmak için.Kaydırma SADECE LÜTFEN saf JS

Bağlantı bağlantılarının bir listesi var ve tıklandıklarında bir konuma kaydırmak istiyorum.

Temel olarak sadece pencerede değil, bir div içinden kaymak için çapa aramak. Pencerenin hiçbir zaman gerçekte taşmadığı gibi çalışmaz.

Basit test durumu http://codepen.io/mildrenben/pen/RPyzqm

JADE

nav 
    a(data-goto="#1") 1 
    a(data-goto="#2") 2 
    a(data-goto="#3") 3 
    a(data-goto="#4") 4 
    a(data-goto="#5") 5 
    a(data-goto="#6") 6 

main 
    p(data-id="1") 1 
    p(data-id="2") 2 
    p(data-id="3") 3 
    p(data-id="4") 4 
    p(data-id="5") 5 
    p(data-id="6") 6 

SCSS

html, body { 
    width: 100%; 
    height: 100%; 
    max-height: 100%; 
} 

main { 
    height: 100%; 
    max-height: 100%; 
    overflow: scroll; 
    width: 500px; 
} 

nav { 
    background: red; 
    color: white; 
    position: fixed; 
    width: 50%; 
    left: 50%; 
} 

a { 
    color: white; 
    cursor: pointer; 
    display: block; 
    padding: 10px 20px; 
    &:hover { 
    background: lighten(red, 20%); 
    } 
} 

p { 
    width: 400px; 
    height: 400px; 
    border: solid 2px green; 
    padding: 30px; 
} 

JS

var links = document.querySelectorAll('a'), 
    paras = document.querySelectorAll('p'), 
    main = document.querySelector('main'); 

for (var i = 0; i < links.length; i++) { 
    links[i].addEventListener('click', function(){ 
    var linkID = this.getAttribute('data-goto').slice(1); 
    for (var j = 0; j < links.length; j++) { 
     if(linkID === paras[j].getAttribute('data-id')) { 
     window.scrollTo(0, paras[j].offsetTop); 
     } 
    } 
    }) 
} 

PURE JS SADECE LÜTFEN - HAYIR JQUERY

+0

JS'yi bir 'href' yerine kullanmak istediğiniz belirli bir neden var mı?(Eğer öyleyse, sorun değil, sadece merak ediyordum) – icke

+0

@icke, arka taraftaki adamın işleri ayarlamasının yolu. href farklı kaplarda olduğu gibi işe yaramazdı. Ve href kaydırmıyor pürüzsüz – mildrenben

+0

Farklı kapsayıcılar, farklı iframe'lerde yüklendiler mi? Yoksa aynı sayfada mı? Örneğinizden tüm JS'leri kaldırdım, hedeflere ve hrefs'e eklenen menü öğelerine kimlikleri ekledim. Ben noktayı özlüyorum gibi hissediyorum, ama sadece söyleyemiyorum ... – icke

cevap

3

Ne istiyorsun scrollTop property on the <main> element ayarlamaktır.

var nav = document.querySelector('nav'), 
    main = document.querySelector('main'); 

    nav.addEventListener('click', function(event){ 
    var linkID, 
     scrollTarget; 
    if (event.target.tagName.toUpperCase() === "A") { 
     linkID = event.target.dataset.goto.slice(1); 
     scrollTarget = main.querySelector('[data-id="' + linkID + '"]'); 
     main.scrollTop = scrollTarget.offsetTop; 
    } 
    }); 

Benim farklı yaptım diğer şeyler bir çift fark edeceksiniz:

  • ben event delegation kullanılan bu yüzden sadece daha verimli herhangi tıklamaları idare edecek nav elemana bir olay eklemek zorunda bağlantılar.
  • Aynı şekilde, yerine tüm p elemanları aracılığıyla döngü, bir attribute selector

Bu sadece daha verimli ve ölçeklenebilir, aynı zamanda daha kısa üretir kullanarak istediğim birini seçtiniz, daha kolay kod korumak için.

Bu kod, bir animasyonlu kaydırma için öğeye atlayacaktır, incrementally updates scrollTop after small delays using setTimeout numaralı bir işlevi yazmanız gerekir. Eğer olay heyeti ile sahip olabilir

var nav = document.querySelector('nav'), 
    main = document.querySelector('main'), 
    scrollElementTo = (function() { 
     var timerId; 
     return function (scrollWithin, scrollTo, pixelsPerSecond) { 
     scrollWithin.scrollTop = scrollWithin.scrollTop || 0; 
     var pixelsPerTick = pixelsPerSecond/100, 
      destY = scrollTo.offsetTop, 
      direction = scrollWithin.scrollTop < destY ? 1 : -1, 
      doTick = function() { 
      var distLeft = Math.abs(scrollWithin.scrollTop - destY), 
       moveBy = Math.min(pixelsPerTick, distLeft); 
      scrollWithin.scrollTop += moveBy * direction; 
      if (distLeft > 0) { 
       timerId = setTimeout(doTick, 10); 
      } 
      }; 
     clearTimeout(timerId); 
     doTick(); 
     }; 
    }()); 

nav.addEventListener('click', function(event) { 
    var linkID, 
    scrollTarget; 
    if (event.target.tagName.toUpperCase() === "A") { 
    linkID = event.target.dataset.goto.slice(1); 
    scrollTarget = main.querySelector('[data-id="' + linkID + '"]'); 
    scrollElementTo(main, scrollTarget, 500); 
    } 
}); 

başka sorun a öğelerde alt öğeler bulunur ve bir alt öğe üzerinde tıklandığında, eğer olay yerine a etiketin kendisinin hedefi olacak olmasıdır. Çevresinde getParentAnchor function I wrote here gibi bir şeyle çalışabilirsiniz.

+0

Çok teşekkürler dostum! Kaydırmak için önerilen herhangi bir bağlantı/bağlantı var mı? – mildrenben

+0

Numarayı yapması gereken bir kod ekledim. Ben orijinal cevabına dahil olurdu ama tüm gece işten sonra 6 am etrafında yazdım ve bunu yapmak için irade yoktu ;-) –

0

Umarım sorunu şu an doğru anlıyorum: Değiştiremeyeceğiniz bir işaretiniz var (bazı durumlarda hiçbir denetiminizin olmadığı anlamına gelir) ve oluşturulan menü öğelerine işlev eklemek için JS kullanmak istediğinizde.

Benim önerim şöyle sırasıyla hedefleri ve menü öğeleri id ve href özelliklerini eklemek olacaktır:

var links = document.querySelectorAll('a'), 
    paras = document.querySelectorAll('p'); 

for (var i = 0; i < links.length; i++) { 
    links[i].href=links[i].getAttribute('data-goto'); 
} 

for (var i = 0; i < paras.length; i++) { 
    paras[i].id=paras[i].getAttribute('data-id'); 
} 
+0

Çalışıyor ancak kaydırma yapmıyor – mildrenben

+0

Yani sorunsuz kaydırma yapmıyor mu? – icke