简体   繁体   English

使用javascript更改textarea包装

[英]Changing textarea wrapping using javascript

For my small wiki application, I mostly need to have the textarea used to edit the contents to use soft (or virtual) wrapping. 对于我的小wiki应用程序,我主要需要使用textarea来编辑内容以使用软(或虚拟)包装。 However, in some cases, not wrapping the content would be preferable. 但是,在某些情况下,不包装内容将是更可取的。 I thought I would do this by simply having a button to turn off wrapping. 我想我只需要一个按钮来关闭包装即可。 Here is the simplified code: 这是简化的代码:

  <form name="wikiedit" action="[[script_name]]" method="post">
    <textarea name="content" rows="25" cols="90" wrap="virtual">[[content]]</textarea>
    <input type="button" onclick="document.wikiedit.content.wrap='off';" value="No Wrap"> &nbsp;
    <input type="submit" value="Save">
  </form>

It works with IE, but not with Firefox or Opera. 它适用于IE,但不适用于Firefox或Opera。 How should I do this? 我该怎么做?

See bug 41464: https://bugzilla.mozilla.org/show_bug.cgi?id=41464 请参阅错误41464: https ://bugzilla.mozilla.org/show_bug.cgi id = 41464

Nasty workaround for now is to replace the textarea with a clone of itself: 现在令人讨厌的解决方法是用自己的克隆替换textarea:

function setWrap(area, wrap) {
    if (area.wrap) {
        area.wrap= wrap;
    } else { // wrap attribute not supported - try Mozilla workaround
        area.setAttribute('wrap', wrap);
        var newarea= area.cloneNode(true);
        newarea.value= area.value;
        area.parentNode.replaceChild(newarea, area);
    }
}

Unrelated: try to avoid accessing elements straight out of the document object, it is unreliable on some browsers and causes name clash problems. 不相关:尽量避免直接从文档对象访问元素,它在某些浏览器上不可靠并导致名称冲突问题。 'document.forms.wikiedit' is better, and moving to 'id' on the form instead of 'name' and then using 'document.getElementById('wikiedit')' better still. 'document.forms.wikiedit'更好,并且在表单上移动到'id'而不是'name',然后更好地使用'document.getElementById('wikiedit')'。

form.elements.content is also more reliable than form.content for similar reasons... or, indeed, you could give the textarea an ID and go straight to the textarea with getElementById without having to bother look at the form. 由于类似的原因,form.elements.content也比form.content更可靠......或者,实际上,你可以给textarea一个ID并直接使用getElementById直接到textarea,而不必费心查看表单。

Here is a primer on textarea wrap, including a CSS solution: 这是textarea包装的入门读物,包括一个CSS解决方案:

http://www.web-wise-wizard.com/html-tutorials/html-form-forms-textarea-wrap.html http://www.web-wise-wizard.com/html-tutorials/html-form-forms-textarea-wrap.html

The CSS solution they cite is: 他们引用的CSS解决方案是:

white-space: pre; overflow: auto;

Which would be: 这将是:

<script type="text/javascript">
function setNoWrap(textarea) {
    textarea.style.whiteSpace = 'pre';
    textarea.style.overflow = 'auto';
}
</script>
<form name="wikiedit" action="[[script_name]]" method="post">
 <textarea name="content" rows="25" cols="90" wrap="virtual">[[content]]</textarea>
 <input type="button" onclick="setNoWrap(this);" value="No Wrap">  
 <input type="submit" value="Save">
</form>

According to the HTML 4.01 spec , wrap isn't a valid attribute for <textarea> s which would explain why it's so difficult and strange. 根据HTML 4.01规范wrap不是<textarea>的有效属性,这可以解释为什么它如此困难和奇怪。 It looks as though Firefox actually does use the wrap attribute, but it won't let you change it. 看起来Firefox实际上确实使用了wrap属性,但它不会让你改变它。

I do have a solution though! 我确实有一个解决方案! It's pretty awful, but here it is. 这太糟糕了,但现在就是这样。 Completely replace the textarea with a new one. 用新的textarea完全替换textarea。

// this is the onclick handler for your button
document.getElementById("nowrapButton").onclick = function() {
  var oldOne = this.form.content;  // the old textarea
  var newOne = document.createElement('textarea'); // the new textarea
  var attrs = ['name', 'rows', 'cols']; // these are the attributes to keep
  for (var i = 0; i < attrs.length; ++i) {
    // copy the attributes to the new one
    newOne.setAttribute(attrs[i], oldOne.getAttribute(attrs[i]));
  }

  // toggle the wrapping on and off
  if (oldOne.getAttribute('wrap') != 'off') {
    newOne.setAttribute('wrap', 'off');
  }

  // copy the text over
  newOne.value = oldOne.value;

  // add the new one
  oldOne.parentNode.insertBefore(newOne, oldOne);
  // get rid of the old one
  oldOne.parentNode.removeChild(oldOne);
  return false;
};

Here's a working version of this you can play with: http://jsbin.com/ugepa 以下是您可以使用的工作版本: http//jsbin.com/ugepa

As usual, this'd be much nicer in jQuery. 像往常一样,这在jQuery中会更好。 :) :)

Here's a variant of bobince's answer that doesn't require cloning the textarea: 这是bobince的答案变体,不需要克隆textarea:

function setWrap(area, wrap) {
    if (area.wrap) {
        area.wrap = wrap;
    } else { // wrap attribute not supported - try Mozilla workaround
        area.setAttribute("wrap", wrap);
        area.style.overflow = "hidden";
        area.style.overflow = "auto";
    }
}

This is similar to VK's comment in the bug that bobince referenced, but setting display instead of overflow didn't work for me unless I put the second set in a setTimeout. 这类似于VK在bobince引用的bug中注释,但设置显示而不是溢出对我来说不起作用,除非我把第二组放在setTimeout中。

Although, this is a old post, but as I getting help from this, I also what to show a easier method I found just now. 虽然,这是一个老帖子,但是当我从中得到帮助时,我还要展示一种我刚才发现的更简单的方法。 And I think it's more correct. 我认为这更正确。

To replace the .cloneNode(), I think the best method is: 要替换.cloneNode(),我认为最好的方法是:

child.setAttribute( 'wrap', wrap ); child.setAttribute('wrap',wrap); parent.removeChild( child ); parent.removeChild(child); parent.appendChild( child ); parent.appendChild(child);

using this way, you can not only save the attributes of itself, but also the attributes you added, for example, a script handle or something else. 使用这种方式,您不仅可以保存自身的属性,还可以保存您添加的属性,例如脚本句柄或其他内容。

试试这个jQuery扩展: Textarea Wrap Changer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM