2017-04-09 62 views
2

我對這一切都很陌生,但花了一週的時間試圖找到答案後,我想我會試着直接詢問。 我正在構建使用javascript和jquery的文本編輯器。我有一個textarea(帶contenteditable),一個樣式表和一個js腳本。我想要的是,對於每個字母按下,字距將是隨機的。我實現了一個簡單的功能,但我不希望所有的textarea文本有這樣的字距,只有按下的最後一個字母等等等等,所以這種類型的東西會結果:在每個字母的文本區域(輸入)中隨機調整

simulation

有什麼我至今在我的js文件:

$(document).ready(

function() { 
$('#textarea').keypress(function(){  
var KerningRandom = Math.floor((Math.random()*90)-20); 
$(this).css('letter-spacing',KerningRandom); 

});

這是我的jsfiddle,實際上不工作在jsfiddle,我不明白爲什麼,因爲它在當地工作正常......?

謝謝!

+0

您能否回顧一下答案? – Sorikairo

回答

0

您不能在CSS中處理單個字符(以及字形)。只有::first-letter

選項您有:

  1. 轉換所有字符個人跨度。我想這太多了。
  2. 使用<canvas>來呈現文本,從而從頭開始實現文本流佈局。
+0

是的,我想過在一個範圍內包含每個輸入字母,但影響是無窮無盡的,我認爲...我嘗試使用kerning.js來影響每個字母(給a,b等分配特定的字距)和告訴kerning.js從KerningRandom函數中設置這些字距(我希望我很清楚,我不確定哈哈)可能會起作用嗎?作爲核心。js可以設置特定字母的特定字母我認爲它可能...但我不是專業人士。 非常感謝你的回答,我會考慮讓textarea成爲一個畫布,如果它不起作用,它會回來(對不起,我是新手...) 再次感謝! –

0

你可以找到一個你想在那裏達到什麼樣的工作(我分叉你的)。

https://jsfiddle.net/1gesLgsa/2/

全碼:

//Code from https://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity 


    //Namespace management idea from http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/ 
    (function(cursorManager) { 

    //From: http://www.w3.org/TR/html-markup/syntax.html#syntax-elements 
    var voidNodeTags = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX']; 

    //From: https://stackoverflow.com/questions/237104/array-containsobj-in-javascript 
    Array.prototype.contains = function(obj) { 
     var i = this.length; 
     while (i--) { 
      if (this[i] === obj) { 
       return true; 
      } 
     } 
     return false; 
    } 

    //Basic idea from: https://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text 
    function canContainText(node) { 
     if(node.nodeType == 1) { //is an element node 
      return !voidNodeTags.contains(node.nodeName); 
     } else { //is not an element node 
      return false; 
     } 
    }; 

    function getLastChildElement(el){ 
     var lc = el.lastChild; 
     while(lc && lc.nodeType != 1) { 
      if(lc.previousSibling) 
       lc = lc.previousSibling; 
      else 
       break; 
     } 
     return lc; 
    } 

    //Based on Nico Burns's answer 
    cursorManager.setEndOfContenteditable = function(contentEditableElement) 
    { 

     while(getLastChildElement(contentEditableElement) && 
       canContainText(getLastChildElement(contentEditableElement))) { 
      contentEditableElement = getLastChildElement(contentEditableElement); 
     } 

     var range,selection; 
     if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+ 
     {  
      range = document.createRange();//Create a range (a range is a like the selection but invisible) 
      range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range 
      range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start 
      selection = window.getSelection();//get the selection object (allows you to change selection) 
      selection.removeAllRanges();//remove any selections already made 
      selection.addRange(range);//make the range you have just created the visible selection 
     } 
     else if(document.selection)//IE 8 and lower 
     { 
      range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible) 
      range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range 
      range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start 
      range.select();//Select the range (make it the visible selection 
     } 
    } 

}(window.cursorManager = window.cursorManager || {}));  



// ACTUAL CODE MADE FOR THIS ANSWER 

    $('#textarea').keypress(function(event) { 
    event.preventDefault(); 
     var KerningRandom = Math.floor((Math.random() * 90)); 
     if ($("#last").length > 0) 
     { 
     var previousLast = $("#textarea #last").html(); 
     $("#textarea #last").remove(); 
     } 
     else 
     var previousLast = ""; 
     $("#textarea").html($("#textarea").html().slice() + previousLast + "<span id='last'>" + String.fromCharCode(event.which) + "</span>") 
     $("#last").css('margin-left', KerningRandom + "px"); 

var editableDiv = document.getElementById("textarea"); 
cursorManager.setEndOfContenteditable(editableDiv) 
    }); 

var editableDiv = document.getElementById("textarea"); 
cursorManager.setEndOfContenteditable(editableDiv) 

逐點解釋:

 $('#textarea').keypress(function(event) { 
    event.preventDefault(); 
     var KerningRandom = Math.floor((Math.random() * 90)); 
     if ($("#last").length > 0) 
     { 
     var previousLast = $("#textarea #last").html(); 
     $("#textarea #last").remove(); 
     } 
     else 
     var previousLast = ""; 
     $("#textarea").html($("#textarea").html() + previousLast + "<span id='last'>" + String.fromCharCode(event.which) + "</span>") 
     $("#last").css('margin-left', KerningRandom + "px"); 

     var editableDiv = document.getElementById("textarea"); 
     cursorManager.setEndOfContenteditable(editableDiv) 
    }); 

event.preventDefault()防止信按下一個鍵時添加。 然後,我們計算我們的左邊距值,保存我們以前的最後一個字母,並刪除包含最後一個字母的跨度,因爲它不再是最後一個字母了。 我們附加了前一個最後一個字母,以及具有隨機左邊距(用於模擬字距)的跨度以及按下的鍵的值(感謝 How to find out what character key is pressed?)與實際內容。

之後,我們需要手動將文件頭移動到textarea的末尾,否則它會停留在開頭。

爲此,我使用了 How to move cursor to end of contenteditable entity的代碼,所以在此處解釋。

+0

嗨!感謝所有這一切,它看起來不錯!我看到的唯一問題是,每次按下一個新鍵時,最後一個字母的邊距都會消失,並返回原來的字距不是嗎?我怎樣才能「修復」邊距/字距?再一次,我是新手,希望你明白我想說的是什麼......但是你提供的代碼是一大步!我沒有想到將字距作爲邊緣... 謝謝! –

+0

@Lea我確實認爲字距必須重置爲「非最後」字母。那麼你到底想要達到什麼目標?它不會很長:) – Sorikairo

+0

@Lea MC Ok對不起,我沒有看到你提供的示例圖片,我會在1小時內爲你提供一個固定的代碼,所以每個字母都有不同的字距 – Sorikairo