Javascript 如何从srcset中确定最高分辨率图像

Javascript 如何从srcset中确定最高分辨率图像,javascript,jquery,image,url,srcset,Javascript,Jquery,Image,Url,Srcset,假设我有一个图像为 <img srcset="large.jpg 1400w, medium.jpg 700w, small.jpg 400w" sizes="(min-width: 700px) 700px, 100vw" alt="A woman reading"> 现在,这也可以是类似于 <img srcset="large.jpg 2x, medium.jpg 1.3x, small.jpg 0.8x" sizes="(min-wi

假设我有一个图像为

<img srcset="large.jpg 1400w, medium.jpg 700w, small.jpg 400w"
     sizes="(min-width: 700px) 700px, 100vw"
     alt="A woman reading">


现在,这也可以是类似于

<img srcset="large.jpg 2x, medium.jpg 1.3x, small.jpg 0.8x"
     sizes="(min-width: 700px) 700px, 100vw"
     alt="A woman reading">


另外,(不是有效的HTML)



现在如何提取具有最高分辨率图像的URL。
我曾想过拆分srcset,然后提取大小,但问题是大小可以是
1200w
格式,也可以是
2x
格式,或者两者都是,我不知道如何区分这是
1200w
格式还是
2x
格式,即使我知道是什么,如何比较它们以确定最大尺寸。


我希望我能展示我已经尝试过的东西,但是关于如何做到这一点,我脑子里没有任何想法

首先,您的HTML代码是无效的,因为您不能将
srcset
x
w
描述符混合使用。选择一个,但不要同时选择两个

1)除非下载所有图像,否则您无法知道哪个图像更大,当然,如果服务器端支持,您可以对每个图像执行
HEAD
请求,并检查
Content Length
header属性。这并不容易,你得到的只是以字节为单位的图像大小,而不是它的尺寸,但这是一个很好的近似值。大致如下:

var sizes = [];

// Peform this for each UR...
$.ajax({
    type: "HEAD",
    url: imageUrl,
    success: function(data, textStatus, request) {
        sizes.push({
            url: imageUrl,
            size: parseInt(request.getResponseHeader("Content-Length"));
        });
    }
});
您只需拆分
srcset
属性并忽略大小部分即可获得URL(我相信对regex有更好了解的人可以做得更好):

调用可以使用队列和
$(document.queue()
jQuery方法并行完成,或者更容易地按顺序完成

这并不是总能做到的(可能是因为服务器不接受
HEAD
或者由于压缩和/或纵横比,图像大小太相似),然后您必须解析
srcset
属性

2)首先让我们看一看像素密度描述符
x的概念证明(读作:它既不完整也不高效):用空白拆分
。拆分(//)
,然后选择最大的一个

// Read value from tag...this is just for testing
var srcset = "small.jpg 0.8x, large.jpg 1.5x, medium.jpg 1.3x";

var biggestImage = "";
var highestPixelDensity = 1;

for (var descriptor of srcset.split(/,/)) {
    var parts = descriptor.trim().split(/ /);

    // Here we check only for pixel density, see later for
    // width descriptor but code is straightforward
    var pixelDensity = parseFloat(parts[1].substring(-1));
    if (pixelDensity > highestPixelDensity) {
        biggestImage = parts[0];
        highestPixelDensity = pixelDensity;
    }
}
宽度描述符
w
的情况有所不同,因为它与
大小相关,所以首先需要确定应用哪一个。它有点复杂,但使用
window.matchMedia()
很容易(同样,它不是完整的代码,只是一个概念的说明性证明):

现在您已经有了所需的大小(例如,检查其单位并适当地转换它),并且您已经完成了将其与从
srcset
提取的宽度描述符一起使用

请注意,除非下载图像,否则您不知道哪个图像更大。您可以假设,较高的像素密度
x
或较高的宽度描述符
w
(但它必须根据
大小
属性内容计算,屏幕越大,图像越大)将为您提供越大的像素密度。当然这是一个假设,在某些情况下它可能会失败。要确定必须使用哪种方法,只需:

var isPixelDensity = srcset.trim().substr(-1) === "x";

只要…把这些示例放在一起,处理丢失的角落、基本错误处理和特定于浏览器的问题,您就完成了…

我需要对生成的wordpress图像和相关的
srcset

Wordpress创建
srcset
的方式是先创建较小的图像,然后继续增加,直到在
srcset
中获得最大的图像

wordpress生成的图像代码示例:

<img width="300" height="221" src="http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-300x221.jpg" class="vc_single_image-img attachment-medium" alt="" srcset="http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-300x221.jpg 300w, http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-768x566.jpg 768w, http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-1024x755.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px">
我是Javascript/jQuery新手,所以如果我选择了更长的路线,请原谅。;)

