skip to Main Content

I’m creating a mobile landing page by using a combination of two third-party pages embedded in iframes. One of the iframes has been optimized to display a volume button in 50×50 dimensions. The problem is that the sound is off by default and the volume control button is hidden. The iframe shows only a white background, which also doesn’t suit the very dark background of the other iframe that takes most of the viewport. The speaker icon appears for a few seconds only when the 50×50 iframed area is touched / clicked, so a visitor has no clue they should touch it for turning the sound on.

I asked ChatGPT and it told me I could use JavaScript to do what I need, but it turned out to be a false information. JavaScript cannot capture a click event on an element that has click events disabled.

So far, the best solution that I could come up with is using pointer-events: none property on a static speaker icon that indicates the volume is turned off and placing it over the iframe with the hidden sound button. But it looks really weird when the sound is already on but the icon still shows it’s off.

<iframe
  frameborder="0"
  height="50"
  scrolling="no"
  src="speaker.html"
  style="bottom: 0; left: 0; position: absolute; z-index: 1"
  width="50"
></iframe>

<div class="speaker"
  style="
    background-image: url('Sound-Off.png');
    bottom: 0;
    height: 50;
    left: 0;
    pointer-events: none;
    position: absolute;
    width: 50;
    z-index: 2"
></div>

The above alone works as I described but looks confusing to users since the icon doesn’t switch to the "volume on" status.

let isOn = false;
const element = document.querySelector('.speaker');
element.addEventListener('click', function(event) {
  isOn = !isOn;
  if (isOn) {
    element.style.backgroundImage = 'url("Sound-On.png")';
  } else {
    element.style.backgroundImage = 'url("Sound-Off.png")';
  }
});

This JavaScript snippet I made with the help of ChatGPT but turned out it doesn’t work with pointer-events: none.

Please don’t be misled by the same-origin URL in the iframe you see in the snippet. I’m using a hack of an iframe in an iframe in an iframe and the last iframe contains a cross-origin URL as I mentioned at the beginning as the "third-party" page.

Is there a simple workaround to make the sound icon change its status when clicked and letting the click to go through to the iframe beneath at the same time?

2

Answers


  1. Chosen as BEST ANSWER

    The solution to my problem was pretty simple, I only needed to be a bit creative with the limitations I faced.

    So, instead of using image of a red speaker with sound off for the static overlay with pointer-events: none, I created a new 50x50px image that says "AUDIO SWITCH" in the upper half and includes both speaker icons in the lower half, one red with sound off and the other green with sound on.

    This is how the new overlay image looks like. 🙌


  2. Well, here i just wrapped div inside another div, so when this parent div is clicked, it will change the image of the inner div with pointer event none

    let isOn = false;
    const parent = document.querySelector(".parent");
    const element = document.querySelector('.speaker');
    parent.addEventListener('click', function(event) {
      isOn = !isOn;
      if (isOn) {
        //element.style.backgroundImage = 'url("Sound-On.png")';
        element.style.background = "green";
      } else {
        //element.style.backgroundImage = 'url("Sound-Off.png")';
        element.style.background = "red";
      }
    });
    .parent {
        bottom: 0;
        height: 50px;
        left: 0;
        cursor: pointer;
        position: absolute;
        width: 50px;
        z-index: 2;
    }
    
    .speaker {
        background: red;
        bottom: 0;
        height: 50px;
        left: 0;
        pointer-events: none;
        position: absolute;
        width: 50px;
        z-index: 2;
    }
    <iframe
      frameborder="0"
      height="50"
      scrolling="no"
      src="speaker.html"
      style="bottom: 0; left: 0; position: absolute; z-index: 1"
      width="50"
    ></iframe>
    
    <div class="parent">
    <div class="speaker"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search