javascript - 有没有更好的方法来防止单击 href 时整个页面滚动?

标签 javascript jquery html href

我正在尝试使用 JavaScript 制作日历。它工作正常,除了当单击下一个/上一个 V 形时,整个页面向下滚动,而不是仅日历动画。我认为这是因为月份之间的切换是通过更新 href 来实现的。因此,由于页面的其余部分找不到该 href,因此它会滚动到底部。

我尝试添加 preventDefault()return false;,这确实会阻止整个页面滚动。不幸的是,它也会扰乱日历页面滚动到下个月的情况。在 $("#angle_down").click(function (e) 末尾使用 preventDefault()return false; code>$("#angle_up").click(function (e),日历滚动不再起作用。

我不知道如何解决这个问题。非常感谢您的帮助。

我做了一个截图,以便您可以看到正在运行的代码。

// Check for Leap Year
function isLeap(year) {
  if (year % 4 == 0) {
    return 29;
  } else {
    return 28;
  }
}

const days = ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstg", "Freitag", "Samstag"];
const months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
// This array gives the index for months with only 30 days. September = 9
const thirty = [9, 4, 6, 11];

let d = new Date();

let currentMonth = d.getMonth();
let currentDate = d.getDate();
let currentDay = d.getDay();
let currentYear = d.getFullYear();

// limit displayed months
let maxMonths = 32;

// Create text based upon the selected date.
$("#selectedDate").text(`${currentDate}. ${months[currentMonth]} ${currentYear}`);
$("#month h3").text(`${months[currentMonth]} ${currentYear}`);


// to get the days from other months, create a loop over 12 months
for (let j = 1; j <= maxMonths; j++) {
  currentMonth++;

  // If month goes past December, reset month and add a year.
  if (currentMonth == 13) {
    currentMonth = 1;
    currentYear = currentYear + 1;
  }

  // Get first of Month and Day.
  let firstOfMonth = new Date(`${currentMonth}/1/${currentYear}`);
  let firstOfMonthDay = firstOfMonth.getDay();

  // Check for Days in Month
  if ($.inArray(currentMonth, thirty) > -1) {
    var lastDay = 30;
  } else if (currentMonth == 2) {
    var lastDay = isLeap(currentYear);
  } else {
    var lastDay = 31;
  }

  // Loop through the amount of days in the month to create the date tiles
  for (let i = 1; i <= lastDay; i++) {
    let date = new Date(`${currentMonth}/${i}/${currentYear}`);
    let day = date.getDay();

    // To correctly display the first date on the correct day, do a check and add empty blocks
    if (firstOfMonth.getDate() == i && j == 1) {
      for (let k = 0; k < day; k++) {
        $("#dates").append('<p class="dates"></p>');
      }
    }

    // Add tile to div
    $("#dates").append(`<p class="dates" id="${i}_${currentMonth}_${currentYear}">${i}</>`)

    // If it is the last day of the month and last month of the loop - check to add empty tiles.
    if (i == lastDay && j == maxMonths) {
      for (let l = 0; l < (6 - day); l++) {
        $("#dates").append("<p></p>");
      }
    }

    // When a day reaches Saturday, break
    if (days[day] == days[6]) {
      $("#dates").append("<br/>")
    }
  }
}

// Add selected style to selected date by accessing its id.
// generates and id, like so: 1_9_2019
$(`#${currentDate}_${d.getMonth() + 1}_${d.getFullYear()}`).addClass("selected");

// When user clicks on a new date, selectedDate will be updated
$(".dates").click(function(e) {
  let newDate = e.target.id;
  let newDateArr = newDate.split("_");

  $(".selected").removeClass("selected");
  $(this).addClass("selected");

  if (!newDate || newDate == "dates") {
    // tile is empty
    $("#selectedDate").text("Terminkalender");
  } else {
    // tile contains date
    $("#selectedDate").text(`${newDateArr[0]} ${months[newDateArr[1] - 1]} ${newDateArr[2]}`);
  }

});



/* Calendar Navigation */

let getMonth = d.getMonth();
let updatedMonth = getMonth + 1;

let getYear = d.getFullYear();
let updatedYear = getYear;

// Add opacity to next or previous month to add more clarity.
$(".dates").not(`[id*=${updatedMonth}_${updatedYear}]`).addClass("opacity");

// down chevron
$("#angle_down").click(function(e) {

  // If user reaches end of calender, disable event
  if (updatedMonth == getMonth + 1 && updatedYear == getYear + 10) {
    $("#angle_down").addClass("opacity");
    return false;
  }

  $(".opacity").removeClass("opacity");

  // when down-chevron gets clicked, add one month
  updatedMonth++;

  // If month goes past December, reset month and add a year.
  if (updatedMonth == 13) {
    updatedMonth = 1;
    updatedYear = updatedYear + 1;
  }

  // update the link attribute with the new month and year, and update it in the DOM
  var link = `#1_${updatedMonth}_${updatedYear}`;
  $("#angle_down").attr("href", link);

  // update heading with updated month and year when chevron gets clicked
  $("h3").text(months[updatedMonth - 1] + " " + updatedYear);

  // Add opacity to next or previous month to add more clarity.
  $(".dates").not(`[id*=${updatedMonth}_${updatedYear}]`).addClass("opacity");

  // e.preventDefault();
});

//up chevron 
$("#angle_up").click(function(e) {

  // If user reaches beginning of calender, disable event
  if (updatedMonth == getMonth + 1 && updatedYear == getYear) {
    $("#angle_up").addClass("opacity");
    return false;
  }

  // when up-chevron gets clicked, remove one month
  updatedMonth--;

  // If a months value is before January, reset month to December and remove a year.
  if (updatedMonth == 0) {
    updatedMonth = 12;
    updatedYear = updatedYear - 1;
  }

  var link = `#1_${updatedMonth}_${updatedYear}`; // = 1_9_2019
  $("#angle_up").attr("href", link); // = href="#1_9_2019"
  $("h3").text(months[updatedMonth - 1] + " " + updatedYear);

  $(".opacity").removeClass("opacity");

  // Add opacity to any day not in the selected month.
  $(".dates").not(`[id*=${updatedMonth}_${updatedYear}]`).addClass("opacity");

  // e.preventDefault();
});
/* calendar styles */

.calendar-wrapper {
  position: sticky;
  top: 10rem;
  background: #fff;
  margin: 1rem 0;
  width: 25rem;
  color: #232323;
  background-color: #fff;
  -webkit-box-shadow: 10px 10px 15px 0px rgba(0, 0, 0, 0.6);
  -moz-box-shadow: 10px 10px 15px 0px rgba(0, 0, 0, 0.6);
  box-shadow: 10px 10px 15px 0px rgba(0, 0, 0, 0.6);
}

.calendar {
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 2rem;
  width: 23rem;
}

.calendar-wrapper span {
  color: #232323;
}

.calendar-wrapper h2 {
  text-align: center;
  font-weight: 400;
  color: #fff;
  background-color: #595959;
  letter-spacing: 0.1rem;
  padding: 0.7rem 0;
  cursor: pointer;
}

.head p,
.dates p {
  text-align: center;
  padding: 0.5rem 0;
  width: 3rem;
  margin: 0;
  display: inline-block;
  height: auto;
}

.dates {
  background-color: #fff;
  height: 20rem;
  overflow-y: hidden;
  scroll-behavior: smooth;
  border: 2px solid transparent;
  transition: all 0.2s ease-in-out;
}

.dates p:hover {
  background-color: #262626;
  color: #fff;
}

.selected {
  background-color: #fff;
  color: #000;
  opacity: 1;
}

.month i {
  color: #262626;
  cursor: pointer;
  font-size: 1.5rem;
  margin: 0 0.6rem;
}

.month h3 {
  font-size: 1.2rem;
  letter-spacing: 0.02rem;
  font-weight: 400;
  display: inline-block;
  width: 16rem;
  margin-left: 0.5rem;
}

.month a {
  text-decoration: none;
}

.opacity {
  opacity: 0.5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="calendar-wrapper" class="calendar-wrapper">
  <!-- Date Title -->
  <h2 id="selectedDate"></h2>
  <!-- Calendar -->
  <div id="calendar" class="calendar">
    <!-- Month and Arrows-->
    <div id="month" class="month">
      <h3></h3>
      <a id="angle_up" href="#1_9_2019"><i class="fas fa-chevron-up"></i>prev</a>
      <a id="angle_down" href="#1_10_2019"><i class="fas fa-chevron-down"></i>next</a>
    </div>
    <!-- Days of Week -->
    <div id="head" class="head">
      <p>So</p>
      <p>Mo</p>
      <p>Di</p>
      <p>Mi</p>
      <p>Do</p>
      <p>Fr</p>
      <p>Sa</p>
    </div>
    <!-- Date Tiles -->
    <div id="dates" class="dates"></div>
  </div>

最佳答案

这与position:sticky有关(position:absolute也会发生同样的问题)。我之前在生产中使用模态时遇到过这个问题。您需要您的元素是 position: Sticky 吗?

您可以使用 position:fixed 来实现类似的用户体验,让模态 float 在内容之上。

Here's a code pen with it working (随意向下滚动,这样您就可以看到潜在的“跳转”到页面顶部)

关于javascript - 有没有更好的方法来防止单击 href 时整个页面滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58898182/

相关文章:

javascript - .fadeIn() 和 .fadeOut() 在 for 循环中不起作用

jquery - 如何向动态创建的图像添加边框图像?

jquery - 显示 js 模态不适用于最新的 jQuery 版本

javascript - 为什么我无法访问 Angular 创建的新 DOM 元素?

javascript - 鉴于 javascript 在单线程中执行,promise.all 有用吗?

javascript - 通过 Javascript 检查 img 的纵横比

javascript - 填充功能

javascript - “window.open”被 Firefox 阻止

javascript - 如何使用 Jquery Ajax 将参数发送到 servlet

html - 处理转换 :translate? 的 Chrome 或 Safari 的移动版本是否有任何怪癖