Problems with iframe when used more than once on the page











up vote
7
down vote

favorite












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;"><a href="javascript:void(0)" id="quickview-close"><i class="glyphicon glyphicon-remove"></i></a></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.










share|improve this question




























    up vote
    7
    down vote

    favorite












    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;"><a href="javascript:void(0)" id="quickview-close"><i class="glyphicon glyphicon-remove"></i></a></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.










    share|improve this question


























      up vote
      7
      down vote

      favorite









      up vote
      7
      down vote

      favorite











      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;"><a href="javascript:void(0)" id="quickview-close"><i class="glyphicon glyphicon-remove"></i></a></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.










      share|improve this question















      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;"><a href="javascript:void(0)" id="quickview-close"><i class="glyphicon glyphicon-remove"></i></a></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.







      javascript magento iframe modal-dialog prototypejs






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 3:16

























      asked Nov 9 at 2:16









      Denis Spalenza

      4182827




      4182827
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          +25










          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






          share|improve this answer























          • I tried iframe.contentWindow.location.reload(true);. When iframe was opened, reload works, but when iframe is hide, it not works (reloaded but with de js problem).
            – Denis Spalenza
            Nov 12 at 15:09












          • Ok, I updated my answer.
            – Gillsoft AB
            Nov 12 at 16:11











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53218905%2fproblems-with-iframe-when-used-more-than-once-on-the-page%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          2
          down vote



          +25










          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






          share|improve this answer























          • I tried iframe.contentWindow.location.reload(true);. When iframe was opened, reload works, but when iframe is hide, it not works (reloaded but with de js problem).
            – Denis Spalenza
            Nov 12 at 15:09












          • Ok, I updated my answer.
            – Gillsoft AB
            Nov 12 at 16:11















          up vote
          2
          down vote



          +25










          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






          share|improve this answer























          • I tried iframe.contentWindow.location.reload(true);. When iframe was opened, reload works, but when iframe is hide, it not works (reloaded but with de js problem).
            – Denis Spalenza
            Nov 12 at 15:09












          • Ok, I updated my answer.
            – Gillsoft AB
            Nov 12 at 16:11













          up vote
          2
          down vote



          +25







          up vote
          2
          down vote



          +25




          +25




          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






          share|improve this answer














          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







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 18 at 10:45

























          answered Nov 11 at 10:44









          Gillsoft AB

          3,33021232




          3,33021232












          • I tried iframe.contentWindow.location.reload(true);. When iframe was opened, reload works, but when iframe is hide, it not works (reloaded but with de js problem).
            – Denis Spalenza
            Nov 12 at 15:09












          • Ok, I updated my answer.
            – Gillsoft AB
            Nov 12 at 16:11


















          • I tried iframe.contentWindow.location.reload(true);. When iframe was opened, reload works, but when iframe is hide, it not works (reloaded but with de js problem).
            – Denis Spalenza
            Nov 12 at 15:09












          • Ok, I updated my answer.
            – Gillsoft AB
            Nov 12 at 16:11
















          I tried iframe.contentWindow.location.reload(true);. When iframe was opened, reload works, but when iframe is hide, it not works (reloaded but with de js problem).
          – Denis Spalenza
          Nov 12 at 15:09






          I tried iframe.contentWindow.location.reload(true);. When iframe was opened, reload works, but when iframe is hide, it not works (reloaded but with de js problem).
          – Denis Spalenza
          Nov 12 at 15:09














          Ok, I updated my answer.
          – Gillsoft AB
          Nov 12 at 16:11




          Ok, I updated my answer.
          – Gillsoft AB
          Nov 12 at 16:11


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53218905%2fproblems-with-iframe-when-used-more-than-once-on-the-page%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Florida Star v. B. J. F.

          Danny Elfman

          Lugert, Oklahoma