有 CSS ":drop-hover" 伪类吗?

Posted

技术标签:

【中文标题】有 CSS ":drop-hover" 伪类吗?【英文标题】:Is there a CSS ":drop-hover" pseudo-class? 【发布时间】:2017-08-08 18:51:13 【问题描述】:

说我有一个input type="file" 字段。可以在input 上放置一个文件(就像在 Firefox 中一样),而不是单击“浏览”并选择文件。

现在,我想对其进行一些自定义,方法是在即将将文件放入input 时更改字段的背景颜色。我不能真正使用:hover,因为即使你不拖放它也匹配。是否有 CSS(伪类)可以做到这一点?

如果要删除的文件不被接受,是否有 CSS 方法来设置不同的样式?比如说,如果该字段仅接受使用 accept 属性的 PNG 文件,如果您要在其上放置 PNG 文件,我会将字段设置为绿色,如果这是另一种类型的文件,则将其设置为红色。

今天有 CSS 方法来做这些吗? CSS 中是否有计划的方法(例如在即将到来的规范中/在当前规范中但未在任何地方实现)?

【问题讨论】:

它可能使用:invalid 伪选择器工作。至于“drop-hover”,不,不是单独使用 CSS... @Andrei 至少在目前实际使用:invalid 的想法(因为即使我没有想到,我实际上也想表明“正常选择的文件”也是不可接受的) 【参考方案1】:

更新:感谢@Renato 的评论,根据https://github.com/w3c/csswg-drafts/issues/2257,drop 伪类现在已经被删除了。


:drop:drop()伪类,目前处于Working Draft状态。

据[版主:删除垃圾邮件链接],浏览器支持不好。

对于“不接受文件被删除”的情况,:drop(invalid active) 预计将来会起作用。

【讨论】:

太棒了! CSS4 会带来(就像 CSS3 一样)很多很棒的特性 :) 谢谢,因为我在搜索时没有在规范中看到它 “文件被删除不被接受”听起来应该是 :drop(invalid active) 而不仅仅是 :drop(invalid),但我只是挑剔。 drop 伪类已被删除:github.com/w3c/csswg-drafts/issues/2257【参考方案2】:

我有同样的问题,但解决的方法与 nashcheez 略有不同。不过仍然使用 javascript(我在这里使用 jQuery 来简化事情):

function drag(ev) 
  ev.dataTransfer.setData("text", "foo");


function allowDrop(ev) 
  $(ev.target).attr("drop-active", true);
  ev.preventDefault();


function leaveDropZone(ev) 
  $(ev.target).removeAttr("drop-active");


function drop(ev) 
  ev.preventDefault();
  $(ev.target).removeAttr("drop-active");
  alert(ev.dataTransfer.getData("text"));
#draggableItem 
  height: 50px;
  width: 150px;
  background-color: #eee;


#dropZone 
  height: 50px;
  width: 150px;
  background-color: #efe;


#dropZone[drop-active=true] 
  box-shadow: inset 0px 0px 0px 2px #00C;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="draggableItem" draggable="true" ondragstart="drag(event);">Drag Me</div>

<div id="dropZone" ondragover="allowDrop(event);" ondragleave="leaveDropZone(event);" ondrop="drop(event);">Drop Here</div>

我已经在 Safari、Firefox 和 Chrome 上测试过这个,但我还没有尝试过 IE。我可能违反了自定义属性的规则,但它似乎在我等待 CSS4 时起作用。

【讨论】:

尽管这个关于 jQuery 的模因很有趣,但 TobyRush 以非常简洁的方式回答了这个问题。虽然不是最好的答案,但它仍然没有意图。一个称职的编码人员将能够翻译成 vanilla JS,而新手将能够使其在 jquery 中工作(尽管效率低下)。 很好的回答托比:它对我帮助很大,谢谢!我把它翻译回 jquery,因为我每天在工作中使用它(我的意思是在现实世界中),希望你不介意! ;-) 听到一些火箭科学家编码员谈论罕见或一次性事件的“效率”总是很有趣 @Polyducks jQuery 是整个网络的真正瘟疫。它比大多数图像都大,它添加了另一个 HTTP 请求,而且毫无意义,它是多余的,它比纯 JavaScript 慢,它窃取人们玩酷的想法以使其锁定它,它甚至与自身不兼容!当它第一次被创建以使来自 IE 和标准的代码工作时,他们制作了第三个完全不同的集合!从字面上和客观上看,它甚至比 WordPress 还要糟糕!实际的专业人士必须在搜索中添加-jquery 才能找到结果,这一事实证明了它是多么糟糕! 好吧@John - 不管你信不信,但 jQuery 帮助推动了网络的发展。当浏览器对 JavaScript 的支持不完整时,它提供了一致的 API。它允许无数专业人士和涉猎者在所有浏览器中提供功能。时至今日,如果你不是程序员或者时间/资源/技能有限,只是想快速为你的网页添加一些很酷的功能,jQuery 会让你摆脱困境。 jQuery 是否应该在现代应用程序中使用 - 不,绝对不是。但是对于不需要 Angular、React、Vue、Svelte 等的任何较小的东西 - 它非常适合。【参考方案3】:

