Autor Zpráva
o_O
Profil
Dobrý den,

zajímalo by mě, zda lze zachytit vkládání (copy & paste) víceřádkových hodnot do inputu a především jak? (pouze javascript)

Je jasné, že prohlížeč automaticky převede víceřádkový text na jeden řádek. Jediné, co mě napadá je zachytit zmáčknutí kláves CTRL+V, jakkoliv uložit do proměnné a pak s ní nadále pracovat.

Jedná se mi o toto: V případě chatu se víceřádkový text zobrazí špatně, resp. text se narve na jeden řádek bez mezer, čímž způsobí špatnou čitelnost. Chtěl bych v takovémto případě dát návštěvníkovi možnost odeslat zprávu na Xkrát (například confirm-em).

Předem díky za jakékoliv postrčení.
Darker
Profil
V chatu to vyřeš přes PHP - zprávy prožeň funkcí nl2br.
Chamurappi
Profil
Reaguji na o_O:
V Internet Exploreru to jde jednoduše, chytneš událost onpaste a při ní se podíváš, co vrací metoda clipboardData.getData("Text").
V ostatních prohlížečích je zapotřebí odchytit stisk kláves Ctrl a V, vytvořit novou <textarea> (nějak schovanou, ale ne display: none), hodit do ní focus, počkat milisekundu, poznamenat si, co se vložilo, zrušit <textarea>, vrátit focus…
o_O
Profil
Darker:
lze zachytit vkládání (copy & paste) víceřádkových hodnot do inputu a především jak? (pouze javascript)

Chamurappi:
Díky.
o_O
Profil
Chamurappi:
Ještě jeden dotaz - je lepší napsat obě metody (jednu pro IE a druhou pro ostatní prohlížeče) - nebo bude rozumnější napsat jen ten druhý způsob?
Chamurappi
Profil
Reaguji na o_O:
Událost onpaste je (již podle názvu) universálnější, umí zachytit i jiné postupy vkládání než Ctrl+V. Existují lidi (třeba já), kteří místo Ctrl+C a Ctrl+V dodnes používají Ctrl+Insert a Shift+Insert. To by ještě chytit šlo, ale vložení přes kontextové menu (přes to, které se ukáže při kliknutí pravým tlačítkem na formulářovém poli) už ničím jiným než onpastem nechytíš.

Rozumnější je použít oba způsoby. Ani není nutné testovat prohlížeč — při onpaste si po úspěšném clipboardData.getData("Text") zapamatuj, že už nemáš číhat na Ctrl+V.
o_O
Profil
Chamurappi:
Tak jsem se k tomu nakonec dostal.
function onPasteMsg(){
  if(clipboardData.getData("Text")){
    textik=clipboardData.getData("Text");
    /*alert(textik);*/
    textik=textik.split("\n");
    if(textik.length>1){
      alert("Zachyceno vkládání víceřádkového textu.");
      /* ... */
    }
  }
}
<input type="text" name="text" onpaste="onPasteMsg();" onKeyPress="GetKeyCode();">

S tímto takřka problém nebyl - vkládaný text lze zpracovat jednoduše. Pak ten horší způsob pro ostatní pr. Koukal jsem, jak je to řešené zde a mohl by mi někdo například poslat článek který pojednává o tomto zápisu funkcí?
document.documentElement.onkeypress = window.onkeypress = function(e)
Jako normální funkce mi to nechtělo pracovat, použil jsem tedy zápis z DJPW (pokud nevadí).

Dotáhl jsem to tedy do této fáze:
function GetKeyCode(e){
  document.documentElement.onkeypress = window.onkeypress = function(e) {
    var event = window.event || e;
    var target = event.target || event.srcElement;
    var key = (event.which + 1) ? event.which : event.keyCode;
    if(key==118){ /* 118=CTRL+V */
      var textTo=document.createElement("textarea");
      document.getElementsByTagName('BODY')[0].appendChild(textTo);
      textTo.focus();
    }
  }
}
Funguje jak má, jen bych měl ještě jednu otázku. Proč jsou použity obě? document.documentElement.onkeypress, window.onkeypress
- v chrome a safari mi nefunguje ani jedna, v mozille obě (vytváří však 2 textarey), v opeře jen documentElement
Zkoušel jsem alertovat, ale funkce GetKeyCode() se vůbec nezavolá. Můžete mě, prosím, nasměrovat správným směrem?

Díky.
o_O
Profil
Tak už jsem na to přišel. Nevím proč, ale chrome a safari mi bere pouze onkeydown.

