Hiding a button based on the visibility of another button in the user's viewport

Is there a way to dynamically hide button B when the user scrolls and button A becomes visible on the screen? Additionally, how can we show button B again once button A is no longer visible to the user? Both buttons should never be visible simultaneously.

Here is what I have set up so far:

On an online store's cart page, there is a Go To Checkout button that appears in the middle of the page as the user scrolls to that section. This button, identified as button A in the code snippet below:

<div id="horizontalCheckoutBottomPageButtonA"> <div class="cart-section"> <button id="CheckOutA" class="button button--regular" type="submit" name="checkout"  form="cart">Go To Check Out></button>    

There is also a sticky checkout button, button B, which remains on the page and follows the user as they scroll. It is represented by the following code:

<div id="horizontalCheckoutBottomPageButtonB" <div class="container--large container--vertical-space"> <button id="CheckOutB" class="button button--regular button--outline sticky-buttonzzz" type="submit" name="checkout" form="cart">Check Out ></button</div</div>

I've attempted to implement a script that currently logs whether button A is visible or not. However, it always indicates that button A is visible even when it's scrolled out of view. The desired logic I aim for is:

1. Hide button B when button A becomes visible to the user on the screen as they scroll.

2. Un-hide button B when button A is no longer visible to the user scrolling on the screen.

Please refer to the JavaScript code provided below, which is only logging "The ButtonA is visible in the viewport", requiring adjustments to achieve the intended functionality:

<script>
function isInViewport(el) {
const rect = el.getBoundingClientRect();
return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
    rect.right <= (window.innerWidth || document.documentElement.clientWidth)

);
}

const CheckOutA = 
document.querySelector('#CheckOutA');
const message = document.querySelector('#message');

document.addEventListener('scroll', function () {
const messageText = isInViewport(CheckOutA) ?
    'The ButtonA is visible in the viewport' :
    'The ButtonA is not visible in the viewport';

message.textContent = messageText;

}, {
passive: true
});
</script>

Answer №1

Great job on your code! I have provided a working example below. By using the disabled property on the button, you can easily show and hide it.

If you are experiencing issues with this implementation in your specific scenario, feel free to share more of your code or outline any distinctions between this example and your own.

function isElementInViewport(element) {
  const rect = element.getBoundingClientRect();
  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
    rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  );
}

const CheckOutA = document.querySelector('#CheckOutA');
const CheckOutB = document.querySelector('#CheckOutB');
const message = document.querySelector('#message');

document.addEventListener('scroll', function() {
  let isInView = isElementInViewport(CheckOutA);
  const displayMessage = isInView ?
    'The ButtonA is visible in the viewport' :
    'The ButtonA is not visible in the viewport';

  message.textContent = displayMessage;
  CheckOutB.disabled = !isInView;
});
html, body {
  margin: 0;
}
body {
  height: 200vh;
  position: relative;
}

#CheckOutB:disabled {
  visibility: hidden;
}

#horizontalCheckoutBottomPageButtonB {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  border: solid green 2px;
}

#horizontalCheckoutBottomPageButtonA {
  margin-top: 140vh;
  border: solid blue 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="horizontalCheckoutBottomPageButtonB">
  <div class="container--large container--vertical-space">
    <button id="CheckOutB" class="button button--regular button--outline sticky-buttonzzz" type="submit" name="checkout" form="cart">Check Out &gt;</button><span id="message"></span>
  </div>
</div>

<div id="horizontalCheckoutBottomPageButtonA">
  <div class="cart-section">
    <button id="CheckOutA" class="button button--regular" type="submit" name="checkout" form="cart">Go To Check Out &gt;</button>
  </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The jQuery regex validation function fails to adequately validate the credit card input field

My form has multiple fields that need validation. To achieve this, I am using a customized version of jQuery Validation plugin as I want to incorporate Font-Awesome icons for indicating valid and invalid fields. It seems that with jQuery Validation, adding ...

React Native displaying identical path

