我需要动态加载横幅图像到HTML5应用程序,并希望几个不同的版本,以适应屏幕宽度。我不能正确地确定手机的屏幕宽度,所以我能想到的唯一方法是添加div的背景图像,并使用@media来确定屏幕宽度并显示正确的图像。

例如:

 <span style="background-image:particular_ad.png; @media (max-width:300px){background-image:particular_ad_small.png;}"></span>

这可能吗,或者有人有其他建议吗?


当前回答

Yes, this is quite possible but only as using javascript event attributes in HTML elements. Here you have to keep in mind that not every html tag element could fire every js event, which can listen for changes to the DOM, such as onresize or execute js code, when DOM is loaded, as onload event does. In the example above I use body and img tags as they are capable to fire img only onload event, body tag both onload and onresize. Depending on the event, you could choose the approach to resolve your issue, as using the code from the examples.

使用body标签:

<body onload="
const mediaQueryList = window.matchMedia('(max-width: 600px)');
function screenTest(e) {
 if (e.matches) {
 /* the viewport is 600 pixels wide or less */
  console.log('This is a narrow screen — 600px wide or less.');
  document.body.style.backgroundColor = 'pink';
 } else {
 /* the viewport is more than 600 pixels wide */
  console.log('This is a wide screen — more than 600px wide.');
  document.body.style.backgroundColor = 'aquamarine';
 }
}
mediaQueryList.addEventListener('change', screenTest);
" onresize="
if (document.documentElement.offsetWidth <= 600) {
/* the viewport is 600 pixels wide or less */
console.log('This is a narrow screen — 600px wide or less.');
document.body.style.backgroundColor = 'pink';
} else {
/* the viewport is more than 600 pixels wide */
 console.log('This is a wide screen — more than 600px wide.');
 document.body.style.backgroundColor = 'aquamarine';
}
"><!-- Some other code goes here --></body>

使用img标签:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==" 
width="100%" style="width: 100vw; height: 1px;" 
alt="" height="1"  
onload="
   const mediaQueryList = window.matchMedia('(max-width: 600px)');
   function screenTest(e) {
     if (e.matches) {
        /* the viewport is 600 pixels wide or less */
        console.log('This is a narrow screen — 600px wide or less.');
        document.body.style.backgroundColor = 'pink';
     } else {
        /* the viewport is more than 600 pixels wide */
        console.log('This is a wide screen — more than 600px wide.');
        document.body.style.backgroundColor = 'aquamarine';
     }
   }
   mediaQueryList.addEventListener('change', screenTest);
" />

您还应该记住,如果您决定使用这种在HTML信件中嵌入mediaquery css的方式,它可能不会通过邮件服务器的黑名单,这在大多数情况下会减少此类javascript事件。但对于一些ajax或横幅,一些动态应用程序,这种方法应该没有问题。

其他回答

通过使用像Breakpoint for Sass这样的东西,可以实现内联媒体查询

这篇博客文章很好地解释了内联媒体查询如何比单独的块更易于管理:There Is No Breakpoint

与内联媒体查询相关的是“元素查询”的思想,一些有趣的阅读是:

关于元素媒体查询的思考 媒体查询是一种Hack 媒体查询不是答案:元素查询填充 If else块

我试着测试了一下,似乎没有效果,但我很好奇苹果为什么要用它。我刚刚在https://linkmaker.itunes.apple.com/us/上,注意到在生成的代码中,如果你选择“大按钮”单选按钮,他们正在使用内联媒体查询。

<a href="#" 
    target="itunes_store" 
    style="
        display:inline-block;
        overflow:hidden;
        background:url(#.png) no-repeat;
        width:135px;
        height:40px;
        @media only screen{
            background-image:url(#);
        }
"></a>

注:增加了换行符的可读性,原始生成的代码是最小化的

内联样式目前只能包含声明(属性:值对)。

您可以在文档的头部部分使用带有适当媒体属性的样式元素。

您可以使用image-set()

<div style="
  background-image: url(icon1x.png);
  background-image: -webkit-image-set(  
    url(icon1x.png) 1x,  
    url(icon2x.png) 2x);  
  background-image: image-set(  
    url(icon1x.png) 1x,  
    url(icon2x.png) 2x);">

问题

不,媒体查询不能以这种方式使用

<span style="@media (...) { ... }"></span>

解决方案

但是,如果您希望提供一个动态可用且响应性强的特定行为,则可以使用样式标记而不是属性。

e.i.

<style scoped>
.on-the-fly-behavior {
    background-image: url('particular_ad.png'); 
}
@media (max-width: 300px) {
    .on-the-fly-behavior {
        background-image: url('particular_ad_small.png');
    }
}
</style>
<span class="on-the-fly-behavior"></span>

在CodePen上查看实时工作的代码

以我的博客为例,我在<head> <link>声明后面为CSS注入了一个<style>标记,它包含了一个文本区域的内容,在我写一篇文章时,它提供了一个真正的内容textarea,用于创建额外的类。

注意:scoped属性是HTML5规范的一部分。如果你不使用它,验证器会责备你,但是浏览器目前不支持真正的目的:将<style>的内容限定在直接的父元素和该元素的子元素上。如果<style>元素在<head>标记中,Scoped不是强制性的。


更新:我建议总是在移动第一的方式使用规则,所以以前的代码应该是:

<style scoped>
/* 0 to 299 */
.on-the-fly-behavior {
    background-image: url('particular_ad_small.png'); 
}
/* 300 to X */
@media (min-width: 300px) { /* or 301 if you want really the same as previously.  */
    .on-the-fly-behavior {   
        background-image: url('particular_ad.png');
    }
}
</style>
<span class="on-the-fly-behavior"></span>