15

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.

James
  • 17,965
  • 11
  • 91
  • 146
  • Have a look at window.postMessage. and most services let the users embed a javascript... – Jonas Wilms Jan 01 '17 at 19:47
  • 1
    wrap both in a container and make the container go full size and make the button position absolute also – charlietfl Jan 01 '17 at 19:49
  • 1
    Is requirement to have ability to click `iframe` element? Or style `button` to cover `iframe` and at `click` of `button` apply event to `iframe`? – guest271314 Jan 01 '17 at 20:15
  • The goal is to embed a chat windows in a normal webpage using an iframe, the 'Click Me' button is just an example of a normal webpage that should still be clickable even though it has the iframe in it. – James Jan 03 '17 at 00:26

8 Answers8

6

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).

Neri Barakat
  • 1,555
  • 20
  • 25
  • the button is just an example of a webpage to be embedded on, "anything" in the webpage should be clickable – James Jan 01 '17 at 19:59
  • @James yes got your point, but how anything exist on the page be clickable while the iframe cover all the page with 100% width, height? to make things clickable you should put the iframe on the back or decrease its size. – Neri Barakat Jan 01 '17 at 20:42
  • but I see lots of live chat products do this, they embed their live chat "Chat Now" button in an iframe with 100% width/height, but somehow still let clicks go to the page. There must be a way to do this. – James Jan 03 '17 at 00:23
  • what do you mean "put the iframe on the back"? The iframe only adds the button and a chat window with z-index and fixed positions in the framed webpage – James Jan 03 '17 at 00:24
  • @James seams there is something missing here and I couldn't get, putting a full page width/height iframe on a page and be able to click on the buttons on the original page doesn't make sense for me, so for sure I am missing something, could you please give me an example of a website you found doing that and I can get what you mean and investigate it more. – Neri Barakat Jan 03 '17 at 00:30
  • Maybe its not possible. If you search for "live chat" some of the live chat vendors seem to add their chat in an iframe that has 100% width/height – James Jan 04 '17 at 18:31
  • 1
    @James yes, I can see it is 100% iframe but 100% from a container div which has a fixed height and width, so the size of the iframe will never get outside the container div. – Neri Barakat Jan 07 '17 at 23:39
1

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>
Souji
  • 86
  • 1
  • 8
0

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/

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177
0

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>
RawkFist
  • 474
  • 5
  • 12
0

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.

Really Nice Code
  • 1,144
  • 1
  • 13
  • 22
0

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:

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
Community
  • 1
  • 1
drzaus
  • 24,171
  • 16
  • 142
  • 201
-1

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>
 Yourprogramsnamestart("app");
</script>
Community
  • 1
  • 1
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • but how to size the iframe so it covers the area of the chat window, and allows click through to the page for the area not covered? – James Jan 01 '17 at 19:58
  • Why does the iframe need to be over the full size? Couldnt you resize it (using javascript)? – Jonas Wilms Jan 01 '17 at 20:11
-1

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.

Optimum Creative
  • 1,438
  • 13
  • 21
  • Your codepen is different from the code given in your answer: the iframe does not cover the "Click me" button (as highlighted in yellow [here](http://codepen.io/ConnorsFan/pen/apzxpW)) and you don't use `pointer-events: none`. If you try [this codepen](http://codepen.io/ConnorsFan/pen/XpJQjj), which implements the code you mention in your answer, you will see that the "Click me" button can be clicked, as desired, but the chat controls don't respond anymore. – ConnorsFan Jan 06 '17 at 02:05