【问题标题】:Method to show native datepicker in Chrome在 Chrome 中显示本机日期选择器的方法
【发布时间】:2013-03-20 17:38:57
【问题描述】:

当浏览器不支持该字段时,我使用<input type="date"> 字段优雅地回退到 jQuery。最近,Chrome 开始提供原生日期选择器,这很棒。但是我发现很多用户错过了调出日历的小箭头,因此错过了一个简单的日历选择日期这一事实。

为了更直观,如果我可以在用户将焦点移至输入或单击另一个元素(如小日历图标)时调出原生日期选择器 UI,那就太好了。

我可以在 Chrome 中使用什么方法来触发 datepicker UI?

【问题讨论】:

  • 如果你问我想去掉那个胡萝卜图标,那我认为这是不可能的。
  • @defau1t 你可以用一些 CSS 去掉箭头,但我不认为这是被问到的。尽管为了更加一致,当用户单击日历时,可能会隐藏箭头并触发本机事件。
  • 不知道可以触发原生日期选择器打开,但可能有设置告诉它默认打开?
  • @nathan-p,不客气;)jsfiddle.net/e9bat3wh

标签: javascript html


【解决方案1】:

这是一种在用户单击字段本身时触发日期选择器的方法,因为计算机文盲用户不知道应该单击哪里:

input[type="date"] {
    position: relative;
}

/* create a new arrow, because we are going to mess up the native one
see "List of symbols" below if you want another, you could also try to add a font-awesome icon.. */
input[type="date"]:after {
    content: "\25BC"; 
    color: #555;
    padding: 0 5px;
}

/* change color of symbol on hover */
input[type="date"]:hover:after {
    color: #bf1400;
}

/* make the native arrow invisible and stretch it over the whole field so you can click anywhere in the input field to trigger the native datepicker*/
input[type="date"]::-webkit-calendar-picker-indicator {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: auto;
    color: transparent;
    background: transparent;
}

/* adjust increase/decrease button */
input[type="date"]::-webkit-inner-spin-button {
    z-index: 1;
}

 /* adjust clear button */
 input[type="date"]::-webkit-clear-button {
     z-index: 1;
 }
<input type="date">

链接:

【讨论】:

  • 如果你这样做,你会失去小向上/向下按钮的功能。
  • @Postlagerkarte 这就是为什么我描述了如何让它们在 sn-p 下再次工作。 sn-p 可以为您提供一个想法,您应该根据自己的需要进行调整。
  • 我已经调整了 sn-p,使其支持清除、向上和向下按钮。
  • @Andy 当我们打开数据选择器对话框点击输入区域时,同时我们如何能够在一次打开选择器时写入输入。
  • @GaurangDhorda 在某些浏览器中,您只能在原生日期选择器关闭时输入,因此您可以单击左侧不打开日期选择器输入或增加@987654326 中的left 的值@,但这带走了我回答的全部目的,即覆盖该字段以打开日期选择器。
【解决方案2】:

我认为您不能触发本机日历控件显示,但您可以将其突出显示一点:

input[type="date"]:hover::-webkit-calendar-picker-indicator {
  color: red;
}
input[type="date"]:hover:after {
  content: " Date Picker ";
  color: #555;
  padding-right: 5px;
}
input[type="date"]::-webkit-inner-spin-button {
  /* display: none; <- Crashes Chrome on hover */
  -webkit-appearance: none;
  margin: 0;
}
&lt;input type="date" /&gt;

您可以按原样阻止显示它,例如从文档中显示:

您可以通过以下代码禁用本机日历选择器:

<style>
::-webkit-calendar-picker-indicator {
    display: none;
}
</style>
<input type=date id=dateInput>
<script>
dateInput.addEventListener('keydown', function(event) {
    if (event.keyIdentifier == "Down") {
        event.preventDefault()
    }
}, false);
</script>

这是来自 Webkit 的文档,我从中获得了上述内容:

http://trac.webkit.org/wiki/Styling%20Form%20Controls

也许可以扭动它并使其显示日期选择器,但问问自己,您是否希望每次鼠标在页面上漫游时都飞出每个日历控件?

这个答案也很有帮助:

https://stackoverflow.com/a/15107073/451969

【讨论】:

  • 有办法做到这一点 - 看我的回答
  • @MichałŠrajer 不再
【解决方案3】:

2020 年编辑: chrome 似乎发生了变化,以前的答案不再有效。

我做了一个 hacky 解决方法,您可以根据自己的需要进行调整。

这种新方法会增加日历图标的大小以使其溢出其输入容器,从而完全覆盖它。您可以通过调整这些参数来调整位置和大小:

  top: -150%;
  left: -150%;
  width: 300%;
  height: 300%;

越大,越稳定。但仍然是 hack 之上的 hack


2020 年 7 月更新 - 适用于新 Chrome 的日历选择器

label {
  display: inline-block;
  position: relative;
  line-height: 0;
}
input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  border: 0;
  overflow: hidden;
  cursor: pointer;
}
input::-webkit-calendar-picker-indicator {
  position: absolute;
  top: -150%;
  left: -150%;
  width: 300%;
  height: 300%;
  cursor: pointer;
}
input:hover + button {
  background-color: silver;
}
<label>
  <input type="date">
  <button id="calendar_text">Search Date ?</button>
</label>

There's still an issue in Firefox, when a date is selected and you click near the right border, the input will clear, because the input's clear button is right there.


我调整了cinatic's solution 使其在 Chrome 上运行,并调整了Andy's trick 以适应 Chrome 在 2020 年的最新变化

Andy's trick:将 Chrome 的日期选择器的箭头扩展到整个输入

cinatic's solution:将输入隐藏在另一个元素之上