Výsledný script:
var cleverP = window.clipboardData; // pro detekci MSIE / ostatní
function cleverPaste(){ // pouze MSIE
  textik=clipboardData.getData("Text");
  textik=textik.split("\n");
  if(textik.length>1){
    alert("Zachyceno vkládání víceřádkového textu.");
  }
}

  if(cleverP)
  document["otevr"]["zprava"].onpaste = function() {cleverPaste();} // v případě MSIE volat jednodušší možnost

  document.documentElement.onkeypress = window.onkeypress = window.onkeydown = function(e) { // ostatní prohlížeče
  if(cleverP)return true;
  var event = window.event || e;
  var target = event.target || event.srcElement;
  var key = (event.which + 1) ? event.which : event.keyCode;
  if(target.tagName!="INPUT") // detekce inputu
    return true;
  if(target.name!="zprava" || target.id!="zprava_n") // detekce správného inputu
    return true;
  if(key==86 && event.ctrlKey){ // ctrl+v
    var textTo=document.createElement("textarea");
    textTo.style.cssText = 'width:0px;height:0px;position:absolute;left:-10000px;top:-10000px;';
    document.body.appendChild(textTo);
    textTo.focus();
    setTimeout(function(){ // počkáme milisekundu
      textik=textTo.value.split("\n");
      if(textik.length>1){
        alert("Zachyceno vkládání víceřádkového textu.");
      }
      textTo.parentNode.removeChild(textTo); // odstraníme vytvořenou textareu
    },1);
  }
  return true;
};

Nějaké výhrady, či připomínky?
Chamurappi
Profil
Reaguji na o_O:
Některé konstrukce jsou mi fakt dost povědomé :-)

ale chrome a safari mi bere pouze onkeydown
Ve všech prohlížečích se vyplatí používat spíš onkeydown. Já v djpw.js musel použít onkeypress, protože jinak některý z prohlížečů (tuším) nedovoloval stornovat výchozí akci (což ty nepotřebuješ).

if(target.name!="zprava" || target.id!="zprava_n") // detekce správného inputu
Proč nehlídáš onkeydown přímo na tom <input>u? Není přeci nutné chytat každou klávesu ve stránce. (Krom toho ji nejspíš v některých prohlížečích chytneš dvojmo, možná i trojmo.)
o_O
Profil
Chamurappi:
Některé konstrukce jsou mi fakt dost povědomé :-)
použil jsem tedy zápis z DJPW (pokud nevadí)“ :)

Proč nehlídáš onkeydown přímo na tom <input>u?
To je dobrá otázka, to by mě taky zajímalo.

dvojmo, možná i trojmo
Semtam se mi podařilo vytvořit 3 textarey naráz, ale většinou jen dvě :)

vyplatí používat spíš onkeydown
Dobré vědět, říct mi to před dvěmi týdny byl bych ovšem šťastnější. Málem jsem nad tím rezignoval.

Budiž tedy. Nějak takto?
<form name="otevr">
  <input type="text" name="zprava" id="zprava_n" onkeydown="radky();">
</form>

var cleverP = window.clipboardData; // pro detekci MSIE / ostatní
function cleverPaste(){ // pouze MSIE
  textik=clipboardData.getData("Text");
  textik=textik.split("\n");
  if(textik.length>1){
    alert("Zachyceno vkládání víceřádkového textu.");
  }
}
if(cleverP)
  document["otevr"]["zprava"].onpaste = function() {cleverPaste();} // v případě MSIE volat jednodušší možnost

  function radky(){ // ostatní prohlížeče
  window.onkeydown = function(e) {
    if(cleverP)return true;
    var event = window.event || e;
    var target = event.target || event.srcElement;
    var key = (event.which + 1) ? event.which : event.keyCode;
    if(key==86 && event.ctrlKey){ // ctrl+v
      var textTo=document.createElement("textarea");
      textTo.style.cssText = 'width:0px;height:0px;position:absolute;left:-10000px;top:-10000px;';
      document.body.appendChild(textTo);
      textTo.focus();
      setTimeout(function(){ // počkáme milisekundu
        textik=textTo.value.split("\n");
        if(textik.length>1){
          alert("Zachyceno vkládání víceřádkového textu.");
        }
        textTo.parentNode.removeChild(textTo); // odstraníme vytvořenou textareu
      },1);
    }
    return true;
  };
}

[OT]Když už máte tu supr fíčuru která umí odhalit vkládání kódu, mohli by jste ošetřit, zda se text nevkládá do již připraveného [ pre ][/OT]
Chamurappi
Profil
Reaguji na o_O:
Nějak takto?
Ne. V momentě, kdy uživatel začne psát do <input>u, nastavíš, že chceš chytat všechny následující onkeydown na window — proč?
Když k <input>u dodáváš onpaste skriptem, tak už mu můžeš dodat stejným způsobem i onkeydown.

mohli by jste ošetřit, zda se text nevkládá do již připraveného [pre]
Ošetřené to je, ale počítá to jen s [pre], ne s [prejs] a spol. — ano, to bych asi měl opravit.
Chamurappi
Profil
Reaguji na o_O:
Možná ten postup s odchytávacím pracovním elementem <textarea> není optimální. Nevím, proč jsou s ním problémy, nedokážu je nasimulovat.

Nicméně napadla mě druhá, více selhánívzdorná možnost:
Jakmile se odchytí Ctrl+V, nezasáhnu skriptem do přirozeného dění vůbec, nechám text normálně vložit, akorát se před tím podívám, co je momentálně před a za výběrem (před selectionStart a za selectionEnd). O milisekndu později se znovu mrknu na value a vyzobnu si s pomocí dříve zjištěných hranic výběru to, co se změnilo. Pak můžu vložený text také zanalyzovat a případně znovu celý označit a přepsat jiným textem.

Teď mě ale napadá, že tahle možnost asi není úplně použitelná v tvém případě, jelikož máš jako vstupní pole <input> a nikoliv <textarea>.

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: