I'm creating a quickview functionality, where you can see the contents of each item in a product listing directly in a modal that will open.
In the modal there is a frame that is generated dynamically with javascript, and I place the url of my controller that renders the modal content (url like this http://localhost/quickview/product/view/id/18564/).
When the modal is closed, I delete the modal content, and when the user wants to see the content of another product on the same page, I re-generate an iframe element with javascript and display.
The problem is that after the first modal view, the iframe loads and displays the content again but the javascript that runs in the iframe (we have an image gallery in the product content) does not work. Soon after the second attempt in front of the gallery and all other behaviors with javascript do not work, although modal, iframe and content coming from the controller are correct.
I already tried to reload the same iframe (without destroying it) and display it again, I tried to create the iframe with id different to each modal view, but I could not solve it once. Below the javascript I use to generate the modal and the iframe. The controller I do not believe is relevant (whenever I open the url of the content in a new tab everything works perfectly, as well as being independent of the product every time I open the modal first, everything loads correctly in the modal).
var ProductInfo = Class.create();
ProductInfo.prototype = {
settings: {
'loadingMessage': 'aguarde ...',
'viewport': document.viewport.getDimensions()
},
idframe: 'quick-frame',
initialize: function(selector, x_image, settings) {
Object.extend(this.settings, settings);
this.createWindow();
var that = this;
$$(selector).each(function(el, index){
el.observe('click', that.loadInfo.bind(that));
})
},
createLoader: function() {
var loader = new Element('div', {id: 'pleaseWaitDialog'});
var imgLoader = new Element('img', {src: '/js/inovarti/ajax-loader.gif', alt: this.settings.loadingMessage, id: 'loading-quickview-img'});
var contentLoader = new Element('p', {class: 'loader'});
contentLoader.setStyle({
'display': 'block',
'margin-top': (this.settings.viewport.height/2 - contentLoader.getHeight()/2)+'px',
'text-align': 'center'
});
contentLoader.appendChild(imgLoader);
loader.appendChild(contentLoader);
document.body.appendChild(loader);
$('pleaseWaitDialog').setStyle({
'position': 'fixed',
'top': 0,
'left': 0,
'width': '100%',
'height': '100%',
'display': 'block',
'opacity': '.8',
'background': '#FFFFFF',
'z-index': '99999'
});
},
destroyLoader: function(full) {
if(full) {
$('pleaseWaitDialog').remove();
}
else {
if($('loading-quickview-img') != null) {
$('loading-quickview-img').remove();
}
$('pleaseWaitDialog').setStyle({'background-color': '#000000'});
}
},
showButton: function(e) {
el = this;
while (el.tagName != 'P') {
el = el.up();
}
$(el).getElementsBySelector('.quickview-ajax')[0].setStyle({
display: 'block'
})
},
hideButton: function(e) {
el = this;
while (el.tagName != 'P') {
el = el.up();
}
$(el).getElementsBySelector('.quickview-ajax')[0].setStyle({
display: 'none'
})
},
createWindow: function() {
var qWindow = new Element('div', {id: 'quick-window'});
qWindow.innerHTML = '<div id="quickview-header" style="width: 100%; text-align: right;"><i class="glyphicon glyphicon-remove"></i></div><div class="quick-view-content"></div>';
document.body.appendChild(qWindow);
$('quickview-close').setStyle({
'padding-right': "20px",
'padding-left': "20px"
});
$('quickview-close').observe('click', this.hideWindow.bind(this));
},
showWindow: function() {
var screenWidth, offsetTopModal;
if(document.body.clientWidth > 1400) {
screenWidth = 1400;
offsetTopModal = 100;
}
else {
if(document.body.clientWidth < 768) {
screenWidth = document.body.clientWidth;
offsetTopModal = 0;
}
else {
screenWidth = document.body.clientWidth * 0.8;
offsetTopModal = 100;
}
}
var windowWidth = screenWidth;
$('quick-window').setStyle({
'top': document.viewport.getScrollOffsets().top + offsetTopModal + 'px',
'left': document.body.clientWidth/2 - windowWidth/2 + 'px',
'display': 'block',
'position': 'absolute',
'width': windowWidth + 'px',
'background': '#FFFFFF',
'padding': '20px 0px',
'margin-bottom': '20px',
'border': '1px solid #F0F0F0',
'z-index': '999999',
'border-radius': '4px'
});
$('pleaseWaitDialog').observe('click', this.hideWindow.bind(this));
this.resizeIframe($(this.idframe));
},
setContent: function(srcUrl) {
var options = {
id: this.idframe,
frameborder: "0",
scrolling: "no",
src: srcUrl,
hspace: "0",
name: this.idframe+(new Date().getTime()),
width: "100%"
};
var frame = new Element('iframe', options);
$$('.quick-view-content')[0].insert(frame);
},
clearContent: function() {
$$('.quick-view-content')[0].replace('<div class="quick-view-content"></div>');
},
hideWindow: function() {
this.clearContent();
this.destroyLoader(true);
$('quick-window').hide();
},
loadInfo: function(e) {
e.stop();
var that = this;
this.createLoader();
this.clearContent();
this.setContent(e.element().href);
Event.observe($(this.idframe), 'load', function() {
window.quickview.completeInfo();
setTimeout(function () {
window.quickview.resizeIframe($(this.idframe));
},500);
});
},
completeInfo: function () {
this.destroyLoader(false);
this.showWindow();
},
resizeIframe: function(obj) {
if(obj) {
obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
obj.style.width = "100%";
}
}
}
Event.observe(window, 'load', function() {
window.quickview = new ProductInfo('.quickview-ajax', '.product-image', {
});
});
I believe it is not relevant, but the application is Magento 1.9.3.9, so I'm using prototype as js framework (native from Magento).
A curious fact, if I update the frame through the browser using the right button and requesting the "Refresh Frame" with mouse, the iframe is updated correctly and the content javascript loads correctly.
UPDATE:
By performing some tests, I noticed that the first time the iframe is loaded, the width of the iframe is detected in js inside iframe. But in the other times that it is created and inserted, the width is detected as zero. Below the tests:
//First open
console.log(document.documentElement.clientWidth);
//output: 1356
//Second open
console.log(document.documentElement.clientWidth);
//output: 0
OwlCarousel2 do a throw (more details in https://github.com/OwlCarousel2/OwlCarousel2/issues/1704), and I think de JS stop with the exception.
Owl.prototype.viewport = function() {
var width;
if (this.options.responsiveBaseElement !== window) {
width = $(this.options.responsiveBaseElement).width();
} else if (window.innerWidth) {
width = window.innerWidth;
} else if (document.documentElement && document.documentElement.clientWidth) {
width = document.documentElement.clientWidth;
} else {
throw 'Can not detect viewport width.';
}
return width;
};
Even though I change OwlCarousel2 (the latest version doesn't has a throw), I believe that the fact that the width is being detected incorrectly will generate several other problems.
I also updated the iframe by always creating it 100% wide, but the problem still persists.
It is a jQuery cache issue. You should send headers from your server in order to not cache the iframe in the client:
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
You can also force a iframe refresh by using:
iframe.contentWindow.location.reload(true);
Update
var nameOrIndex = 'nameOrIndex'; // i.e. 'my_iframe' or '0'
var iFrame = window.frames[nameOrIndex];
if (iFrame) {
var document = iFrame.contentDocument ? iFrame.contentDocument : iFrame.contentWindow ? iFrame.contentWindow.document : iFrame.document;
if (document && document.location) {
document.location.reload(true); // 1 (sandboxing, same domain origin policy)
document.location.href = document.location.href; // 2 (cross domain, might detect size changes)
}
if (iFrame.src) {
window.frames[nameOrIndex].src = iFrame.src; // 3 (cross domain, might detect size changes)
}
$(iFrame).replaceWith($(iFrame).clone()); // 4 (cross domain, might detect size changes)
}
However, regarding your size problem look at this SO question
Related
I have this website: http://wearewebstars.dk/poc/index.html
If you click the top menu, then it makes an Ajax request to another page. And if you click again, a new request to another page and so on...
However, it seems, that If I click the top navigation once, then it loads the new page, and then if I click on another link in the top navigation, then it seems that it loads the page twice or something? I cant quite figure out why it does this?
If you start by clicking "Omgivelserne", and after that click "Skriv dig op", then the page "Skriv dig op", seems to be loading twice, judging from the fade transitions?
My JS for the Ajax and Transitions (Edited to only show relevant code):
var DIS = DIS || {};
// create a timeline
var tl = new TimelineMax();
(function($, DIS, window) {
var graphic = $("div.page-transition");
DIS.PageTransitionStart = {
start: function(url) {
$this = $(this);
var pageTransitionStart = new TimelineMax({
onComplete: DIS.loadPage,
onCompleteParams: [url, $this]
});
pageTransitionStart.add(TweenMax.set($("body"), {
className: "animating"
}));
pageTransitionStart.to(graphic, 0.3, {
css: {
scale: 50,
opacity: 0.5,
force3D: true
},
ease: Power1.easeOut
});
pageTransitionStart.to(graphic, 0.5, {
css: {
scale: 130,
opacity: 1,
force3D: true
},
ease: Power1.easeOut
});
//tl.add(pageTransitionStart);
},
toggleSelectedClass: function(el) {
$("#mainmenu").find("a").removeClass("selected");
el.addClass("selected");
}
};
DIS.PageTransitionEnd = {
end: function(el, url) {
var pageTransitionEnd = new TimelineMax();
pageTransitionEnd.add(TweenMax.to(el, 0.3, {
css: {
scale: 1,
opacity: 1
},
ease: Power4.easeOut
}));
pageTransitionEnd.add(TweenMax.to(el, 0.1, {
onComplete: function() {
TweenMax.set($("body"), {
className: ""
}); // then only replace with blue div with new height and width
}
}));
//tl.add(pageTransitionEnd);
}
};
DIS.TopNavigation = function() {
$(".nav a").click(function(event) {
event.preventDefault();
$url = $(this).attr("href");
DIS.PageTransitionStart.start($url);
});
};
DIS.loadPage = function(url, el) {
var div = url + "#pages-container .content";
//var title = el.attr("title").replace(/\s/g, ''); //Remove spaces from Title
$(".content").load(div, function(response, status, xhr) {
if (status == "success") {
//alert("test");
//window.location.hash = title; // Adds a hash to the URL
console.log(xhr.status);
DIS.PageTransitionEnd.end(graphic, $url);
DIS.PageTransitionStart.toggleSelectedClass(el);
DIS.init();
} else if (status == "error") {
alert("Vi kunne desværre ikke hente siden - Kontakt venligst Living Homes");
console.log(xhr.status);
console.log(xhr.responseText);
console.log(response);
return;
}
});
};
DIS.init = function() {
DIS.TopNavigation();
if ($(window).width() > 768) {
DIS.pageNavigation();
}
DIS.TextEffects();
DIS.slider();
};
}(jQuery, DIS, window));
$(function() {
DIS.init();
});
If you change the following, I assume there would be no more "double clicks". This will make sure that TopNavigation() is only fired once, and not binding two click-events to the menu links.
DIS.init = function() {
//DIS.TopNavigation();
if ($(window).width() > 768) {
DIS.pageNavigation();
}
DIS.TextEffects();
DIS.slider();
};
and
$(function() {
DIS.TopNavigation();
DIS.init();
});
Not the best thought out solution, but it's a way to confirm where the problem lies.
Edit: Once confirmed that this is indeed the problem, the next step would be to make sure that DIS.init() is only used to reset states/variables, and that it doesn't create a lot of double bindings or conflicting events.
You can handle this by adding a...
$(".nav a").unbind("click");
But if there is no specific reason to unbind & rebind, it's better to just leave it be and fix the structure instead.
Ok, So I finally figured out the problem. It seems that there was a problem with some naming conventions. I was trying to load .content into .content, and that was caused the problem. I changed the class name on the div I was loading .content into, and that solved the problem.
I am having issues in closing the active div in my site. When I click menu you will see that a menu panel will slide from the left of the screen. As of now the only way to close it would be to click the x button. But I also have the ability for when you click footer a div will slide up from the bottom. Everything works, but the problem I am having is when the menu is open and you click footer the div will cover the menu instead of closing the menu. Same goes the other way around, when the footer is open and you click menu it will open up as well instead of closing the footer.
I would like for one div to open while closing the other open div. How would go about doing this?
Here is the JS and the full code of the site http://jsfiddle.net/8en2D/21/
$(function(){
window.status=0;
$('#menu').click(function(){
if(window.status==0){
$('#slidingMenu').stop().animate({left:'0px'},500);
window.status=1;
$('body, html').css('overflow','hidden');
}
else{
$('#slidingMenu').stop().animate({left:'-100%'},500);
window.status=0;
$('body, html').css('overflow-y','scroll');
}
});
})
/* 1. FOOTER SLIDEUP
-----------------------------------------------------------------------------------------------
===============================================================================================*/
//Close menu when you click Footer
$('#more').click(function () {
var open = $('header').is('.open');
$('#dropFooter')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=200'
}, 400, function () {
$('header').toggleClass('open');
});
});
$('#menu').click(function () {
if ($('').is('.open')) {
$('')
.removeClass('open')
.animate({
'bottom': "-=200"
}, function () {
var $footer = $('.activetoggle');
if ($footer.length)
$footer
.toggleClass('activetoggle footerButton')
.text('Footer');
});
$('footer').slideUp(400);
}
});
$('.footerButton').click(function () {// Change wording once pressed
var $this = $(this);
$this.toggleClass('footerButton');
if ($this.hasClass('footerButton')) {
$this.text('Footer');
} else {
$this.text('Close');
}
$(this).toggleClass('activetoggle');
});
$(window).resize(function(){ //check when window resize
if($(window).width() < 780){ // check when the window width is less than 780
if ($('header').is('.open')) {
$('header')
.removeClass('open')
.animate({
'bottom': "-=200"
});
$footer = $('.activetoggle');
if ($footer.length) {
$footer.toggleClass('activetoggle footerButton').text('Footer');
}
$('#dropFooter').slideToggle(400);
}
}
});
I was able to tweak your jQuery a bit to make this work. See jsfiddle here. Below I have put the two main functions that I modified.
$('#menu').click(function () {
//new jquery
if ($('header').is('.open')) {
var open = $('header').is('.open');
$('#dropFooter')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=200'
}, 400, function () {
$('header').removeClass('open');
});
if ($('.navFooter button').hasClass('activetoggle')) {
$('.navFooter button').removeClass('activetoggle').addClass('footerButton').text('Footer');
}
}
//back to your exisitng code
if (window.status == 0) {
$('#slidingMenu').stop().animate({
left: '0px'
}, 500);
window.status = 1;
$('body, html').css('overflow', 'hidden');
$('#slidingMenu').addClass('open');
} else {
$('#slidingMenu').stop().animate({
left: '-100%'
}, 500);
window.status = 0;
$('body, html').css('overflow-y', 'scroll');
$('#slidingMenu').removeClass('open');
}
});
$('#more').click(function () {
//new jquery
if ($('#slidingMenu').is('.open')) {
$('#slidingMenu').stop().animate({
left: '-100%'
}, 500);
window.status = 0;
$('body, html').css('overflow-y', 'scroll');
$('#slidingMenu').removeClass('open');
}
//back to existing code
var open = $('header').is('.open');
$('#dropFooter')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=200'
}, 400, function () {
$('header').toggleClass('open');
});
});
The list of issues that contributed to your problem is pretty long and I am fairly certain you still have some extraneous code in the fiddle that is still unnecessary.
Multiple .click() functions - all of your code for the click event of
an element should do in one function
Missing or incorrect jQuery selectors - in one area I found $('')
Lacked a notification class that the menu was open (you had this
implemented for the footer (which was called header)
Scienario:
I have a window, and I am fetching data remotely over a http protocol. What is the best way in titanium to prevent the window displaying the data prematurely.
In many mobile apps, they get around this problem by having a load indicator , everytime you open a window, how can you do this in titanium?
$.window.addEventListener('load',function(){
..
//some text
..
});
I have tried this, but I am not sure what to do next, as my async methods are fired outside of it. So not sure if this will have any affect.
thanks
Translating this from jquery:
$.ajaxSetup({
beforeSend: function() {
// show loading overlay gif
$("#Loading").show();
},
complete: function() {
// hide loading overlay gif
$("#Loading").hide();
}
});
$.ajax({
type: "GET",
url: url,
data: param = "",
contentType: "application/json; charset=utf-8",
success: doSomething,
error: errorFunction
});
};
Ajax setup means every time I fire an Ajax request, an loading overlay will appear on the screen until the response is received. How can I achieve the same thing in titanium?
Update:
Is this a good way to do it?
Albums.JS
function getAlbumCovers() {
//first check to see if profile pics already exist in user model
//create a collection
var usersCollection = Alloy.Collections.user;
facebookModule.requestWithGraphPath('me/albums', {
fields : 'id,name,cover_photo,count,created_time'
}, 'GET', function(graphResp) {
//show view indicator before data is fetched
$.view_indicator.visible = true;
if (graphResp.success) {
if (graphResp.result) {
var rows = [];
var data = JSON.parse(graphResp.result).data;
for (x in data) {
Ti.API.debug(JSON.stringify(data[x]));
if (data[x].name == "Profile Pictures") {
var row = Titanium.UI.createTableViewRow({
width : '100%',
height : 'auto'
});
var image = Titanium.UI.createImageView({
image : "https://graph.facebook.com/" + (data[x].cover_photo || 0) + "/picture?access_token=" + Ti.Facebook.accessToken,
top : 0,
left : 0,
width : 100,
height : 100
});
var title = Titanium.UI.createLabel({
text : String.format("%s (%d)", data[x].name, data[x].count),
top : 0,
left : 110,
width : 'auto',
height : 'auto'
});
row.add(image);
row.add(title);
rows.push(row);
} else {
break;
}
}
//set table rows
$.tableview.setData(rows);
//end
}
$.view_indicator.visible = false;
} else {
if (e.error) {
alert(e.error);
} else {
alert("Unkown result");
}
}
});
}
Albums.XML
<Alloy>
<Window id="win" backgroundColor="white">
<LeftNavButton>
<Button id="lbtn" onClick="rightButtonClicked" />
</LeftNavButton>
<RightNavButton>
<Button id="btnRight" onClick="rightButtonClicked" />
</RightNavButton>
<View id = "view_indicator">
<ActivityIndicator id="ind" />
</View>
<TableView id="tableview"></TableView>
</Window>
</Alloy>
App.tss
//overlay
//loading overlay to cover full screen
"#view_indicator": {
backgroundColor : '#000',
opacity : 0.6,
width : '100%',
height : '100%',
borderRadius : 5,
zIndex: 20,
visible : false
},
"#ind": {
style : Ti.UI.iPhone.ActivityIndicatorStyle.BIG,
visible : true
},
In this instance I have made a call to Facebook api, and placed $.view_indicator.visible = true; just before if (graphResp.success) { function. The loading overlay is removed once if (graphResp.success) { is hit.
The idea is, the end user has to wait for the table to be populated before seeing the tableview.
I am not sure if this is the correct way of doing this. Could someone confirm, cheers.
You can achieve this effect by calling window.open() at the end of onload callback in `HTTPClient.
var window = Ti.UI.createWindow();
var http = Ti.Network.createHTTPClient({
onload: function(e) {
var response = this.responseText;
/* Add views to window based on response */
window.open();
}
});
http.open('GET', url);
httpCallbackDecorator(http);
http.send();
function httpCallbackDecorator(http) {
var onloadCallback = http.onload;
var onerrorCallback = http.onerror;
http.onload = function(event) {
onloadCallback.call(this, event);
hideLoadingIndicator();
}
http.onerror = function(event) {
onerrorCallback.call(this.event);
hideLoadingIndicator();
}
}
I'm testing my webpage in browsers and it seems that some bits are not working in firefox and opera. I assume it's caused by jQuery used on my page.
This is my website: http://freshbeer.lv/ht/index.html
At the bottom of the source code you can find all jQuery code used (mainly to call and apply plugins). I'm having trouble to determine what is wrong, as there are no errors shown in console (firefox 20.0) Main dysfunctions are
player, just compare how it works in chrome and than check it out in firefox or opera, first of all it doesn't show "..." which signifies loading, secondly once you click play on another player, both songs keep playing, where as in other browsers first song would pause, so there would be only one song playing.
advertisement should have margins on top and bottom calculated by jQuery, it doesn't in opera and firefox.
So Am I missing something? Maybe I need to apply certain code standards?
That seems to be all, however I can't be sure.
I'll put code written by me here (most likely issue is in it), note, there are several jQuery plugins included above it.
<script type="text/javascript">
//Audio Player
audiojs.events.ready(function () {
var as = audiojs.createAll();
$('audio').each(function () {
var myAudio = this;
this.addEventListener('play', function () {
$('audio').each(function () {
if (!(this === myAudio)) {
this.pause();
}
});
});
});
});
$(document).ready(function() {
//Responsive add margins
function addMargin () {
var add = $(".advert");
var addMargin = add.css("margin-left");
add.css({
"margin-top": addMargin,
"margin-bottom": addMargin
});
}
addMargin();
$(window).resize(addMargin);
//Responsive Grid
var MusicGrid = (function() {
var $musicGridContainer = $('.grid'),
init = function() {
changeMusicGrid();
initEvents();
initPlugins();
},
changeMusicGrid = function() {
var w_w = $(window).width();
if (w_w <= 765) n = 1;
else if (w_w <= 1180) n = 2;
else n = 3;
},
initEvents = function() {
$(window).on('smartresize.MusicGrid', function(event) {
changeMusicGrid();
});
},
initPlugins = function() {
$musicGridContainer.imagesLoaded(function() {
setTimeout(function() {
$musicGridContainer.masonry({
itemSelector: '.article',
columnWidth: function(containerWidth) {
return containerWidth / n;
},
isAnimated: true,
animationOptions: {
duration: 150
}
});
}, 500);
});
};
return {
init: init
};
})();
MusicGrid.init();
});
//Preload Content
function preloadCode() {
if (preloadCode.done) return;
preloadCode.done = true;
clearTimeout(t);
$(".preloader").css("display", "none");
$(".grid").css({ opacity: 0, visibility: 'visible', marginTop: 20 }).animate({ marginTop: 0, opacity: 1 }, 550);
$('.article[id^="article-"]').each(function () {
if (parseInt(this.id.replace('article-', '')) % 3 === 0) {
$('#' + this.id).css({ marginTop: 50 }).animate({ marginTop: 0 }, 350);
} else if (parseInt(this.id.replace('article-', '')) % 2 === 0) {
$('#' + this.id).css({ marginTop: 100 }).animate({ marginTop: 0 }, 400);
} else {
$('#' + this.id).css({ marginTop: 150 }).animate({ marginTop: 0 }, 450);
}
});
$(".footer").css("display", "block");
}
var t = setTimeout(preloadCode, 6000);
$(window).load(preloadCode);
</script>
1. advertisement should have margins on top and bottom calculated by jQuery, it doesn't in opera and firefox. So Am I missing something? Maybe I need to apply certain code standards?
Your element has auto margins, so, depending on the browser, .css('margin-left') might return different values, including 0.
I recommend using the JsSizes library which is a lightweight plugin that will allow you to get the actual margins in pixels.
2. player, just compare how it works in chrome and than check it out in firefox or opera, first of all it doesn't show "..." which signifies loading, secondly once you click play on another player, both songs keep playing, where as in other browsers first song would pause, so there would be only one song playing.
Firefox and Opera don't support mp3 in their audio element, so it gets replaced by a flash object. Therefore you can't listen to those DOM events anymore.
Although, according to their annotated source code, the flash object has public methods play(), pause(), and isPlaying.
I'd recommend listening a click event on the 'play-pause' button and use these functions. Like this :
var as = ''; // You're going to have to make your as variable global to access it outside of your function.
audiojs.events.ready(function () {
as = audiojs.createAll();
$('.audiojs .play-pause').click(function(){ //Listening to the click event
var thisIndex = $(this).parents('.audiojs').index('.audiojs'); // When you create several players, as is an array of instances of players. Here we're finding the DOM index of the player so it reflects its position in the as array.
$.each(as, function(index,val){ //then, for each instance of players in the as array
if ( index != thisIndex && as[index].playing ) as[index].pause(); //If the player is already playing, and its index is different than the one we just clicked on, pause it !
});
});
});
I have an overlay script that pops up when a link like:
<a id="b1" href="page.html">link</a>
is used. The problem is that I need multiple links but can't use the same ID.
Here is the code:
$(function(){
$('#b1').frameWarp();
});
I have tried replace #b1 with .b1 and a.b1 and using class instead of ID. This works fine on the first link but any subsequent links clicked cause the first page clicked to open again. I think there is a conflict with classes already being used in the script for the overlay.
Is there a way I can use onclick in to get this to work the same way?
The script is from a plugin but here is the rest of it:
(function($){
// Private varialble deffinitions
var body = $('body'),
win = $(window),
popup, popupBG;
var frameCache = {};
var frameCacheDiv = $('<div class="frameCacheDiv">').appendTo('body');
var currentIframe;
// The main plugin code
$.fn.frameWarp = function(settings){
// Supplying default settings
settings = $.extend({
cache: false,
url: '',
width:600,
height:500,
closeOnBackgroundClick: true,
onMessage:function(){},
onShow:function(){}
}, settings);
this.on('click',function(e){
e.preventDefault();
var elem = $(this),
offset = elem.offset();
// The center of the button
var buttonCenter = {
x: offset.left - win.scrollLeft() + elem.outerWidth()/2,
y: offset.top - win.scrollTop() + elem.outerHeight()/2
};
// The center of the window
var windowCenter = {
x: win.width()/2,
y: win.height()/2
};
// If no URL is specified, use the href attribute.
// This is useful for progressively enhancing links.
if(!settings.url && elem.attr('href')){
settings.url = elem.attr('href');
}
// The dark background
popupBG = $('<div>',{'class':'popupBG'}).appendTo(body);
popupBG.click(function(){
if(settings.closeOnBackgroundClick){
hide();
}
}).animate({ // jQuery++ CSS3 animation
'opacity':1
},400);
// The popup
popup = $('<div>').addClass('popup').css({
width : 0,
height : 0,
top : buttonCenter.y,
left : buttonCenter.x - 35
});
// Append it to the page, and trigger a CSS3 animation
popup.appendTo(body).animate({
'width' : settings.width,
'top' : windowCenter.y - settings.height/2,
'left' : windowCenter.x - settings.width/2,
'border-top-width' : settings.height,
'border-right-width' : 0,
'border-left-width' : 0
},200,function(){
popup.addClass('loading').css({
'width': settings.width,
'height': settings.height
});
var iframe;
// If this iframe already exists in the cache
if(settings.cache && settings.url in frameCache){
iframe = frameCache[settings.url].show();
}
else{
iframe = $('<iframe>',{
'src' : settings.url,
'css' : {
'width' : settings.width,
'height' : settings.height,
}
});
// If the cache is enabled, add the frame to it
if(settings.cache){
frameCache[settings.url] = iframe;
iframe.data('cached',true);
settings.onShow();
}
else{
// remove non-cached iframes
frameCacheDiv.find('iframe').each(function(){
var f = $(this);
if(!f.data('cached')){
f.remove();
}
});
}
iframe.ready(function(){
frameCacheDiv.append(iframe);
setUpAPI(iframe, settings);
settings.onShow();
});
}
currentIframe = iframe;
});
});
return this;
};
// Helper Functions
function hide(){
if(currentIframe){
currentIframe.hide();
currentIframe = null;
}
popupBG.remove();
popup.remove();
}
function setUpAPI(iframe, settings){
if(sameOrigin(settings.url)){
// Exposing a minimal API to the iframe
iframe[0].contentWindow.frameWarp = {
hide: hide,
sendMessage:function(param){
return settings.onMessage(param);
}
};
}
}
function sameOrigin(url){
// Compare whether the url belongs to the
// local site or is remote
return (getOrigin(url) == getOrigin(location.href));
}
function getOrigin(url){
// Using an anchor element to
// parse the URL
var a = document.createElement('a');
a.href = url;
return a.protocol+'//'+a.hostname;
}
})(jQuery);
Try this:
link1
link2
link3
Have not tried it but should work