How to overlay an iframe and allow click through

2019-06-15 08:07发布

问题:

I want to be able to put a "Chat Now" button that pops up a chat window inside any webpage.

I can add the "Chat Now" button using JavaScript, but that inherits css in the page and makes it look bad. So I want to put it in its own page, and embed it in any webpage using an iframe.

This is as close as I can get it. It display the iframe on top of the page, but does not allow clicks to go through. How can I make the button "Click Me" clickable?

I see most live chat do this, so it must be possible.

<html>
    <head></head>
    <body>
        <div><button>Click Me</button></div>
        <iframe allowtransparency="true" frameborder="0" scrolling="no" src="https://www.botlibre.com/script?file&id=15069189" style="height:100%; background: none; border: 0px; bottom: 0px; float: none; left: 0px; margin: 0px; padding: 0px; position: absolute; right: 0px; width: 100%;"></iframe>
    </body>
</html>

Hopefully it is possible without having to size the iframe exactly, but maybe... it is not? It is odd that the iframe can show the webpage behind it, but cannot allow it to be clicked on.

回答1:

z-index only works on positioned elements (position:absolute, position:relative, or position:fixed)

So make sure to give your button div container a position

From: https://developer.mozilla.org/en/docs/Web/CSS/z-index

The z-index property specifies the z-order of a positioned element and its descendants. When elements overlap, z-order determines which one covers the other. An element with a larger z-index generally covers an element with a lower one.

For a positioned box (that is, one with any position other than static), the z-index property specifies:

The stack level of the box in the current stacking context. Whether the box establishes a local stacking context.

And From http://www.w3schools.com/cssref/pr_pos_z-index.asp

Definition and Usage The z-index property specifies the stack order of an element.

An element with greater stack order is always in front of an element with a lower stack order.

Note: z-index only works on positioned elements (position:absolute, position:relative, or position:fixed).



回答2:

I am a little confused as to why you want the iFrame with the chat to cover the entire screen when the chat itself only occupies a small section at the bottom right of the page. Elements with a greater stack order is always placed in front of elements with a lower stack order... so to achieve what you are trying to do with an iFrame of size 100% 100% will more than lightly require a questionably lengthy workaround.

"Yes the following method does involve manipulating the exact size of the iframe"

I did something like this a few months ago and i simply placed the iFrame on the page using absolute-positioning. Since most of those 'Live Chat' windows allow scrolling for its content i just worked with two states/heights for the iFrame. The two heights of the iFrame must match the open and close heights of the chat window contained within the iFrame.

Now.. when the user clicks on the Chat Now button... the iFrame will call a function of its parent window that will manipulate the height of the iFrame. *Just be sure to add an ID tag to the iFrame to allow the OPEN and CLOSE functions (in the parent window) to be able to manipulate the height of the iFrame.

This worked well for me!

HTML

<div><button>Click Me</button></div>
<iframe id="ChatFrame" allowtransparency="true" frameborder="0" scrolling="no" src="https://www.botlibre.com/script?file&id=15069189" style="position:absolute; height:38px; width:165px; bottom:0px; right:0px; borde:0px; background:none;"></iframe>

JavaScript to be placed in the parent window

var LiveChatOpen = false;

function open_LiveChatWindow()
{
  document.getElementById('ChatFrame').style.height=340+'px';
  document.getElementById('ChatFrame').style.width=320+'px';  
  LiveChatOpen = true;
}//End of open_LiveChatWindow


function close_LiveChatWindow()
{
  document.getElementById('ChatFrame').style.height=38+'px';
  document.getElementById('ChatFrame').style.width=165+'px'; 
  LiveChatOpen = false;     
}//End of close_LiveChatWindow

Stuff to do on the page that is being placed via iFrame: Now all you have to do is attach the onClick events to the buttons in the Chat-GUI that Maximizes and Minimizes the chat window.

Eg: Add an event listener to the "CHAT NOW" button that calls the open_LiveChatWindow() function of the parent window.

You can call the functions in the parent window like this: parent.open_LiveChatWindow();

I hope you found this solution useful.



回答3:

If interpret Question correctly, you can use a variation of approach at Can a button click cause an event in iframe? Adjust width, height of iframe and button elements to meet specific requirement.

$(function() {

  var url = "http://www.wpclipart.com/animals/cats/Cat_outside.png";
  var iframe = $("<iframe>", {
    "id": "frame",
    "width": "100px",
    "height": "50px"
  });
  var body = $("body").append(iframe);

  var img = $("<img>", {
    "id": "frameimg",
    "width": "400px",
    "height": "300px",
  }).css("background", "blue");
  var a = $("<a>", {
    "href": url,
    "html": img
  }).css("textDecoration", "none");
  var button = $("<button>", {
      "html": "click"
    }).css({
      width: iframe.prop("width"),
      height: iframe.prop("height"),
      fontSize: "48px",
      position: "absolute",
      left: 0
    })
    .one("click", function(e) {
      $(this).remove()
      body.find("#frame")
        .attr("width", "400px")
        .attr("height", "300px")
        .attr("style", "")
        .contents()
        .find("body a")
        .get(0).click()
    });
  button.appendTo(body);
  body.find("#frame").contents()
  .find("body").html(a);
});

