首先,您的 HTML 代码无效,因为您不能将 x 和 w 描述符混合用于 srcset。选择其中之一,但不要同时选择两者。
1) 除非您全部下载它们,否则您无法知道哪个图像更大,当然您可以 - 当支持服务器端时 - 对每个图像执行 HEAD 请求并检查 @987654328 @标头属性。这并不容易,你得到的只是图像大小(以字节为单位),而不是它的尺寸,但它是一个很好的近似值。大致是这样的:
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(我相信对正则表达式有更好了解的人可以做得更好):
var urls = srcset.replace(/\s+[0-9]+(\.[0-9]+)?[wx]/g, "").split(/,/);
调用可以并行完成,或者 - 更容易 IMO - 使用队列和 $(document).queue() jQuery 方法顺序完成。
这不能总是完成(可能是因为服务器不接受 HEAD 或者由于压缩和/或纵横比,图像大小太相似)然后你必须解析 @987654334 @ 属性。
2) 让我们首先看一个概念证明(读作:它不完整也不高效),您可以为像素密度描述符x 做些什么:split有超过空格.split(/ /),然后选择最大的。
// 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 的情况有所不同,因为它与sizes 相关,那么您首先需要确定应用哪个。这有点复杂,但使用window.matchMedia() 很容易做到(同样它不是完整的代码,而是一个说明性的概念证明):
// Read this from tag...
var sizes = "(min-width: 800px) 700px, (min-width: 700px) 300px";
for (var descriptor of sizes.split(/,/)) {
// Love this from https://stackoverflow.com/a/651646/1207195
var imageSize = descriptor.split(/[, ]+/).pop();
// You still need to handle last item special case (where there is not media query).
var mediaQuery = descriptor.substring(-imageSize.length);
// You can stop with first matched media query, you have your required imageSize
var isMatch = window.matchMedia(mediaQuery).matches;
}
现在您已经获得了所需的大小(检查其单位并进行适当的转换,例如this post),并且您可以将其与从srcset 提取的宽度描述符一起使用。
请注意,除非您下载它,否则您不知道哪个图像更大。你可以假设更高的像素密度x或更高的宽度描述符w(但它必须根据sizes属性内容计算,更大的屏幕使用更大的图像)会给你较大的一个。当然这是一个假设,在某些情况下它可能会失败。要确定必须使用哪一个,只需:
var isPixelDensity = srcset.trim().substr(-1) === "x";
只需...将这些示例放在一起,处理丢失边角的情况、基本错误处理和浏览器特定问题,您就完成了...