Is there a way to dynamically change routes in React Native when a button is pressed? Inside my SplashContainer component, I have the following method: handleToSignUp = () => { console.log("Running handleToSignUp") this.props.navigator.push({ ...

Change the name of the state in Vue mapState

I have a specific situation in my computed where I need to track two different "loading" states. Is there a method to include an alias for the second state using this syntax? computed: { ...mapState('barcodes', ['barcodes', ' ...

When using the React Material Tree Table, I expect any new row added to automatically expand by default in the table tree structure

<MaterialTable title="title" columns={columns} data={data} icons={tableIcons} parentChildData={(row, rows) => rows.filter((item) => item.id === row.productId)} /> ...

Is browser rendering performance affected by wrapping everything in a div?

Let's consider a scenario where I have an HTML page with the following simplified content within the body: <div class="wrapper"> <div class="block1"></div> <div class="block2"></div> <div class="block3"></ ...

Flexbox Columns Maintaining Width when Window is Resized

My current challenge involves utilizing Flexbox to create a responsive layout with 5 boxes that shrink when the browser window is resized. However, 4 of these boxes are not reducing their width as expected when placed in columns. (Despite Bob behaving cor ...

Adjust date by one day using the Datetimepicker tool

I have been attempting to adjust the date of my input by one day either forward or backwards, but I seem to be stuck and not making any progress. Take a look at my code: function function backDay() { var date = $('input#datetimepicker').va ...

Center Checkboxes in Bootstrap 4 Form Input

I am working with a Bootstrap Form that contains checkboxes. One specific scenario involves a large number of options to choose from. Currently, these options are displayed in a single long list, which can make it difficult for users to read and select the ...

I am struggling to set up angular-localstorage4

I have been following the instructions in the provided link: angular-localstorage4 When attempting to import WebStorageModule and LocalStorageService from angular-localstorage, I encounter an error in the console even though the compilation is successful. ...

How can I make Firefox render the padding in a textarea the identical way as in a div?

In my efforts to ensure a consistent line width inside a textarea across IE8, Firefox, and Safari, I have encountered an issue where Firefox seems to add an extra pixel of padding compared to the other browsers. This results in text wrapping differently an ...

Implement consistent styling across several elements within a component

const GreenRow = styled.div` background-color: green; ` const RedRow = styled.div` background-color: red; ` const YellowRow = styled.div` background-color: yellow; ` const GreyRow = styled.div` background-color: grey; ` const MyComponent = () => ...

Modify the background color of a particular TD element when clicking a button using JavaScript and AJAX

When I click on the "Active account" button inside the designated td with the <tr id="tr_color" >, I want the value "1" to be added to the 'active_account' column in the database. I have been successful with this functionality. However, I a ...

Words spilling onto the picture

The issue of the text col-xs-9 col-md-9 overlapping with the image col-xs-3 col-md-3 has been persistent. Even after attempting to add the img-responsive class to the img src, it continues to not work as expected. Interestingly, CSS was intentionally avoid ...

Is your event listener failing to activate?

I have been working on a project where I gather array elements from user input and try to display them in an HTML table. Unfortunately, the event listener seems to not be triggering, and I can't figure out why. Here is the relevant HTML code: ...

Possible solution to address the issue: xhr.js:178 encountered a 403 error when attempting to access https://www.googleapis.com/youtube/v3/search?q=Tesla

Encountering this console error: xhr.js:178 GET https://www.googleapis.com/youtube/v3/search?q=river 403 A specific component was designed to utilize the API at a later point: const KEY = "mykeyas23d2sdffa12sasd12dfasdfasdfasdf"; export default ...

Text font automatically adjusts size in Chrome on Android

It seems that when a paragraph of text reaches a certain length, Google Chrome on Android decides to resize the text and make it larger (which can cause some interesting results). I've noticed that on my website, about half of the p-tags stick to the ...

Generating a JavaScript variable linked to a Rails Active Record relationship

I'm trying to implement an active record association in the DOM, but I'm encountering some difficulties. Here is my editor class: .editing .row .col-sm-3 .col-sm-8 .text-left #font-20 .title-font . ...

The UI gets all wonky when using ThemeRoller for jQuery

Currently, I am encountering an issue where I want to utilize ThemeRoller for implementing custom themes on my views. However, when I apply these themes, the interface ends up looking distorted, as shown in the images below: Before using ThemeRoller: Aft ...

JavaScript and Responsive Design Techniques

I'm struggling to create a responsive page that starts with a mobile-first approach, but I keep running into the same issue. When I have my dropdown menu in the mobile version, it looks good. However, when I try to switch it to the non-mobile version ...

Utilizing Zend JSON encoding for seamless integration with JavaScript

I'm currently working with the Zend Framework. My objective is to pass JSON data from the controller to JavaScript. I have a simple array: $array = array('a' => 1, 'b' => 2); After encoding this array into JSON format: ...