jsfiddle http://jsfiddle.net/2x4xz/11/



回答4:

The easiest way is to use position and z-index for both elements. The z-index will define the "layer" an element belongs to. The element with a higher z-index will be displayed before another. Z-index only works with positioned elements therefore you need to position both the button and the iframe. It should look like this:

<html>
<body>
 <div><button style="position: relative; z-index:1;" onclick="alert('You just clicked')">Click Me</button></div>
        <iframe  allowtransparency="true" frameborder="0" scrolling="no" src="https://www.botlibre.com/script?file&id=15069189" style="height:100%; background: none; border: 0px; float: none; left: 0px; margin: 0px; padding: 0px; position: absolute; right: 0px;  bottom: 0px; width: 100%;z-index:0; "></iframe>


        </body>

</html>

Another way to achieve the same result without using z-index is to switch the order of the elements in the code. Since the browser will put the last mentioned element on top of the other one. In that case you need to set the position of the button to absolute (which will refer to the position in the parent element which is the body) and define top and left values:

<html>
<body>
 <div>
        <iframe  allowtransparency="true" frameborder="0" scrolling="no" src="https://www.botlibre.com/script?file&id=15069189" style="height:100%; background: none; border: 0px; float: none; left: 0px; margin: 0px; padding: 0px; position: absolute; right: 0px;  bottom: 0px; width: 100%;"></iframe>
    <button onclick="alert('You just clicked')" style="position:absolute; top:0px; left: 0px;">Click Me</button></div>

        </body>

</html>


回答5:

I have changed the z-index of the button to 9999 with position relative, and it does allow the clicks to go through.

However since the iframe embeds a page from different domain (since I was on plunker), clicks could not be propagated till the "Chat Now", due to Same origin security

Try this plunker

<!DOCTYPE html>
<html>
<head>
  <script>
    var openChat = function() {
      var iframe = document.getElementById('iframeId');
      var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
      innerDoc.getElementById("botlibrechatboxbarmax").click();
    };
  </script>
</head>
<body>
  <div style="z-index:9999; position:relative">
    <button onclick="openChat()">Click Me</button>
  </div>
  <div>
    <iframe id="iframeId" allowtransparency="true" frameborder="0" scrolling="no" src="https://www.botlibre.com/script?file&id=15069189" style="height:100%; background: none; border: 0px; bottom: 0px; float: none; left: 0px; margin: 0px; padding: 0px; position: absolute; right: 0px; width: 100%;"></iframe>
  </div>
</body>
</html>



回答6:

What you state (100% coverage iframe not interfering with elements below it) is not practical and hasn't been for years, at least according to some other unanswered SO questions:

  • Allow click to pass through iFrame to content behind it
  • Click through transparent floating iframe

It's sort of like clickjacking.

Anything positioned over something else will become the click target and "steal" all the interaction. The same thing happens with the pop-up modals (divs) that "fade" the background of the webpage with a 100% width translucent div. You'd have to capture mouse clicks in the overlaid element (iframe) and pass the position back to the main page and have it trigger click on the appropriate element at that position.

Alternatives:

  • if you only care about the button interactivity -- can you have the button click embed the iframe instead? This still won't allow interacting with the webpage behind it.
  • Don't make the iframe 100% -- just specify the size to fit it to the contents you're intending to load


回答7:

The best would be to embed a small javascript that shows the button, and handles the iframe:

function Yourprogramsnamestart(id){
  var container=document.getElementById(id);
  var a=document.createElement("a");
  a.textContent="Start App";
  a.onclick=function(){
    //create iframe
  };
  container.appendChild(a);
  }

Now the client can do this:

<div id="app"></div>
<script src="yourscript.js"></script>
<script>
 Yourprogramsnestart("app");
 </script>


回答8:

This is very quick and easy. Just add an id to iframe and in css set pointer-events:none for that id.

See working codepen here. http://codepen.io/sajiddesigner/pen/ygyjRV

CODE

HTML

<html>
<head></head>
<body>
    <div><button>Click Me</button></div>
    <iframe id="MyIframe" allowtransparency="true" frameborder="0" scrolling="no" src="https://www.botlibre.com/script?file&id=15069189" style="height:100%; background: none; border: 0px; bottom: 0px; float: none; left: 0px; margin: 0px; padding: 0px; position: absolute; right: 0px; width: 100%;"></iframe>
</body>

CSS

 #MyIframe{
     pointer-events:none;
 }

Hope this works for you.