2015-03-03 205 views
2

我正在構建一個Chrome擴展,它可以讓你在網頁上保存你的滾動位置。我遇到的問題通常是當您調整頁面的大小時,您正在查找的內容可能已被推到位,並且不再位於同一個滾動位置。我一直在嘗試構建一些能夠調整滾動位置以適應調整大小的內容。我發現this solution,它更接近我所尋找的,但它仍然是一些不準確的。它使用文檔的高度和滾動位置來確定您的百分比。然後在您調整頁面大小時嘗試維持該百分比。不幸的是,百分比並不完全準確。如何在窗口大小調整後保持滾動位置?

我已經將它集成到我的擴展中,並且我一直在嘗試在這wikipedia article(我喜歡圖紙)。我已在下面添加屏幕截圖來展示它的可能性。我試圖將高度增量乘以一個常數,但沒有單一的數字是有效的。我試圖將數字四捨五入到不同的點,但同樣的問題。我能做些什麼來使滾動位置更準確?

manifest.json的

{ 
    "name": "ScrollMark", 
    "description": "Save your place on a page", 
    "version": "1.1", 
    "manifest_version": 2, 
    "content_scripts": [{ 
     "js": ["jquery.min.js", "contentScript.js"], 
     "matches": ["http://*/*", "https://*/*"] 
    }] 
} 

contentScript.js

$(document).keypress(function (e) { 
    if (e.which == 13) { 
     console.group("User hit enter"); 
     console.log('window size', $(window).width(), $(window).height()); 
     console.log('document size', $(document).width(), $(document).outerHeight(true));   
     console.log('scroll top', $(document).scrollTop()); 
     console.groupEnd(); 
    } 
}); 
(function() { 
    var pageHeight = $(document).outerHeight(true), //get hight of element, including margin 
     scrollPosition = $(document).scrollTop(), 
     scrollPercent = scrollPosition/pageHeight, 
     resizing = false, 
     resizeTimer; 
    $(window).scroll(function() { 
     if (!resizing) { 
      scrollPosition = $(document).scrollTop(); 
      scrollPercent = scrollPosition/pageHeight; 
     } 
    }); 
    $(window).resize(function() { 
     resizing = true; 
     clearTimeout(resizeTimer); 
     resizeTimer = setTimeout(function() { 
      resizing = false 
     }, 500); 
     pageHeight = $(document).outerHeight(true); 
     $(document).scrollTop(scrollPercent * pageHeight); 
    }); 
})(); 

100% View 100%查看 預計滾動的位置:962 實際滾動位置:962 75% View 75%查看 預期滾動位置:1207 實際滾動地點:1211 50% View 50%查看 預計滾動位置:1534 實際滾動地點:1577 25% View 25%查看 預計滾動位置:2852 實際滾動地點:2708

回答

3

要完全按照你想要的方式,它是不幸的,因爲你無法知道響應式設計在調整大小後如何處理內容(當然,你可以,但需要數年的時間來編寫這樣的代碼)。

但是,如果我可能會給你一條建議,那就是依靠最頂端的可見元素。你可以遍歷所有的DOM樹,並找到最接近屏幕可見部分頂部的靜態元素(使用偏移屬性等),然後存儲它的完整和精確的CSS選擇器。

然後,所有你需要做恢復滾動位置:

var el = document.querySelector(storedSelector); 

el && el.scrollIntoView(); 

這會不會是那樣精確,你可能想,但它應該沒問題。

如果您仍然想要更高的精度,除了選擇器之外,還可以存儲一些偏移值,並多滾動一些,但這可能非常棘手。

希望這會有所幫助。

+0

我採取這種做法,在一個項目中我的工作,我在那裏拿到了第一個:可見對象和使用scrollTo嘗試主要滾動條的位置在瀏覽器中調整大小後。當用戶增加瀏覽器的大小時,大多數情況下它是有效的,但是當縮小時,事情就會變得很糟糕。我不得不添加代碼來檢測窗口是否縮小,並獲取LAST項目而不是第一個項目(如果窗口正在增長,這可以正常工作)。我用這個項目在桌面上敲了很多頭 - 希望這可以幫助別人嘻嘻 – Losbear 2016-11-30 16:30:26

1

我在找同樣的事情,但沒有找到任何有希望的東西。我是js的初學者,但做了一個工作腳本。它在滾動期間選擇屏幕上可見的html元素,並在調整大小期間保持與所選元素相關的滾動位置。我很安靜地相信我的代碼並不完美,但這是我沒有很多經驗就可以做到的。希望我能幫助任何人。

var html_tags = []; 
 
\t var public_closest; 
 
\t var from_top_pos; 
 
\t var public_body_height; 
 

 
\t 
 
