我想创建一个div,它位于内容块下方,但一旦页面滚动到足够接触其顶部边界,它就会固定在原地并随着页面滚动。
我想创建一个div,它位于内容块下方,但一旦页面滚动到足够接触其顶部边界,它就会固定在原地并随着页面滚动。
我的解决方案可能有点啰嗦,但它可以处理居中布局中来自左边缘的变量定位。
// Ensurs that a element (usually a div) stays on the screen
// aElementToStick = The jQuery selector for the element to keep visible
global.makeSticky = function (aElementToStick) {
var $elementToStick = $(aElementToStick);
var top = $elementToStick.offset().top;
var origPosition = $elementToStick.css('position');
function positionFloater(a$Win) {
// Set the original position to allow the browser to adjust the horizontal position
$elementToStick.css('position', origPosition);
// Test how far down the page is scrolled
var scrollTop = a$Win.scrollTop();
// If the page is scrolled passed the top of the element make it stick to the top of the screen
if (top < scrollTop) {
// Get the horizontal position
var left = $elementToStick.offset().left;
// Set the positioning as fixed to hold it's position
$elementToStick.css('position', 'fixed');
// Reuse the horizontal positioning
$elementToStick.css('left', left);
// Hold the element at the top of the screen
$elementToStick.css('top', 0);
}
}
// Perform initial positioning
positionFloater($(window));
// Reposition when the window resizes
$(window).resize(function (e) {
positionFloater($(this));
});
// Reposition when the window scrolls
$(window).scroll(function (e) {
positionFloater($(this));
});
};
function moveScroller() {
var move = function() {
var st = $(window).scrollTop();
var sl = $(window).scrollLeft();
var ot = $("#scroller-anchor-top").offset().top;
var ol = $("#scroller-anchor-top").offset().left;
var bt = $("#scroller-anchor-bottom").offset().top;
var s = $("#scroller");
if(st > ot) {
if (st < bt - 280) //280px is the approx. height for the sticky div
{
s.css({
position: "fixed",
top: "0px",
left: ol-sl
});
}
else
{
s.css({
position: "fixed",
top: bt-st-280,
left: ol-sl
});
}
} else {
s.css({
position: "relative",
top: "",
left: ""
});
}
};
$(window).scroll(move);
move();
}
.inProjectNavigation {
width: 60.5%;
max-width: 1300px;
position: fixed; top: 60%;
display: block;
}
我只需将此 div 放置在页面的某个位置,它就会出现在内容的顶部。对其父元素的样式没有特殊要求。
使其固定在顶部的 JS 代码如下:
const MIN_TOP_POSITION = 30;
/**
* Make the project navigation initially scroll down with the page, but then stick to the top of the browser
*/
$(window).scroll(function(e){
let $navigationDiv = $('.inProjectNavigation');
let originalTopPosPx = $navigationDiv.attr('data-originalTopPosPx');
//-- on first scroll, save the original px position in the element, as defined by CSS
if (originalTopPosPx == null) {
let cssValue = $navigationDiv.css('top');
originalTopPosPx = cssValue.substring(0, cssValue.length - 2); // get rid of the 'px'
$navigationDiv.attr('data-originalTopPosPx', originalTopPosPx);
}
//-- follow the scroll, but stick to top
$navigationDiv.css({'top': Math.max(MIN_TOP_POSITION, (originalTopPosPx - $(this).scrollTop())) + 'px'});
});
在Mac - Safari,Firefox和Chrome上测试过。希望也能在IE上运行 :)
您可以添加3行额外的代码,这样当用户向上滚动时,div将会固定在原来的位置:
以下是代码:
if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){
$('.fixedElement').css({'position': 'relative', 'top': '200px'});
}
被接受的答案是有效的,但如果您向上滚动,则不会返回到先前的位置。它始终停留在顶部,放置在那里后。
$(window).scroll(function(e) {
$el = $('.fixedElement');
if ($(this).scrollTop() > 42 && $el.css('position') != 'fixed') {
$('.fixedElement').css( 'position': 'fixed', 'top': '0px');
} else if ($(this).scrollTop() < 42 && $el.css('position') != 'relative') {
$('.fixedElement').css( 'relative': 'fixed', 'top': '42px');
//this was just my previous position/formating
}
});
我在一个 div 中设置了链接,使其成为字母和数字链接的垂直列表。
#links {
float:left;
font-size:9pt;
margin-left:0.5em;
margin-right:1em;
position:fixed;
text-align:center;
width:0.8em;
}
var listposition=false;
jQuery(function(){
try{
///// stick the list links to top of page when scrolling
listposition = jQuery('#links').css({'position': 'static', 'top': '0px'}).position();
console.log(listposition);
$(window).scroll(function(e){
$top = $(this).scrollTop();
$el = jQuery('#links');
//if(typeof(console)!='undefined'){
// console.log(listposition.top,$top);
//}
if ($top > listposition.top && $el.css('position') != 'fixed'){
$el.css({'position': 'fixed', 'top': '0px'});
}
else if ($top < listposition.top && $el.css('position') == 'fixed'){
$el.css({'position': 'static'});
}
});
} catch(e) {
alert('Please vendor admin@mydomain.com (Myvendor JavaScript Issue)');
}
});
position: sticky;
是行不通的。我在侧边栏上遇到了同样的情况,但是我成功地使用了position: fixed;
来固定它。<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<title>Events Beta</title>
<style>
/* COMMON */
body {
font-family: 'Segoe UI', sans-serif;
margin: 0px;
width: 100%;
height: 100%;
}
a, button {
margin: 8px;
padding: 10px;
border-radius: 8px;
background-color: #0d6efd;
border: 1px solid #fff;
color: #fff;
text-decoration: none;
transition: background-color 0.9s;
display: inline-flex;
}
.secondary {
background-color: #ffffff00;
color: #ccc;
float: right;
border: 2px solid #ccc;
}
a:hover, button:hover {
background-color: #5398fe;
}
h1, h2, h3 {
font-weight: 600;
}
dialog {
border-radius: 6px;
}
header {
background-color: #212020;
margin: 0px;
padding: 15px;
color: #ffffff;
height: 32px;
}
header img {
width: auto;
height: 32px;
}
select {
padding: 10px;
border-radius: 5px;
background-color: rgb(248, 249, 250);;
color: rgb(33, 37, 41);
}
.object {
background-color: #ccc;
border-radius: 6px;
padding: 8px;
margin: 8px;
width: 40%;
display: inline-block;
vertical-align: top;
}
input, textarea {
padding: 10px;
border: 1px solid rgb(222, 226, 230);
background-color: rgb(248, 249, 250);
color: rgb(33, 37, 41);
border-radius: 5px;
}
footer {
padding: 15px;
background-color: rgb(248, 249, 250);
color: #0d6efd;
}
footer a {
color: inherit;
text-decoration: none;
background-color: #ffffff00;
border: none;
}
a.secondary {
float: right;
background-color: #ffffff00;
color: #000;
}
.clear {
clear: both;
}
.island {
text-align: center;
border: 2px solid #ccc;
width: fit-content;
border-radius: 6px;
margin: auto;
padding: 10px;
margin-top: 10px;
}
.exclusive {
display: none;
}
/* NAV */
.top_menu nav {
float: right;
}
.top_menu nav a {
font-weight: 600;
padding-left: 20px;
color: #ffffff;
text-decoration: none;
background-color: #ffffff00;
border: none;
display: inline;
}
.top_menu nav a:first-child {
padding-left: 0px;
}
/* FORM COMMON */
.form-inline {
margin: 15px 0px;
max-width: 330px;
background-color: #f5f5f5;
border-radius: 5px;
padding: 15px;
}
.form-inline label {
width: 100px;
display: block;
float: left;
margin-top: 10px;
}
.form-inline input,
.form-inline textarea,
.form-inline select {
margin-bottom: 5px;
width: 200px;
}
.form-inline input[type="checkbox"] {
margin-top: 15px;
}
.form-inline input::after,
.form-inline textarea::after,
.form-inline select::after,
.form-inline input[type="checkbox"]::after {
content: " ";
clear: both;
}
/* BLOG */
.blog-post {
padding: 15px 0px 18px 0px;
border-bottom: 2px dotted #ccc;
clear: both;
}
.blog-post:last-child {
border-bottom: 0px;
}
.blog-date {
float: right;
color: #9f9f9f;
}
.blog-post h3.blog-title {
margin: 0px 0px 10px 0px;
padding: 5px 10px;
background-color: #7250ef;
color: #fff;
display: inline-block;
border-radius: 3px;
}
.blog-categories {
font-weight: 600;
color: #adabf4;
font-size: 14px;
padding-top: 10px;
}
.blog-content {
font-size: 17px;
}
.container
/* EVENTS */
.inline-text {
width: 300px;
}
/* Sidebar CSS */
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
}
/* Let's style our sidebar */
.sidebar {
width: 30%;
background-color: #333;
color: white;
position: absolute;
overflow-x: hidden;
overflow-y: auto;
height: 100%;
}
.sidebar > div {
padding: 1px 20px 20px 20px;
}
.sidebar ul {
padding-left: 0px;
}
.sidebar li {
list-style-type: none;
}
.sidebar li a {
color: inherit;
text-decoration: none;
border-radius: 4px;
padding: 8px;
margin: 0px -8px;
display: block;
background-color: #ffffff00;
}
.sidebar li a.active,
.sidebar li a.active:hover {
background-color: #666;
}
.sidebar li a:hover {
background-color: #444;
}
/* Some styling for the main content area */
.container {
margin-left: 250px; /* Leave space for the sidebar */
overflow-x: hidden;
overflow-y: auto;
height: 80%;
width: 70%;
}
.container .page {
padding: 20px;
height: 100%;
display: none;
padding-bottom: 0px;
padding-right: 0px;
}
.container .page.display {
display: block;
}
/* Media Queries */
@media (max-width: 700px) {
.container {
margin-left: 0px !important;
width: 100% !important;
}
.sidebar {
float: none !important;
text-align: center !important;
height: fit-content !important;
width: 100% !important;
position: sticky !important;
top: 0px;
}
.sidebar a {
width: fit-content;
}
#mobile-nav {
display: inline;
}
#desk-nav {
display: none;
}
.object {
width: 90%;
}
}
@media (min-width: 700px) {
.sidebar {
width: 230px !important;
padding: 15px;
}
#desk-nav {
display: inline;
}
#mobile-nav {
display: none;
}
}
</style>
<link rel="icon" href="logo_white.png" type="image/png">
<script src="script.js"></script>
<script>
function auth() {
var good = document.cookie.indexOf('authToken');
var createButton = document.querySelector("button#create_event.exclusive");
if (good = true) {
document.querySelector("button#create_event.exclusive").style.display = "inline-flex";
}
function redirect() {
createButton.addEventListener('click', redirect);
}
}
var head = document.querySelector("header.top_menu");
var body = document.querySelector("div.container");
body.width = head.width;
auth();
</script>
</head>
<body>
<header class="top_menu">
<img id="logo" src="logo_white.png">
<nav>
<button onclick="talDialogOpen()">Projects</button>
<dialog id="tal">
<button onclick="talDialogClose()" class="secondary">Close</button>
<h3>Projects</h3>
<small>This is a list of my projects. You can see my GitHub for more.</small>
<div class="object">
<h3>The Agent: Legacy</h3>
<p>A game about how an FBI agent uncovers a scheme to steal the plans for a military drug that is much bigger than himself
<br>
This game is being made in Unreal Engine 5.2, but may be moved to CryENGINE due to fees.
<br>
Platforms: Mainly PC but all</p>
</div>
</dialog>
<dialog id="events">
<button onclick="evDialogClose()" class="secondary">Close</button>
<h3>Events</h3>
<div class="object">
There are no events right now.
</div>
<a href="events.php"><button class="exclusive" id="create_event">Create Event</button></a>
</dialog>
<button onclick="evDialogOpen()">Events</button>
<script>
function evDialogOpen() {
document.getElementById("events").open = true;
}
function evDialogClose() {
document.getElementById("events").close();
}
</script>
<script>
// Script to handle dialogs
function talDialogOpen() {
document.getElementById("tal").open = true;
}
function talDialogClose() {
document.getElementById("tal").close();
}
</script>
</nav>
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
<script>
// define a default navigation starting point (usually first link on sidebar nav)
var default_nav_hash = "#home";
// handle sidebar navigation hash for "initial load of page"
function nav_hash() {
// make sure its a string and the length is larger than a '#' value
if (window.location.hash.length <= 1) {
// set the default hash in the URL
window.location.hash = default_nav_hash;
}
// set it as .active (default was set above if there was none)
$('.sidebar a[href="' + window.location.hash + '"]').addClass('active');
$('#' + window.location.hash.substring(1) + '.page').addClass('display');
}
// once the document is ready (DOM - Document Object Model)
$(document).ready(function() {
// process initial load of page
nav_hash();
// process based on click
$('.sidebar a').click(function() {
// clear .active from all
$('.sidebar a').removeClass('active');
$('.page').removeClass('display');
// set THIS to active (its been clicked on)
$(this).addClass('active');
$('#' + $(this).attr('href').substring(1) + '.page').addClass('display');
});
});
</script>
<style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
}
/* Let's style our sidebar */
.sidebar {
width: 30%;
background-color: #333;
color: white;
position: absolute;
overflow-x: hidden;
overflow-y: auto;
height: 100%;
}
.sidebar > div {
padding: 1px 20px 20px 20px;
}
.sidebar ul {
padding-left: 0px;
}
.sidebar li {
list-style-type: none;
}
.sidebar li a {
color: inherit;
text-decoration: none;
border-radius: 4px;
padding: 8px;
margin: 0px -8px;
display: block;
}
.sidebar li a.active,
.sidebar li a.active:hover {
background-color: #666;
}
.sidebar li a:hover {
background-color: #444;
}
/* Some styling for the main content area */
.container {
margin-left: 250px; /* Leave space for the sidebar */
overflow-x: hidden;
overflow-y: auto;
height: 100%;
width: 70%;
}
.container .page {
padding: 20px;
height: 100%;
display: none; /* treat as page pages */
}
.container .page.display {
display: block;
}
</style>
<!-- Sidebar -->
</header>
<section>
<nav>
<div class="sidebar">
<div id="mobile-nav">
<a href="#home">Home</a>
<a href="#portfolio">Info</a>
<a href="#contact">FBLA</a>
<a href="#classes">Schedule</a>
<a href="#guides" class="active">Events</a>
</div>
<div id="desk-nav">
<h2>Pages</h2>
<li><a href="#home">Home</a></li>
<li><a href="#portfolio">Info</a></li>
<li><a href="#contact">FBLA</a></li>
<li><a href="#classes">Schedule</a></li>
<li><a href="#guides" class="active">Events</a></li>
</div>
</div>
</nav>
<!-- Each Div element in here counts as a section that won't display unless it is selected on the sidebar. The code in in header.php -->
<div class="container">
<div class="page" id="home">
<h1>Hello, User!</h1>
<p>
Welcome to the website for Events Beta! This will be used for purposes like sharing info.
<br>
Visit the other tabs on the left (or top if your on a phone), and explore.
<br>
Here is an app list so you can go places fast:
</p><ul>
<li><a href="https://mail.google.com" target="_blank">Gmail</a></li>
<li><a href="https://mail.google.com/chat" target="_blank">Google Chat</a></li>
<li><a href="https://www.github.com/realitygamesdev" target="_blank">GitHub</a></li>
<li><a href="mailto:****************@gmail.com" target="_blank">Email me</a><small>This may not work, as the browser cannot open emails and you need to have an email client like Outlook installed on your device.</small></li>
</ul>
<p></p>
</div>
<div class="page" id="portfolio">
<h1>Info</h1>
<p>This is my and any mutual info that should be listed on this website.</p>
<ul>
<li>School: Osceola Creek Middle School</li>
<li>Email: *******************@gmail.com <a href="https://mail.google.com">Open Gmail</a></li>
<li>To chat with me and my friends, go to <a href="https://chat.google.com">Google Chat</a> and enter my email.</li>
</ul>
<p>You may also need my interests. Here they are.</p>
<ul>
<li>Coding</li>
<li>Making Video Games</li>
<li>Playing Video Games</li>
<li>Working with media (videos, images, etc.)</li>
<li>Anything on the computer</li>
</ul>
</div>
<div class="page" id="classes">
<h1>Classes</h1>
<p>These are my daily classes in school, and their info.</p>
<p>My daily periods</p>
<>
</>
</div>
<div class="page" id="contact">
<h1>FBLA Projects</h1>
<p>I am in FBLA, and have competitions all the time. The projects for them are in here.</p>
<div class="object">
<h2>Video Game Challenge</h2>
<p>
The challenge for this is to make a semi complicated video game to present to the judges.
<br>
The game is planned to be 3D, but may be 2D due to a lack of avalible resources.
<br>
If it's 3D, it will be made in CryENGINE due to fees with Unreal Engine.
</p>
</div>
</div>
<div class="page display" id="guides">
<h2>Events</h2>
<p>Welcome to Events Beta. This is your console for seeing and participating in events.</p>
<div class="object">
<h3>Events</h3>
<p>This module is in PHP</p>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Loading</title>
<script>
</script>
<div style="text-align: center;">
<video src="loading.mp4" loop="" autoplay="" muted="" width="50px"></video>
<noscript>
<div style="background-color: red;color:white;width:fit-content;border-radius:6px;padding:10px;margin-left:40%;">
This site uses JavaScript to function correctly.
<br>
You would normally see content here, but you must enable JavaScript first.
</div>
</noscript>
</div>
<h3>Event: Chat with Caleb</h3><p>Date: 10/20/2023</p><p>Participants: Gabriel, Caleb</p><h3>Event: </h3><p>Date: </p><p>Participants: </p> </div>
<div class="object">
<h3>Add an event</h3>
<p>Use the form below to add an event that others can participate in.</p>
<form action="api.php" method="post">
<label for="event_name">Event Name:</label>
<input type="text" id="event_name" name="event_name" required="">
<br>
<label for="event_date">Event Date:</label>
<input type="date" id="event_date" name="event_date" required="">
<br>
<label for="event_participants">Participants (comma-separated):</label>
<input type="text" id="event_participants" name="event_participants">
<br>
<button type="submit">Add Event</button>
</form>
</div>
<h2>Developers</h2>
<p>This section is for developers (or me) who want to use my API.</p>
<div class="object">
<h3>Import the API</h3>
<p>To import the API, link https://gabriel.jemail.us/api.js</p>
<p>This is a JavaScript API. <b>It is not compatible with Python.</b></p>
</div>
<div class="object">
<h3>API Reference</h3>
<p>
To see documentation for the API, click the button.
<a href="docs.txt" download="">See docs</a>
</p>
</div>
</div>
</div>
</section>
</body></html>
我使用了上面的一些工作来创建这个技术。我稍微改进了它,并想分享我的工作。希望这能有所帮助。
function scrollErrorMessageToTop() {
var flash_error = jQuery('#flash_error');
var flash_position = flash_error.position();
function lockErrorMessageToTop() {
var place_holder = jQuery("#place_holder");
if (jQuery(this).scrollTop() > flash_position.top && flash_error.attr("position") != "fixed") {
flash_error.css({
'position': 'fixed',
'top': "0px",
"width": flash_error.width(),
"z-index": "1"
});
place_holder.css("display", "");
} else {
flash_error.css('position', '');
place_holder.css("display", "none");
}
}
if (flash_error.length > 0) {
lockErrorMessageToTop();
jQuery("#flash_error").after(jQuery("<div id='place_holder'>"));
var place_holder = jQuery("#place_holder");
place_holder.css({
"height": flash_error.height(),
"display": "none"
});
jQuery(window).scroll(function(e) {
lockErrorMessageToTop();
});
}
}
scrollErrorMessageToTop();
<div class = "wrapper">
<header>Header</header>
<main>
<nav>Stick to top</nav>
Content
</main>
<footer>Footer</footer>
</div>
CSS:
* {
margin: 0;
padding: 0;
}
body {
background-color: #e2e2e2;
}
.wrapper > header,
.wrapper > footer {
font: 20px/2 Sans-Serif;
text-align: center;
background-color: #0040FF;
color: #fff;
}
.wrapper > main {
position: relative;
height: 500px;
background-color: #5e5e5e;
font: 20px/500px Sans-Serif;
color: #fff;
text-align: center;
padding-top: 40px;
}
.wrapper > main > nav {
position: absolute;
top: 0;
left: 0;
right: 0;
font: 20px/2 Sans-Serif;
color: #fff;
text-align: center;
background-color: #FFBF00;
}
.wrapper > main > nav.fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
}
JS(包括jquery-visible插件):
(function($){
/**
* Copyright 2012, Digital Fusion
* Licensed under the MIT license.
* http://teamdf.com/jquery-plugins/license/
*
* @author Sam Sehnert
* @desc A small plugin that checks whether elements are within
* the user visible viewport of a web browser.
* only accounts for vertical position, not horizontal.
*/
var $w = $(window);
$.fn.visible = function(partial,hidden,direction){
if (this.length < 1)
return;
var $t = this.length > 1 ? this.eq(0) : this,
t = $t.get(0),
vpWidth = $w.width(),
vpHeight = $w.height(),
direction = (direction) ? direction : 'both',
clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;
if (typeof t.getBoundingClientRect === 'function'){
// Use this native browser method, if available.
var rec = t.getBoundingClientRect(),
tViz = rec.top >= 0 && rec.top < vpHeight,
bViz = rec.bottom > 0 && rec.bottom <= vpHeight,
lViz = rec.left >= 0 && rec.left < vpWidth,
rViz = rec.right > 0 && rec.right <= vpWidth,
vVisible = partial ? tViz || bViz : tViz && bViz,
hVisible = partial ? lViz || rViz : lViz && rViz;
if(direction === 'both')
return clientSize && vVisible && hVisible;
else if(direction === 'vertical')
return clientSize && vVisible;
else if(direction === 'horizontal')
return clientSize && hVisible;
} else {
var viewTop = $w.scrollTop(),
viewBottom = viewTop + vpHeight,
viewLeft = $w.scrollLeft(),
viewRight = viewLeft + vpWidth,
offset = $t.offset(),
_top = offset.top,
_bottom = _top + $t.height(),
_left = offset.left,
_right = _left + $t.width(),
compareTop = partial === true ? _bottom : _top,
compareBottom = partial === true ? _top : _bottom,
compareLeft = partial === true ? _right : _left,
compareRight = partial === true ? _left : _right;
if(direction === 'both')
return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
else if(direction === 'vertical')
return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
else if(direction === 'horizontal')
return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
}
};
})(jQuery);
$(function() {
$(window).scroll(function() {
$(".wrapper > header").visible(true) ?
$(".wrapper > main > nav").removeClass("fixed") :
$(".wrapper > main > nav").addClass("fixed");
});
});
position: sticky; top:0;
在大多数浏览器中都能正常工作。 - Colin 't Hartposition: sticky;
的东西真是神奇。 - tscizzlerelative
容器中,position: sticky; top:0;
对我有效。 - Marzieh Mousavi