2012-04-17 4 views
3

Я пытаюсь создать редактор меток, например Stack Overflow.Невозможно прочитать свойство 'length' из null в javascript для цикла

Я получаю эту ошибку, указанную в заголовке, если на самом деле я не нахожу звездочку и http: // содержащую фразу в текстовое поле. Если я нахожу только звездочку, содержащую фразу, ошибка относится к этой строке: if(linkify.length!==0)

Вот jsfiddle, чтобы показать вам, что я имею в виду.

Вот мой HTML:

<textarea></textarea> 
<div></div><button type="button">Markdownify</button> 

Вот мой JS:

var val=$('textarea').val(), boldify = val.match(/\*\*[A-Za-z0-9]+\*\*/gim), 
italicify = val.match(/\*[A-Za-z0-9]+\*/gim),linkify = val.match(/http\:\/\/[A-z0-9]+\.[A-z0-9]+/gim); 

$(document.body).on('click', 'button', function() { 

val=$('textarea').val(), boldify = val.match(/\*\*[A-Za-z0-9]+\*\*/gim), 
italicify = val.match(/\*[A-Za-z0-9]+\*/gim),linkify = val.match(/http\:\/\/[A-z0-9]+\.[A-z0-9]+/gim); 

if (boldify.length!== 0){ 
      for (var i=0; i < boldify.length; i++) { 
       var boldMatch= boldify[i], 
       boldReplace = boldMatch.replace(/\*\*[A-z0-9]+\*\*/gim, '<span style="font-weight:bold;color:blue;">'+boldMatch+'</span>'), 
       val = val.replace(boldMatch, boldReplace);  
      } 
     val = val.replace(/\*\*/gi, ""); 
} 

if(italicify.length!== 0){ 
    for(var j=0; j < italicify.length; j++){ 
    var italicMatch= italicify[j], 
    italicReplace = italicMatch.replace(/\*[A-z0-9]+\*/gim, '<span style="font-style:italic;color:red;">'+italicMatch+'</span>'); 
    val = val.replace(italicMatch, italicReplace); 
    } 
    val = val.replace(/\*/gi, ""); 
} 

if(linkify.length!== 0){ 
    for(var k=0; k < linkify.length; k++){ 
    var linkMatch= linkify[k], 
    linkReplace = linkMatch.replace(/http:\/\/[A-z0-9]+\.[A-z0-9]+/gim, '<a href="'+linkMatch+'">'+linkMatch+'</a>'); 
     val = val.replace(linkMatch, linkReplace); 
    } 
} 

$('div').html(val); 
}); 

Любая помощь будет высоко ценится.

ответ

10

вместо того, чтобы использовать match функции, которая возвращает нуль, если строка оленьей кожи соответствует указанному регулярному выражению использовать функцию test, которая возвращает истинную/ложную, а затем, если вам это нужно, вы можете использовать функцию match.

в основном вы выполняете null.length, которые, очевидно, недействительны как match возвращаются вам нулевые

или вы можете просто выполнить null проверки, прежде чем проверить длину и просто сделать регулярное выражение, соответствующее один раз.

if(linkify!==null && linkify.length!== 0) 
{ 
    //do smthing 
} 
+2

привет Baz1nga, спасибо за ваш help, есть ли какая-то причина, по которой я не должен просто делать то, что предложил jimw, т. е. 'if (linkify && linkify.length)'? Это меньше кода для написания, а затем тестового и комбинированного комбо, не так ли? –

+1

Я не видел этого ответа, и я обновил свой ответ с учетом штрафа за выполнение, за которое вы платите за регулярное выражение дважды. – Baz1nga

+1

также http://jsperf.com/regexp-test-vs-match-m5 – Baz1nga

3

«linkify» равно нулю, когда есть не «HTTP: //» матч в тексте, так что вы должны проверить для этого условия:

if(linkify && linkify.length) 
+0

привет jimw, спасибо за ваш комментарий. Я задам противоположный вопрос, который я задал Baz1nga, что является его предложением кода как-то «лучше», чем «&&' условие, которое вы предлагаете? Извините, все еще изучая, как программировать здесь ... –

+1

По-моему, нет большой разницы, если этот код не особенно важен для производительности. Если это обработчик событий, вызываемый много раз в секунду, какой бы способ быстрее, лучше. В более простом случае используйте то, что вам подходит - они достигнут того же конца. – jimw

+0

отлично, да, я не предполагаю, что это критически, хотя, возможно, позже я изменю его на «keyup», и в этот момент, возможно, я его реорганизую, еще раз спасибо! –

Смежные вопросы