【讨论】:

  • 这太完美了,谢谢!!应该是公认的答案。
  • 感谢您的回答,我已经提出了一个更正的版本来摆脱 Firefox 问题。
  • 您应该在输入元素上设置 tabindex="-1" 以避免在有人使用键盘导航(TAB 键)时获得焦点
【解决方案4】:

诀窍是在输入元素上触发 F4 KeyboardEvent:

function openPicker(inputDateElem) {
    var ev = document.createEvent('KeyboardEvent');
    ev.initKeyboardEvent('keydown', true, true, document.defaultView, 'F4', 0);
    inputDateElem.dispatchEvent(ev);
}

var cal = document.querySelector('#cal');
cal.focus();
openPicker(cal);

这里是 jsfiddle:http://jsfiddle.net/v2d0vzrr/

顺便说一句,chrome 中有一个有趣的错误。如果您在单独的选项卡中打开 jsfiddle,日历弹出窗口将显示在当前选项卡上。 已经是reported了。

【讨论】:

  • initKeyboardEvent 已弃用,如果不使用initKeyboardEvent,是否有任何替代上述脚本的方法。
  • 至少在 chrome 中你应该使用 inputDateElem.focus();发货前
  • 这行不通,至少现在不行了。 MDN 状态 - Note: manually firing an event does not generate the default action associated with that event. For example, manually firing a key event does not cause that letter to appear in a focused text input. In the case of UI events, this is important for security reasons, as it prevents scripts from simulating user actions that interact with the browser itself. (developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent)
【解决方案5】:

参考Andy's answer,我将整个区域设置为可点击并删除了日历图标。

Andy 的 sn-p 中的结果在左侧有一个不可点击的小区域。 (Chrome 87.0.4280.66)

input.picker[type="date"] {
  position: relative;
}

input.picker[type="date"]::-webkit-calendar-picker-indicator {
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  color: transparent;
  background: transparent;
}
&lt;input class="picker" type="date"&gt;

【讨论】:

    【解决方案6】:

    对于桌面(和移动),将输入放置在具有相对定位和图标的 div 中,输入样式如下:

    input {
      position: absolute;
      opacity: 0;
    
      &::-webkit-calendar-picker-indicator {
        position: absolute;
        width: 100%;
      }
    }
    

    这会将选择器指示器拉伸到整个父 div 上,以便在您点击父 div 的图标和/或文本时始终显示日期控件。

    【讨论】:

      【解决方案7】:

      我认为人们经常希望使用另一个图标或元素来打开本机日期选择器框。

      我发现带有“click() 和 .focus()”的 javascript 解决方案仅在 webkit 和其他一些桌面浏览器中有效,但不幸的是不在 FireFox 中

      但也可以通过另一种方式,将 inputField 覆盖在图标元素(或任何你想使用的元素)上,并通过不透明度 0 使其无敌。

      移动设备上非常有效,对于桌面设备,我建议您将 onclick 事件添加为后备 "$('.dateInpuBox').click( ).focus()"

          .myBeautifulIcon {
            position: relative;
            width: 50px;
          }
          .dateInputBox {
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            opacity: 0;
          }
      <div class="myBeautifulIcon">
        ICON
        <input class="dateInputBox" type="date" />
      </div>

      【讨论】:

      • 它在 Linux 上的 Chrome 93 中无法正常工作(不确定 Windows)。选择器图标小于整个输入框。
      【解决方案8】:

      Chrome 99 应该通过添加showPicker() 方法来解决这个问题。从 Chrome 97(发布日期 2021-01-04)开始,它也可用于开发测试(即在功能标志后面)。

      https://chromestatus.com/feature/5692248021794816

      【讨论】:

        【解决方案9】:

        2021 Firefox / Chrome 更新Madacol 回复。

        受到其他回复的启发,我进一步推动了Madacol's solution,以消除当您单击按钮右侧(重置输入)时在 Firefox 下的不良行为。在这里。

        .datepicker{
          display: inline-flex;
          position: relative;
          overflow: clip;
        }
        .datepicker:focus-within {
            outline: black auto 2px;
        }
        .datepicker > input[type=date] {
          position: absolute;
          top: 0;
          left: 0;
          width: 300%;
          height: 100%;
          opacity: 0;
            cursor:pointer;
        }
        .datepicker > input[type=date]::-webkit-calendar-picker-indicator {
          position: absolute;
          top: -150%;
          left: -150%;
          width: 300%;
          height: 300%;
          cursor: pointer;
        }
        <!-- Tested on 2021-09 under latest chrome and firefox -->
        <label class="datepicker">
          ?
          <input type="date" value="2021-09-30" />  
        </label>

        【讨论】:

          【解决方案10】:

          您可以创建另一个本机触发浏览器日期选择器的标签。在 Firefox 上测试:

          <input type="date" id="started[date]" name="started[date]">
          <label class="btn btn-info btn-date" type="button" for="started[time]">
              <i class="far fa-calendar-alt"></i>
          </label>
          

          【讨论】:

          • 可能是最好的答案,因为它不依赖于 hack,而是依赖于 html 元素的本机行为。应该能够通过 css 实现所需的外观并使用它来确保它可以在任何地方工作。
          【解决方案11】:

          我只想为任何寻求更简单、更快捷的解决方案的人添加我的答案。我只是在输入.onfocus.onblur 中使用了两个事件

          <input type="text" name="date_picked" onfocus="(this.type='date')" onblur="(this.type='text')">
          

          据我所知,适用于所有浏览器。

          【讨论】:

          • onfocus 使输入看起来像一个日期选择器,当它被点击时,它会显示日期。只是想补充说明
          猜你喜欢
          • 2013-10-27
          • 2012-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多