Target Environment: Wordpress VIP
header.php
goal: click icon div to open third party chat, toggle to close if needed, chat icon to persist acrross all pages.
Hi All
I've been tasked with integrating a 3rd Party Chat app in our site. I want it to perform like a traditional chat in-page chat app (in a div) , however, the shared script uses js the window.open method and open the chat into a separate window. I've tried unsuccefully to use , tags.
Suspect this shouldnt be to hard but I can't figure it out. I hope I have enough information here.
Thanks in advance!
The code I am replacing is straight forward yet opens into a new window but I need the window to look like a modern chat
script type="text/javascript "
const chatFunc = () => {
var x = screen.width - 550;
var y = screen.height - 800;
var params = 'height=550,width=375,popup=yes,left='+x+',top='+y;
var Url = 'thridpartychat link';
**window.open(Url, '', params);** // this seems to be the issue
}
script
<div id="test" class="chat" onClick="chatFunc()" data-toggle="tooltip" data-placement="top" title="Chat" style=""> </div>
My attempt:
<div id="test" class="chat fas fa-comment-dots fa-7x embed-responsive" data-toggle="tooltip" data-placement="top" title="Chat now!" style="">
<iframe id="chatIframe" class="embed-responsive-item" style="border:none" seamless>
</iframe>
</div>
var x = screen.width - 550;
var y = screen.height - 800;
var params = "height=550,width=375,popup=yes,left=" + x + ",top=" + y;
var Url =
"[link to third Party Chat]";
var test = document.getElementById('test');
test.addEventListener("click", function() {
// Get Iframe - I had exception catch here -didnt work
var iframe = document.getElementById('chatIframe');
// Assign Attr-Used Object.assign at one point to no avail
iframe.setAttribute('left', '+' + x + '+');
iframe.setAttribute('top', '+' + y, );
iframe.setAttribute('height', '550');
iframe.setAttribute('weight', '375');
iframe.setAttribute('src', 'Url');
this.parentNode.appendChild(iframe);
this.parentNode.removeChild(this);
});
Here is how I want the chat to look :
No idea why you are over complicating this. is there a specific reason you want to load the iframe after? if not using css to style it and just toggling it to be visible is the best solution.
HTML
<body>
<header>
<button id="js-chat-toggle" class="chat fas fa-comment-dots fa-7x embed-responsive" data-toggle="tooltip" data-placement="top" title="Chat now!" style="">
Chat now!
</button>
</header>
<div class="chat-container" id="js-chat-container">
<iframe id="chat-iframe" class="embed-responsive-item" seamless src="https://google.com">
</div>
</iframe>
</body>
CSS
.chat-container {
display: none;
position: absolute;
bottom: 10px;
right: 10px;
max-width: 320px;
overflow:hidden;
}
.chat-container.open {
display: block;
}
.chat-container iframe {
width: 100%;
border: none;
overflow:hidden;
}
JavaScript
const chatToggle = document.getElementById('js-chat-toggle');
const chatContainer = document.getElementById('js-chat-container')
chatToggle.addEventListener('click', function() {
chatContainer.classList.toggle('open')
})
How is it possible to close a div that's currently open when you click on its trigger that usely opens the div or any other trigger (that opens a different event on the page)?
So basicaly I have two links: Login and Register. When you click Register, the Login block/div disappears and the Register div shows up. When I hit Login, the Register div hides and the Login div shows up.
Also when I, e.g. click Login and the Login div is already shown - the Login div must hide aswell.
How do I accomplish this? I tried for days now, but unfortunately i'm a beginner to jQuery and my skills in jQuery aren't great at the moment. I made the following script that works. I only can hide/show divs when you click the same trigger. If you click Register AND Login the divs will just show up on top of eachother, without the hiding.
;(function($) {
var $jq = jQuery.noConflict();
$jq.fn.login_switch = function(options) {
var o = $jq.extend({}, $jq.fn.login_switch.defaults, options);
var $this = $jq(this);
$jq(this).click(function(e)
{
e.preventDefault();
// hides matched elements if shown, shows if hidden
$jq(this).closest("div#wrapper").children("div#member_login").eq(0)[o.method](o.speed);
});
};
$jq.fn.reg_switch = function(options) {
var o = $jq.extend({}, $jq.fn.reg_switch.defaults, options);
var $this = $jq(this);
$jq(this).click(function(e)
{
e.preventDefault();
// hides matched elements if shown, shows if hidden
$jq(this).closest("div#wrapper").children("div#member_reg").eq(0)[o.method](o.speed);
});
};
$jq.fn.login_switch.defaults = {
speed : "slow",
method: "slideFadeToggle"
};
$jq("a.log-expand").login_switch();
$jq.fn.reg_switch.defaults = {
speed : "slow",
method: "slideFadeToggle"
};
$jq("a.reg-expand").reg_switch();
var msie = false;
if(typeof window.attachEvent != 'undefined') { msie = true; }
$jq.fn.slideFadeToggle = function(speed, easing, callback) {
return this.animate({opacity: 'toggle', height: 'toggle'}, speed, easing, function() {
if (msie) { this.style.removeAttribute('filter'); }
if (jQuery.isFunction(callback)) { callback(); }
});
};
};
})(jQuery);
My html is:
<div id="member_reg" style="display:none;">
<div class="container">
<div class="sixteen columns">
REGISTRATION.
</div>
</div>
</div>
<div id="member_login" style="display:none;">
<div class="container">
<div class="sixteen columns">
LOGIN.
</div>
</div>
</div>
with the trigger buttons:
<ul class="user">
<li>Register</li>
<li>Login</li>
</ul>
Here I have created a FIDDLE for you with the behavior I think you are trying to achieve.
Let me know if you have any questions or if I'm way off base.
HTML
<button id="btnLogin" data-bound="login">Login</button><button id="btnRegister" data-bound="register">Register</button>
<hr />
<div id="login" class="area" data-state="closed">
Login div
</div>
<div id="register" class="area" data-state="closed">
Register div
</div>
CSS
.area{
float:left;
width:200px;
height:0;
margin:10px;
overflow:hidden;
text-align:center;
line-height:100px;
}
#login{
background:#41cc36;
}
#register{
background:#3764e3;
}
JAVASCRIPT
$(document).ready(function(){
$('button').bind('click', function(){
//close any open areas
$('.area').each(function(){
if($(this).data('state') == 'open'){
$(this).animate({'height': 0}, 750, function(){
$(this).data('state', 'closed');
});
}
});
//retrieve the div we need to toggle and it's state
var divID = $(this).data('bound'),
div = $('#' + divID),
state = div.data('state');
//animate the div based on it's state, then set the new state
if(state == 'closed'){
div.animate({'height': 100}, 750, function(){
div.data('state', 'open');
});
}else{
div.animate({'height': 0}, 750, function(){
div.data('state', 'closed');
});
}
});
//init
$('#btnLogin').trigger('click');
});
This problem occurs in the stock browser included with at least Android 4.1.2 (not Mobile Chrome) and the WebView component in a cordova-based android app we're building.
I've built a page with a fixed header at the top of the view that contains a horizontally scrollable set of tabs with the basic DOM and inline CSS below, and click handlers attached to each of the tabs are not firing.
<html>
...
<body>
<div>
<header class="navheader" style="position: fixed; z-index: 1000;">
<h1>....</h1>
<nav style="width: 100%; overflow: scroll; -webkit-overflow-scrolling: touch;">
<div class="tabs">
<div class="tab">...</div>
<div class="tab">...</div>
<div class="tab">...</div>
<div class="tab">...</div>
<div class="tab">...</div>
<div class="tab">...</div>
...
</div>
</nav>
</header>
<section>
...
</section>
</div>
</body>
</html>
I've tried attaching a click handler in several ways with jQuery, such as:
$('body').on('click', 'header .tab', function(event){ ... });
or
$('.tabs .tab').on('click', function(event){ ... });
along with variations on the selector like 'header .tabs a', 'header .tabs .tab a', and 'header a'. I also tried:
$('.tabs .tab a').each(function(i) { this.onclick=function(){ ... }; });
and adding the onclick attribute to each a tag:
<div class="tab">...</div>
None these worked.
Using this code, though:
$('body').on('click', function(event){
console.log("Click" + $(event.target).attr('class'));
});
The click event will print 'navheader' or whatever is behind the element with 'overflow: scroll' set. Adjusting the z-index for each tab, the tabs container, and/or the nav elem had no effect on this either.
Removing 'overflow: scroll' from the CSS alleviates the problem and the events fire with any of the methods for registering a handler (the '-webkit-overflow-scrolling: touch' seemed to have no effect). But then I obviously lose the ability to scroll horizontally. Thus, it seems like elements with scrollable inner content are in some way removed from the event bubbling hierarchy. It also works in Mobile Chrome and all things iOS.
Has anyone found a work-around?
Also, webView.getSettings().setJavaScriptEnabled(true); is declared in for WebView.
I ended up essentially doing my own hit detection:
$('body').on('click', '.navheader', function(event) {
var $nav = $('nav'), x = event.pageX || event.clientY, y = event.pageY || event.clientY;
y -= $(window).scrollTop();
// Because the nav bar takes up the whole width for us
if (y > $nav[0].offsetTop && y < $nav[0].offsetTop + $nav.outerHeight()) {
var scroll_left = $nav[0].scrollLeft, click_offset = scroll_left + x,
$tabs = $nav.find(".tab");
// Since each tab has a different width
$tabs.each(function(i) {
if (click_offset >= this.offsetLeft && click_offset < this.offsetLeft + this.offsetWidth) {
// Hurray, we clicked a tab, do something like .click()
}
});
}
});
I'm very new to javascript and trying to use Twitter bootstrap to get a good looking website up and running quickly. I know this has something to do with jquery, but I'm not sure how to stop my video when I push the close button or the close icon.
Can someone explain how I can get my video to stop playing because even when I close the window, I can still hear it in the background.
<!-- Button to trigger modal -->
<img src="img/play.png">
<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role=labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria>×</button>
<h3 id="myModalLabel">I am the header</h3>
</div>
<div class="modal-body">
<p><iframe width="100%" height="315" src="http:com/embed/662KGcqjT5Q" frameborder="0" allowfullscreen></iframe></p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>
I know I'm 2+ years late, but since then, a couple of things have changed, with B3 the new way to perform this out of the box is this:
$("#myModal").on('hidden.bs.modal', function (e) {
$("#myModal iframe").attr("src", $("#myModal iframe").attr("src"));
});
Have fun with Bootstrap!
There is a nice proper way of doing this - see the comments in the approved answer to this post.
Couldn't get that working first time round myself though, and was in a rush, so I did a rather horrible hacky bit of code which does the trick.
This snippet 'refreshes' the src of the embed iframe, causing it to reload:
jQuery(".modal-backdrop, #myModal .close, #myModal .btn").live("click", function() {
jQuery("#myModal iframe").attr("src", jQuery("#myModal iframe").attr("src"));
});
If someone still has the problem, try this, it worked for me:
$(document).ready(function(){
$('.modal').each(function(){
var src = $(this).find('iframe').attr('src');
$(this).on('click', function(){
$(this).find('iframe').attr('src', '');
$(this).find('iframe').attr('src', src);
});
});
});
Here is a simple way I've found for having a video play in a modal window, and then stop playing on close.
Use the .html to load the iFrame with your video into the modal-body, when the modal is shown, and then replace the modal-body with nothing when it is hidden.
$('#myModal').on('show', function () {
$('div.modal-body').html('YouTube iFrame goes here');
});
$('#myModal').on('hide', function () {
$('div.modal-body').html('');
});
Here is a jsfiddle example:
http://jsfiddle.net/WrrM3/87/
Here, I generalize #guillesalazar's answer.
This will reset any iFrame within any bootstrap modal (when the modal is closed):
$(function(){
$("body").on('hidden.bs.modal', function (e) {
var $iframes = $(e.target).find("iframe");
$iframes.each(function(index, iframe){
$(iframe).attr("src", $(iframe).attr("src"));
});
});
});
Add this to your layout and you're set.
UPDATE: Code modified for modals with multiple iFrames.
You should empty iframe src first and then set it up again.
So my working answer:
$('#myModal').on('hidden.bs.modal', function () {
var src = $(this).find('iframe').attr('src');
$(this).find('iframe').attr('src', '');
$(this).find('iframe').attr('src', src);
});
October, 2014. For Bootstrap 3.
Here is my solution, it solves the following using bootstrap event calls:
Autoplay movie when showing the modal
Stop movie when modal is hidden
HTML carousel inside modal, first active item is the iframe video
<button class="btn btn-primary" data-toggle="modal" data-target="#myModal">Modal</button>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div id="myCarousel" class="carousel slide carousel-fade" data-ride="carousel">
<div class="carousel-inner" role="listbox">
<div class="item active">
<div class="fill">
<iframe id="videoIframe" width="100%" height="100%" src="https://www.youtube.com/embed/UVAjm8b7YFg?rel=0&showinfo=0" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Javascript autoplay when displaying modal, then reset the URL and apply it to iframe src again
$('#myModal').on('show.bs.modal', function() {
$("#videoIframe")[0].src += "&autoplay=1";
});
$('#myModal').on('hidden.bs.modal', function(e) {
var rawVideoURL = $("#videoIframe")[0].src;
rawVideoURL = rawVideoURL.replace("&autoplay=1", "");
$("#videoIframe")[0].src = rawVideoURL;
});
This one does it perfectly:
$("#myModal").on("hidden.bs.modal", function(t) {
var o = $(t.target).find("iframe");
o.each(function(t, o) {
$(o).attr("src", $(o).attr("src"))
});
});
If you however want to have it start when modal opens / stop when it closes use this code:
But make sure to add enablejsapi=1 in your src, like this for example:
<iframe src="https://www.youtube.com/embed/YOUR_VIDEO_CODE?rel=0&controls=0&showinfo=0&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
function playStopVideo() {
var youtubeFunc ='';
var outerDiv = $("#myModal");
var youtubeIframe = outerDiv.find("iframe")[0].contentWindow;
outerDiv.on('hidden.bs.modal', function (e) {
youtubeFunc = 'stopVideo';
youtubeIframe.postMessage('{"event":"command","func":"' + youtubeFunc + '","args":""}', '*');
});
outerDiv.on('shown.bs.modal', function (e) {
youtubeFunc = 'playVideo';
youtubeIframe.postMessage('{"event":"command","func":"' + youtubeFunc + '","args":""}', '*');
});
}
playStopVideo();
A much easier way than all of these answers is just replacing the whole src. This works for all modals and you can adjust iframe class as required.
$('.modal').on('hidden.bs.modal', function(e) {
var closestIframe = $(e.currentTarget).find('iframe');
var rawVideoURL = $("iframe")[0].src;
closestIframe[0].src = "";
closestIframe[0].src = rawVideoURL;
});
Reload any iframe in bootstrap modal on hide.bs.modal event.
The setTimeout delay added for fixing iframe rendering after src reset.
$('.modal').on('hidden.bs.modal', function (event){
let iframes = event.target.getElementsByTagName('iframe');
for (let i = 0; i < iframes.length; i++) {
let src_tmp = iframes[i].src;
iframes[i].src = '';
setTimeout(() => {
iframes[i].src = src_tmp;
}, 100);
}
});
I used a combination of Ruslanas Balčiūnas and Nathan McFarland's answers to code something that worked well for me.
$('#myModal').on('hide',function(){
$('.modal-body iframe').attr('src','');
});
So basically this sets the src attribute of the iframe to nothing when the close modal event is triggered. Short and sweet.
My solution to this that works for Bootstrap 3 and the modern YouTube embed format is as follows.
Assuming your video is embedded within a standard Bootstrap 3 Modal with id="#video-modal", this simple bit of Javascript will do the job.
$(document).ready(function(){
$("#video-modal").on('hide.bs.modal', function(evt){
var player = $(evt.target).find('iframe'),
vidSrc = player.prop('src');
player.prop('src', ''); // to force it to pause
player.prop('src', vidSrc);
});
});
I've seen proposed solutions to this issue involving use of the YouTube API, but if your site is not an https site, or your video is embedded using the modern format recommended by YouTube, or if you have the no-cookies option set, then those solutions don't work and you get the "TV set to a dead channel" effect instead of your video.
I've tested the above on every browser I could lay my hands on and it works very reliably.
Expanding on Guille's answer above, this is a drop-in function that will work with Bootstrap 3, the latest version of youtube as of Aug 14, and works for multiple videos /modals in one page.
$(".modal").on('hidden.bs.modal', function(e) {
$iframe = $(this).find( "iframe" );
$iframe.attr("src", $iframe.attr("src"));
});
Had a modal with many videos. Updated the code by #guillesalazar to close multiple videos in the modal.
$("#myModal").on('hidden.bs.modal', function (e) {
$("#myModal iframe").each(function () {
$(this).attr("src", '');
});
});
7 years after, we still need to solve this.
We found a best way to fix it (Inspired by RobCalvert123 answer)
jQuery(".modal-backdrop, .modal.open .close,.modal.open .btn").live("click", function() {
// Get iframe opened
var iframe_open = jQuery('.modal.open');
// Get src from opened iframe
var src = iframe_open.attr('src');
// replace src by src to stop it that's the tips
iframe_open.attr("src", src);
});
1. Embed Youtube on your Page (html)
Add the Youtube div-container to your Website:
<div id="ytplayer">This will be replaced with the Youtube iFrame</div>
Add the Youtube Javascript Api (iFrame)
<script>
// Ads Youtube JS API
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// This function creates an <iframe> (and YouTube player) after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
height: '390',
width: '640',
videoId: 'ncif63mSZl4',
WMode: 'transparent',
wmode: 'opaque',
playerVars: {
'autoplay': 0,
'controls': 0,
'autohide':1,
'rel':0,
'showinfo': 0,
'modestbranding': 1,
},
});
}
function stopVideo() {
player.stopVideo();
}
function pauseVideo() {
player.pauseVideo();
}
function playVideo(){
player.playVideo();
}
</script>
Controll with jQuery (Bootstrap Modal)
// Open Modal and start Playing Youtube Video
$("#myModalTrigger").click(function(){
$("#video-modal").modal(); // opens up the Modal
playVideo(); // Starts playing Video
});
// Stop Player on Modal hide
$('#video-modal').on('hide.bs.modal', function (e) {
stopVideo(); // stop player
});
$('#myModal').on('hide', function () {
$('#video_player')[0].stopVideo();
})
#guillesalazaar's answer was only the 1st half of my fix so I felt compelled to share my situation in case it helps someone in the future. I too have an embedded youtube video but I set mine to play automatically when the frame is loaded using autoplay=1. To get around the autoplay issue on page load I have my youtube url stored in a variable that sets the iframe source using a click handler. To solve this I simply removed the attribute source link:
My Url to trigger the modal window:
<div id="movieClick" class="text-center winner">
<a href="#" data-toggle="modal" data-keyboard="true" data-target="#movie">
</div>
My hidden modal window divs:
<div id="movie" class="modal fade" role="dialog" tabindex='-1'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">They Live (1988)</h4>
</div>
<div class="modal-body">
<iframe id="onscreen" width="100%" height="460px" src="" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
My JS:
$("#movieClick").click(function(){
var theLink = "https://www.youtube.com/embed/Wp_K8prLfso?autoplay=1&rel=0";
document.getElementById("onscreen").src = theLink;
});
// really annoying to play in the Background...this disables the link
$("#movie").on('hidden.bs.modal', function (e) {
$("#movie iframe").attr("src", '');
});
//stop youtube video on modal close
$('.modal').on('hidden.bs.modal', function () {
var iframVideo = $('.modal').find('iframe');
$(iframVideo).attr("src", $(iframVideo).attr("src"));
});
My solution for 2 or more Youtube videos using the HTML data-* attribute. The video autoplays and stops when the modal is opened and closed.
<button data-url="https://www.youtube.com/embed/C0DPdy98e4c" data-toggle="modal" data-target="#mymodal">Video 1</button>
<button data-url="https://www.youtube.com/embed/ScMzIvxBSi4" data-toggle="modal" data-target="#mymodal">Video 2</button>
<!-- Modal -->
<div id="mymodal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
</div>
$('.modal').on('show.bs.modal', function (event) {
$(this).find('iframe').attr("src", $(event.relatedTarget).data('url') );
});
$('.modal').on('hidden.bs.modal', function (e) {
$(this).find('iframe').attr("src", "");
});
Here is a Codepen demo:
https://codepen.io/danielblazquez/pen/oOxRJq
For angular or for dynamic html or if we have multiple iframes then use as below
$("#myModal").on('hidden.bs.modal', function (e) {
$("#myModal iframe").each(function(){
$(this).attr("src", $(this).attr("src"));
});
});
if you have multiple modals with many videos, let's say you have a modal on each slide on a carousel for instance, you need something more dynamic to close/stop the video in the visible slide and not mess up all the other modals, use this:
$(".modal").on('hidden.bs.modal', function (e) {
$(this).find("iframe").attr("src", $(this).find("iframe").attr("src"));
});