欢迎对代码进行任何添加/更新。

以下是我使用的:

 static getHighestResImg(element){
        if(element.getAttribute('srcset')){
            let highResImgUrl = '';
            let maxRes = 0;
            let imgWidth,urlWidthArr;
            element.getAttribute('srcset').split(',').forEach((item)=>{
                urlWidthArr = item.trim().split(' ');
                imgWidth = parseInt(urlWidthArr[1]);
                if(imgWidth > maxRes) {
                    maxRes = imgWidth;
                    highResImgUrl = urlWidthArr[0];
                }

            });

            return highResImgUrl;
        }else{
          return  element.getAttribute('src');
        }

    }

这似乎是一个XY问题。为什么你需要这个?还有,为什么你不能假设它是列表中的第一项?@JanDvorak XY problem??我必须在用户的页面上插入一个脚本,然后在弹出窗口中分别向他显示页面上可用的图像。现在我可以简单地使用SRC,但它会给我默认的图像,但是我想得到最好的图像。@JanDvorak第一个图像是最大的吗?@JanDvorak这是否是XY问题并不重要,只要问题清楚。非常感谢
但是很抱歉,我没有得到最后一行。我的理解是,如果我的屏幕大小与
mediaQuery
匹配,那么这就是我需要的。如果我没弄错的话,恐怕我不需要它,只需要最大/最大的图像,不管
mediaQuery
。如何做到这一点?除非您下载所有图片,否则您不知道确切的图片大小,但您可以假设更大的图片将用于更大的屏幕(宽度…),然后当您有一个候选大小(从大小属性)时,您将选择宽度更大的图片(从srcset属性)。对于宽度描述符,这些属性一起工作(但对于像素密度,大小可以忽略)不知道您是否也可以帮助我…?请给我一个机会,让我发布一个答案,但您可能想看看其他问题:。这不是那么容易,但如果没有扩展(除非你可以管理他们的部署并限制到Chrome),当url中有逗号时,这将失败,这只是一个完美的答案!!!!!谢谢你@Sarasrangit
var isPixelDensity = srcset.trim().substr(-1) === "x";
<img width="300" height="221" src="http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-300x221.jpg" class="vc_single_image-img attachment-medium" alt="" srcset="http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-300x221.jpg 300w, http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-768x566.jpg 768w, http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-1024x755.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px">
jQuery('img.my_image_class_to_target').each(function () {
    var mysrcset = jQuery(this).attr('srcset');
    if (typeof mysrcset !== 'undefined'){ //checking if the srcset attribute is defined
        lastsrcset = mysrcset.split(',');
        lastsrc = lastsrcset[(lastsrcset.length - 1)];
        lastpuresrc = lastsrc.split(' ');
        mysrc = lastpuresrc[1];

    } else { //when srcset is not defined in case of small images
    var mysrcset = jQuery(this).attr('src');
        mysrc = mysrcset;
    }

    // display or use src of biggest image src
    console.log(mysrc);

});
 static getHighestResImg(element){
        if(element.getAttribute('srcset')){
            let highResImgUrl = '';
            let maxRes = 0;
            let imgWidth,urlWidthArr;
            element.getAttribute('srcset').split(',').forEach((item)=>{
                urlWidthArr = item.trim().split(' ');
                imgWidth = parseInt(urlWidthArr[1]);
                if(imgWidth > maxRes) {
                    maxRes = imgWidth;
                    highResImgUrl = urlWidthArr[0];
                }

            });

            return highResImgUrl;
        }else{
          return  element.getAttribute('src');
        }

    }