Jquery Mobile:弹出动态加载的图像不会在第一次单击时居中(Jquery Mobile: popup with dynamically loaded image not centered on first click)

当我第一次单击链接时,弹出窗口不会居中,而是第二次弹出窗口。 我已经按照其他问题的答案来说使用'positionTo': 'window' ,但问题是我是否拥有它。 还有其他解决方案可以使用超时,但我不想使用它。

function setImage()
{
  $('#image-popup img').attr('src', 'https://upload.wikimedia.org/wikipedia/commons/7/7b/Orange-Whole-%26-Split.jpg');

  $('#image-popup img').on('load', function() {
    console.log('loaded image from click');
    $('#image-popup').popup('reposition', {'positionTo': 'window'});
  });
} 
  
<html>
<head>

  <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
  <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

</head>
  
<body>

  <a href='#image-popup' data-rel="popup" data-position-to="window" onclick='setImage()'>Open image</a>

  <div id='image-popup' data-role='popup'>
    <a href="#" data-rel="back" class="ui-btn ui-corner-all ui-shadow ui-btn-a ui-icon-delete ui-btn-icon-notext ui-btn-right">Close</a>
    <img class="popphoto" src="" alt="orange">
  </div>

</body>
  
</html> 
  
 

请注意,如果多次运行,则需要清空缓存并进行硬重新加载。

When I click the link the first time, the popup is not centered, but the second time it is. I've followed the answers of other questions that say to use 'positionTo': 'window', but the problem happens whether I have it or not. There are other solutions that say to use a timeout, but I don't want to use that.

function setImage()
{
  $('#image-popup img').attr('src', 'https://upload.wikimedia.org/wikipedia/commons/7/7b/Orange-Whole-%26-Split.jpg');

  $('#image-popup img').on('load', function() {
    console.log('loaded image from click');
    $('#image-popup').popup('reposition', {'positionTo': 'window'});
  });
} 
  
<html>
<head>

  <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
  <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

</head>
  
<body>

  <a href='#image-popup' data-rel="popup" data-position-to="window" onclick='setImage()'>Open image</a>

  <div id='image-popup' data-role='popup'>
    <a href="#" data-rel="back" class="ui-btn ui-corner-all ui-shadow ui-btn-a ui-icon-delete ui-btn-icon-notext ui-btn-right">Close</a>
    <img class="popphoto" src="" alt="orange">
  </div>

</body>
  
</html> 
  
 

Note that you'll need to empty the cache and hard reload if you run this multiple times.

最满意答案

您在下载图像之前打开弹出窗口,没有解决方案,因为框架不知道图像的大小,因此弹出窗口的大小。

请注意:如果您在img.onload中打开弹出窗口,弹出窗口将以正确的大小显示在正确的位置,即以具有图像大小的窗口为中心:

$('#image-popup img').on('load', function() { $('#image-popup').popup('open', {'positionTo': 'window'}); });

所以,我认为你的问题是这样的: “如何尽快打开弹出窗口 - 给用户一个反馈 - 但是尺寸正确,而且图像还在下载时?”

现在,我的建议是通过额外的XHR请求尽可能快地获得图像大小。 显然,这也是网络条件所允许的快速,但我们总是可以简单地显示加载器,而XHR只会得到前几个字节,而不是整个图像数据。

为此,我们需要更改弹出窗口的打开方式:

HTML:

<a href='#' onclick='openPopupWithSize("https://upload.wikimedia.org/wikipedia/commons/7/7b/Orange-Whole-%26-Split.jpg"); return false;'>Open image</a>

JavaScript - 请参阅注释:

// helper function to get byte value function readByte(data, offset) { return data.charCodeAt(offset) & 0xff; } // request size, assign src, open popup & look how the image is downloading function openPopupWithSize(pngUrl){ // clean-up before, if we have to deal with some more images $('#image-popup img').attr('src', ""); // set various parameters var xhr = new XMLHttpRequest(); xhr.open("GET", pngUrl, true); // just get only what is strictly necessary xhr.setRequestHeader("range', 'bytes=0-23"); xhr.overrideMimeType("text\/plain; charset=x-user-defined"); xhr.onprogress = function(e){ // read the few bytes needed to get width & height of the png var data = e.currentTarget.response; // offset are: 16 & 20 - see PNG specifications var w = readByte(data, 19) | (readByte(data, 18) << 8) | (readByte(data, 17) << 16) | (readByte(data, 16) << 24); var h = readByte(data, 23) | (readByte(data, 22) << 8) | (readByte(data, 21) << 16) | (readByte(data, 20) << 24); // set size of the container, will be reset by the framework as needed $('#image-popup-popup').css("width", w+"px"); $('#image-popup-popup').css("height", h+"px"); // assign image src like you did it in your example $('#image-popup img').attr('src', pngUrl); // finally, open the popup - JQM is allowed now to reposition correctly $('#image-popup').popup("open", {"positionTo": "window"}); }; xhr.send(null); }

如果您需要,请随时在评论中分享您的想法。

You are opening the popup before the image has been downloaded, there is no solution, as the framework is not knowing the size of the image, and therefore which size the popup shall be.

Please, note: if you open the popup in img.onload, the popup will be displayed with the right size at the right position, i.e. centered to the window with the size of the image:

$('#image-popup img').on('load', function() { $('#image-popup').popup('open', {'positionTo': 'window'}); });

So, i think your question here is something like: "How to open the popup as fast as possible - to give the user a feedback - but with the correct size, and moreover while the image is still downloading?"

Now, my proposal is to get the image size as fast as possible, through an extra XHR request. Obviously, this is also just fast as allowed by the network condition, but we always have the possibility to show briefly the loader, and the XHR will get just only the first few bytes, not the whole image data.

To do that, we need to change the way the popup is opened:

HTML:

<a href='#' onclick='openPopupWithSize("https://upload.wikimedia.org/wikipedia/commons/7/7b/Orange-Whole-%26-Split.jpg"); return false;'>Open image</a>

JavaScript - see comments:

// helper function to get byte value function readByte(data, offset) { return data.charCodeAt(offset) & 0xff; } // request size, assign src, open popup & look how the image is downloading function openPopupWithSize(pngUrl){ // clean-up before, if we have to deal with some more images $('#image-popup img').attr('src', ""); // set various parameters var xhr = new XMLHttpRequest(); xhr.open("GET", pngUrl, true); // just get only what is strictly necessary xhr.setRequestHeader("range', 'bytes=0-23"); xhr.overrideMimeType("text\/plain; charset=x-user-defined"); xhr.onprogress = function(e){ // read the few bytes needed to get width & height of the png var data = e.currentTarget.response; // offset are: 16 & 20 - see PNG specifications var w = readByte(data, 19) | (readByte(data, 18) << 8) | (readByte(data, 17) << 16) | (readByte(data, 16) << 24); var h = readByte(data, 23) | (readByte(data, 22) << 8) | (readByte(data, 21) << 16) | (readByte(data, 20) << 24); // set size of the container, will be reset by the framework as needed $('#image-popup-popup').css("width", w+"px"); $('#image-popup-popup').css("height", h+"px"); // assign image src like you did it in your example $('#image-popup img').attr('src', pngUrl); // finally, open the popup - JQM is allowed now to reposition correctly $('#image-popup').popup("open", {"positionTo": "window"}); }; xhr.send(null); }

Please, feel free to share your thoughts in a comment, if this is what you need.

更多推荐