2015-10-21 18 views
1

Здравствуйте и спасибо, что нашли время, чтобы прочитать это.Обнаружить, если вы напечатаете внутри тега span

Если у вас есть следующая функция ниже, выделите # и @, когда я напишу в текстовом поле.

Когда я/Тип пользователя на ключей Hightlight (@/#), он createds в <span> tag вокруг него. Когда использование сделать пространство останавливает Hightlight

Мой вопрос, как я могу проверить, если я печатаю в то время как внутри <span> tag, потому что мне нужно что-то должно произойти в то время как использование типа что-то вроде @this или #this, а затем останавливается, когда используйте клавишу пробела.

Надеюсь, вы понимаете мой вопрос, и я благодарю вас за ваше время.

(function ($) { 
 
    $.fn.hashtags = function() { 
 
     $(this).wrap('<div class="Hashtags"><div class="highlighter"></div></div>').unwrap().before('<div class="highlighter"></div>').wrap('<div class="typehead"></div></div>'); 
 
     $(this).addClass("theSelector"); 
 
     autosize($(this)); 
 
     $(this).on("keyup", function() { 
 
      var str = $(this).val(); 
 
      $(this).parent().parent().find(".highlighter").css("width", $(this).css("width")); 
 
      str = str.replace(/\n/g, '<br>'); 
 
      if (!str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\[email protected]?^=%&amp;\/~+#-])?#([a-zA-Z0-9]+)/g) && !str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\[email protected]?^=%&amp;\/~+#-])[email protected]([a-zA-Z0-9]+)/g) && !str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\[email protected]?^=%&amp;\/~+#-])?#([\u0600-\u06FF]+)/g) && !str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\[email protected]?^=%&amp;\/~+#-])[email protected]([\u0600-\u06FF]+)/g)) { 
 
       if (!str.match(/#(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))#/g)) { //arabic support 
 
        str = str.replace(/#(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))/g, '<span class="hashtag">#$1</span>'); 
 
       } else { 
 
        str = str.replace(/#(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))#(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))/g, '<span class="hashtag">#$1</span>'); 
 
       } 
 
       if (!str.match(/@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))@/g)) { 
 
        str = str.replace(/@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))/g, '<span class="hashtag">@$1</span>'); 
 
       } else { 
 
        str = str.replace(/@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+))/g, '<span class="hashtag">@$1</span>'); 
 
       } 
 
      } 
 
      $(this).parent().parent().find(".highlighter").html(str); 
 
     }); 
 
     $(this).parent().prev().on('click', function() { 
 
      $(this).parent().find(".theSelector").focus(); 
 
     }); 
 

 
    }; 
 
})(jQuery); 
 

 
$(document).ready(function() { 
 
      $("textarea").hashtags(); 
 
    });
.Hashtags .highlighter{ 
 
    white-space: pre-wrap; 
 
\t color:transparent; 
 
\t overflow: hidden; 
 
\t position: absolute; 
 
\t padding-left:7px; 
 
\t padding-top:5px; 
 
\t font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 
 
\t font-size:14px; 
 
\t line-height:20px; 
 
} 
 

 
.Hashtags .theSelector{ 
 
\t background-color: transparent; 
 
\t position: relative; 
 
\t direction: ltr; 
 
\t font-size:14px; 
 
\t font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 
 
\t resize:none !important; 
 
\t -webkit-transition: height 0.2s; 
 
\t border: 1px solid #cccccc; 
 
\t -webkit-border-radius: 4px; 
 
\t -moz-border-radius: 4px; 
 
\t border-radius: 4px; 
 
\t padding: 4px 6px; 
 
\t vertical-align:middle; 
 
\t min-height:48px !important; 
 
\t line-height:20px; 
 
} 
 

 
.Hashtags .hashtag{ 
 
\t background: -webkit-linear-gradient(#dce6f8, #bdcff1); 
 
\t border-radius: 2px; 
 
\t box-shadow: 0 0 0 1px #a3bcea; 
 
\t font-size:14px; 
 
\t white-space: pre-wrap; 
 
\t word-break: break-word; 
 
\t line-height:20px; 
 
}
<script src="http://www.jacklmoore.com/js/autosize.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
     <textarea style="width: 250px; min-height: 100px!important;"></textarea>

+0

Я не знаю, почему вы делаете свой код настолько сложным. У вас есть другие html-объекты внутри текстового поля? Если у вас нет причин, почему вы просто не получаете всю текстовую область (jquery .text()) и не добавляете диапазон для каждой записи, начинающейся с @ или #, и останавливается, когда она попадает в пробел или конец файла. – Marcio

+0

вы можете даже обернуть текст внутри 'textarea' в фактическом' span'? Я думаю, вы должны использовать contenteditable 'div' за то, что – Alex

+0

взгляните на это: http://jsfiddle.net/2rTA5/2/ – Alex

ответ

0

На основе this answer я нашел jsfiddle, который использует rangy.js библиотеку. I modified the script a bit and it wraps all strings of the pattern @string в font элемента, но вы можете настроить для ваших нужд :-)

Полный код:

<div contenteditable="true" id="pad" onkeyup="formatText();"></div> 

JS:

function saveSelection(containerEl) { 
    var charIndex = 0, start = 0, end = 0, foundStart = false, stop = {}; 
    var sel = rangy.getSelection(), range; 

    function traverseTextNodes(node, range) { 
     if (node.nodeType == 3) { 
      if (!foundStart && node == range.startContainer) { 
       start = charIndex + range.startOffset; 
       foundStart = true; 
      } 
      if (foundStart && node == range.endContainer) { 
       end = charIndex + range.endOffset; 
       throw stop; 
      } 
      charIndex += node.length; 
     } else { 
      for (var i = 0, len = node.childNodes.length; i < len; ++i) { 
       traverseTextNodes(node.childNodes[i], range); 
      } 
     } 
    } 

    if (sel.rangeCount) { 
     try { 
      traverseTextNodes(containerEl, sel.getRangeAt(0)); 
     } catch (ex) { 
      if (ex != stop) { 
       throw ex; 
      } 
     } 
    } 

    return { 
     start: start, 
     end: end 
    }; 
} 

function restoreSelection(containerEl, savedSel) { 
    var charIndex = 0, range = rangy.createRange(), foundStart = false, stop = {}; 
    range.collapseToPoint(containerEl, 0); 

    function traverseTextNodes(node) { 
     if (node.nodeType == 3) { 
      var nextCharIndex = charIndex + node.length; 
      if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) { 
       range.setStart(node, savedSel.start - charIndex); 
       foundStart = true; 
      } 
      if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) { 
       range.setEnd(node, savedSel.end - charIndex); 
       throw stop; 
      } 
      charIndex = nextCharIndex; 
     } else { 
      for (var i = 0, len = node.childNodes.length; i < len; ++i) { 
       traverseTextNodes(node.childNodes[i]); 
      } 
     } 
    } 

    try { 
     traverseTextNodes(containerEl); 
    } catch (ex) { 
     if (ex == stop) { 
      rangy.getSelection().setSingleRange(range); 
     } else { 
      throw ex; 
     } 
    } 
} 


function formatText() { 
    var el = document.getElementById('pad'); 
    var savedSel = saveSelection(el); 
    el.innerHTML = el.innerHTML.replace(/(<([^>]+)>)/ig,""); 
    el.innerHTML = el.innerHTML.replace(/(\@[0-9a-z]+)/ig,"<font color='red'>$1</font>"); 

    // Restore the original selection 
    restoreSelection(el, savedSel); 
} 

Working example