function start() { 
 
\t \t when_scroll(); 
 
\t \t when_resize(); 
 
\t } 
 

 

 
function when_resize() { 
 
\t 
 
\t \t var count_elements = document.body.childNodes; 
 
\t \t var element = count_elements[public_closest]; 
 
\t \t var closest_pos = count_elements[public_closest].offsetTop; 
 
\t \t var window_height = window.pageYOffset; 
 
\t \t 
 
\t \t window.scrollTo(0, closest_pos + from_top_pos); 
 
\t } 
 

 

 

 

 
function when_scroll() { 
 

 
\t var window_height = document.body.scrollHeight; 
 
\t 
 
\t if (isNaN(public_body_height)) { 
 
\t \t \t public_body_height = window_height; 
 
\t \t } 
 
\t 
 
\t 
 
\t if (public_body_height != window_height) { 
 
\t \t public_body_height = window_height; 
 
\t } else { 
 

 
\t \t var how_many_elems = document.body.childNodes; 
 
\t \t var closest_number; 
 
\t \t var i; 
 
\t \t 
 
\t \t for (i = 0; i < how_many_elems.length; i++) { 
 
\t \t \t \t html_tags[i] = how_many_elems[i].offsetTop; 
 
\t \t \t } 
 
\t \t \t \t 
 
\t \t var closest; 
 
\t \t 
 
\t \t for (i = 0; i < html_tags.length; i++) { \t 
 
\t \t \t if (isNaN(html_tags[i])) { 
 
\t \t \t \t } else { 
 
\t \t \t \t \t 
 
\t \t \t \t \t if (isNaN(closest)) { 
 
\t \t \t \t \t \t \t closest = html_tags[i]; 
 
\t \t \t \t \t \t } 
 
\t \t \t \t \t \t \t 
 
\t \t \t \t \t if (Math.abs(window.pageYOffset - html_tags[i]) <= Math.abs(window.pageYOffset - closest)) { 
 
\t \t \t \t \t \t \t \t closest = html_tags[i]; 
 
\t \t \t \t \t \t \t \t closest_number = i; 
 
\t \t \t \t \t \t \t } \t 
 
\t \t \t \t } 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t if (isNaN(public_closest)) { 
 
\t \t \t \t } else { 
 
\t \t \t \t \t how_many_elems[public_closest].style.border = "dotted 2px #33aaff"; 
 
\t \t \t \t } 
 
\t \t \t 
 
\t \t public_closest = closest_number; 
 
\t \t how_many_elems[closest_number].style.border = "dotted 4px #FF55AA"; 
 
\t \t \t \t 
 
\t \t var count_elements = document.body.childNodes; 
 
\t \t var element = count_elements[public_closest]; 
 
\t \t var current_height = count_elements[public_closest].offsetTop; 
 
\t \t var window_height = window.pageYOffset; 
 
\t \t var height_difference = window_height - current_height; 
 
\t \t 
 
\t \t from_top_pos = height_difference; 
 

 
\t } 
 
}
body>div { 
 
\t \t float:left; 
 
\t \t width:35%; 
 
\t \t min-width:200px; 
 
\t \t min-height:200px; 
 
\t \t max-height:1000px; 
 
\t \t margin:30px 10px; 
 
\t \t padding:20px 10px; 
 
\t \t font-size:22px; 
 
\t \t color:#33aaff; 
 
\t \t background-color:#ffffff; 
 
\t \t border:dotted 2px #33aaff; 
 
\t \t overflow:hidden; 
 
\t }
<body onload="start()" onscroll="when_scroll()" onresize="when_resize()"> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at  urna. Mauris nec venenatis sapien, et auctor ex. Donec vel urna vulputate, volutpat augue non, bibendum quam. Maecenas congue id justo nec feugiat. Mauris non molestie leo. Duis non tincidunt nibh. Duis tristique dapibus sapien id commodo. In et tempor lorem.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna. Mauris nec venenatis sapien, et auctor ex. Donec vel urna vulputate, volutpat augue non, bibendum quam. Maecenas congue id justo nec feugiat. Mauris non molestie leo.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna. Mauris nec venenatis sapien, et auctor ex. Donec vel urna vulputate, volutpat augue non, bibendum quam.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. ullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna. Mauris nec venenatis sapien, et auctor ex.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est.Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna. Mauris nec venenatis sapien, et auctor ex. Donec vel urna vulputate, volutpat augue non, bibendum quam. Maecenas congue id justo nec feugiat. Mauris non molestie leo. Duis non tincidunt nibh. Duis tristique dapibus sapien id commodo. In et tempor lorem.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna. Mauris nec venenatis sapien, et auctor ex. Donec vel urna vulputate, volutpat augue non, bibendum quam. Maecenas congue id justo nec feugiat. Mauris non molestie leo.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna. Mauris nec venenatis sapien, et auctor ex. Donec vel urna vulputate, volutpat augue non, bibendum quam.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna. Mauris nec venenatis sapien, et auctor ex.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio. Nullam vel massa ut nisl sollicitudin ullamcorper a at urna.</p> 
 
</div> 
 

 
<div> 
 
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed urna pellentesque, commodo ante ut, porttitor est. Nullam viverra dignissim sem, ac auctor dui. Phasellus ut neque odio.</p> 
 
</div> 
 

 
</body>

+1

我不知道比這更好的方法,但我會提到在每個滾動事件中運行如此多的代碼可能會降低用戶的幀速率。使用計時器來限制檢測距離屏幕頂部最近的元素的速率是有意義的。 – 2017-09-07 08:37:51

相關問題