最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - newline char n for <textarea> placeholder is ignored on Safari - Stack Overflow

programmeradmin8浏览0评论

I see that this question has been asked here already, but no answer was provided so far. I'm trying to add a multi-line placeholder for a textarea using jQuery. My code looks like this:

$('#ticket_id').attr('placeholder' , 'first line \nsecond line \nthird line')

this works great in Chrome, but fails to work on Safari. I tried using instead of \n but that failed to work at chrome as well. \r\n did the same as \n, worked for chrome but not for Safari.

Any ideas what else can I do?

I see that this question has been asked here already, but no answer was provided so far. I'm trying to add a multi-line placeholder for a textarea using jQuery. My code looks like this:

$('#ticket_id').attr('placeholder' , 'first line \nsecond line \nthird line')

this works great in Chrome, but fails to work on Safari. I tried using instead of \n but that failed to work at chrome as well. \r\n did the same as \n, worked for chrome but not for Safari.

Any ideas what else can I do?

Share Improve this question asked Feb 4, 2020 at 15:13 TalTal 931 silver badge9 bronze badges 3
  • Does this answer your question? Insert line break inside placeholder attribute of a textarea? – Jeremy Harris Commented Feb 4, 2020 at 15:15
  • The only thing that did work from all the suggestions there is Jason Gennaro's Function, but the problem is that my <textarea> is a required field. Therefore if the <textarea> is already filled with text before user's insertion, the required field bee ineffective . – Tal Commented Feb 4, 2020 at 15:25
  • If this is a limitation of Safari, maybe one idea is to create a transparent div that sits on top of the textArea, and shows if the content is empty, and hides if not.. – Keith Commented Feb 4, 2020 at 15:32
Add a ment  | 

4 Answers 4

Reset to default 2

This is maybe a Safari limitation, so one idea is to emulate the placeholder.

All we need to do is place transparent div over the top of the textarea, and then make this visible / invisible based on the value.

Also disable mouse select & pointer events to prevent the div capturing, these are just simple css pointer-events & user-select css properties..

Below is an example.

const ta = document.querySelector('textarea');
const pp = document.querySelector('.placeholder');
console.log(ta);
ta.addEventListener('input', () => {
  pp.classList.toggle('hidden', ta.value !== '');
});
.holder {
  position: relative;
  overflow: hidden;
}
.placeholder {
  pointer-events: none;
  user-select: none;
  position: absolute;
  color: silver;
  padding: 0.2rem 0.2rem;
}
.hidden {
  display: none;
}
textarea {
  width: 200px;
}
<div class="holder">
  <div class="placeholder">
    This is the place holder<br>
    Multiline<br>
    Ok?
  </div>
  <textarea required="true" rows="5"></textarea>
</div>

Line breaks (\n) in a textarea field work as expected in Chrome. However, the Safari default stylesheet overrides these line breaks.

We can mock a placeholder by adding a background image to the text area.

If there is no text in the textarea, show the background image. If the textarea is in focus, or there is a value, don't show the background image.

<TextField
  onChange={onTexfieldChange}
  value={textAreaValue}
  id={'text-area-img-placeholder'}
  style={{backgroundImage: (textAreaValue) && 'none'}}
/>

I am using styled ponents in React, but you can replace TextField with HTML textarea.

The style attribute of the TextField ensures that if there is a value in the textarea (textAreaValue), the background image is removed.

#text-area-img-placeholder {
    background-image: url(./fileName.png);
    background-repeat: no-repeat;
    background-size: contain;
}

#text-area-img-placeholder:focus{
 background-image: none;
}

Add this CSS to cover the background image over the entire textarea. When the HTML is in focus, remove the background image.

  1. &#x0a; is used to break the line in placeholder.
  2. For safari add additional script to handle multiple line placeholder. jQuery is required for below script.

$(function() {
  var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
  
  // Disable for chrome which already supports multiline
  if (! (!!window.chrome && !isOpera)) {
    var style = $('<style>textarea[data-placeholder].active { color: #ccc; }</style>')
    $('html > head').append(style);
    
    $('textarea[placeholder]').each(function(index) {
      var text  = $(this).attr('placeholder');
      var match = /\r|\n/.exec(text);
      
      if (! match)
        return;
      
      $(this).attr('placeholder', '');
      $(this).attr('data-placeholder', text);
      $(this).addClass('active');
      $(this).val(text);
    });
    
    $('textarea[data-placeholder]').on('focus', function() {
      if ($(this).attr('data-placeholder') === $(this).val()) {
        $(this).attr('data-placeholder', $(this).val());
        $(this).val('');
        $(this).removeClass('active');
      }
    });
    
    $('textarea[data-placeholder]').on('blur', function() {
      if ($(this).val() === '') {
        var text = $(this).attr('data-placeholder');
        $(this).val(text);
        $(this).addClass('active');
      }
    });
  }
});
<html>
  <head>
    <script src="https://code.jquery./jquery-2.2.4.js" integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>
  </head>
<body>
   <textarea rows="5" placeholder="first line &#x0a;second line &#x0a;third line"></textarea>
  </body>
</html>

Here one way how to set the linebreaks directly inside the string. However, it does not work in Safari either.

HTML:

<textarea></textarea>


Javascript/Jquery:

var placeholder_text = `• First line
• Second line
• Third line`;

$(document).ready(function()
{
    $('textarea').attr('placeholder', placeholder_text)
});

JSFiddle: https://jsfiddle/gt1ry6d0/2/

发布评论

评论列表(0)

  1. 暂无评论