目前绝对没有纯CSS跨浏览器解决方案可以在将元素拖放到浏览器窗口时更改元素的属性。

您在此处尝试执行的操作可以通过 Javascript/jQuery 使用隐藏容器来实现,并且仅当对象位于可拖动容器内时才显示它。

如果你想看看,我之前保存了这个演示:

var resetTimer;

var reset = function() 
  $('#d1').hide();
;

var f = function(e) 
  var srcElement = e.srcElement ? e.srcElement : e.target;

  if ($.inArray('Files', e.dataTransfer.types) > -1) 
    e.stopPropagation();
    e.preventDefault();

    e.dataTransfer.dropEffect = (srcElement.id == 'd1') ? 'copy' : 'none';

    if (e.type == "dragover") 
      if (resetTimer) 
        clearTimeout(resetTimer);
      
      $('#d1').show();
      console.info('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.types is ' + e.dataTransfer.types + '\n\ne.dataTransfer.files.length is ' + (e.dataTransfer.files ? e.dataTransfer.files.length : 0));

     else if (e.type == "dragleave") 
      resetTimer = window.setTimeout(reset, 25);
     else if (e.type == "drop") 
      reset();
      alert('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.files.length is ' + (e.dataTransfer.files ? e.dataTransfer.files.length : 0));
    
  
;

document.body.addEventListener("dragleave", f, false);
document.body.addEventListener("dragover", f, false);
document.body.addEventListener("drop", f, false);
body 
  border: 1px solid black;


#d0,
#d2 
  border: 1px solid black;


#d1 
  border: 1px solid black;
  display: none;
  background-color: red;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div id="d0">drag files onto this page</div>
  <div id="d1">-&gt; drop here &lt;-</div>
  <div id="d2">and stuff will happen</div>
</body>

【讨论】:

感谢您花时间制作 sn-p,但我想要一种 CSS 方式来完成。我非常喜欢在几个月/几年内忘记一件花哨的事情(直到它达到 CSS 规范),而不是添加对网站的依赖项和命令式代码来维护/通常有副作用。 嗯,这里的 js 代码不会有副作用,而且会是一个干净的解决方案。但是,如果您想等待纯 CSS 解决方案,这很酷。 我一直认为任何 JS 都有副作用:引入 jQuery 会与现有功能发生冲突吗?冒泡取消会破坏其他听众吗?它会带来安全问题(XSS/injections/etc)吗?它会在所有客户端上工作而不会使整个 JS 崩溃吗? JS 会优先于浏览器/用户的自定义样式吗?这就是为什么我更喜欢 CSS(主要是后者);) 各有各的! ;) 的确,不明智地使用 Javascript 会产生影响,但这就是您开始编写更好的 javascript 的方式。当您知道问题时,更容易找到最佳解决方案并且不再重复。 :) @John 如果您会阅读答案,它清楚地提到没有特定于 CSS 的方法可以做到这一点。然后,如果 OP 想要使用(OP 选择不使用),则提供了一个替代方案。在没有当前解决方案的情况下否决替代方案只会显示您的无知,并且会阻碍世界想要学习事物的方式。【参考方案4】:

没有 CSS 解决方案。我的问题是在拖动时更改颜色(Chrome 不支持,Opera 支持)

我是这样做的:

`<input id="xyz" type="FILE" value=""  
    ondragover ="this.style.backgroundColor='#88FF88';" 
    ondragleave="this.style.backgroundColor='#FFFFFF';" 
/> 
<input type="button" onclick="srFU(this);" value="send File" />`

【讨论】:

以上是关于有 CSS ":drop-hover" 伪类吗?的主要内容,如果未能解决你的问题,请参考以下文章

jQuery点击改变Class 修改css 样式

css控制表单长度

苹果电脑 font-weight=100 无效 html css 有办法解决吗

css里面如何把图片居中

手机屏幕自适应 不同屏幕宽度加载不同的css

type="text/css" 有啥用啊 ?