В моем JS-коде присутствуют символы (Zero width space). Откуда они пришли?

Я разрабатываю переднюю часть веб-приложения с помощью среды IDE NetBeans 7.0.1. Недавно у меня была очень неприятная ошибка, которую я наконец исправил.

Скажем, у меня есть код

var element = '<input size="3" id="foo" name="elements[foo][0]" />';
$('#bar').append(element);

Я заметил, что что-то пошло не так, когда я увидел, что атрибут size не работает в Chrome (не проверен в других браузерах). Когда я открыл этот элемент в Inspector, он был интерпретирован как нечто вроде

<input id="&quot;3&quot;" name="&quot;elements[foo][0]&quot;" 
    size="&quot;foo&quot;" />

Это было довольно странно. После ручной переименования символа element string-in-character ошибка исчезла. Когда я отказался от этого изменения, я заметил, что Netbeans предупредил меня о некоторых символах Unicode в моем старом коде. Это было \u200b - пробелы нулевой ширины после каждого '=', между '] [' и в конце строки. Таким образом, строка появилась нормально, потому что пространства с нулевой шириной не были отображены, но после выхода из нее моя строка была

'<input size=\u200b"3" id=\u200b"foo" name=\u200b"elements[foo]\u200b[0]" />\u200b'

Теперь, где, черт возьми, я их получил?

Я не уверен, где я скопировал код element, но это определенно одно из следующего:

  • Другая панель редактора Netbeans с файлом шаблона HTML;
  • Google Chrome Inspector, действие "Копировать как HTML";
  • Страница просмотра исходного кода Google Chrome (очень сомнительно).

Но я не могу воспроизвести ошибку ни с чем.

Я использую Netbeans 7.0.1 и Google Chrome 13.0 под Windows 7. Нет клавиатурных переключателей или чего-то вроде этого. Кроме того, я использую Git для управления версиями, но я не вытащил этот код, поэтому очень маловероятно, чтобы Git виноват. Это не может быть глупой шуткой моих коллег, потому что они довольно хорошо воспитаны.

Любые предложения, которые испортили мой код?

Ответ 1

Вот удар в темноте.

Моя ставка будет в Google Chrome Inspector. Поиск через источник Chromium, я заметил следующий блок кода

    if (hasText)
        attrSpanElement.appendChild(document.createTextNode("=\u200B\""));

    if (linkify && (name === "src" || name === "href")) {
        var rewrittenHref = WebInspector.resourceURLForRelatedNode(node, value);
        value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
        attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a"));
    } else {
        value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
        var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
        attrValueElement.textContent = value;
    }

Вполне возможно, что я просто ругаю неправильное дерево здесь, но похоже, что в процессе отображения атрибутов вставлялось пространство для нулевой ширины (для обработки мягкой текстовой упаковки?). Возможно, функция "Скопировать как HTML" не удалила их должным образом?


Update

После работы с инспектором элементов Chrome я почти уверен, что откуда пришел ваш бродячий \u200b. Обратите внимание, как строка может переноситься не только в видимом пространстве, но и после = или символов, сопоставленных /([\/;:\)\]\}])/, благодаря вставленному пространству нулевой ширины.

chrome inspector screenshot

К сожалению, я не могу реплицировать вашу проблему, когда они непреднамеренно включаются в ваш буфер обмена (я использовал Chrome 13.0.782.112 в Win XP).

Конечно, стоит представить отчет об ошибке, если вы сможете воспроизвести поведение.

Ответ 2

Как г-н Шон Чин уже обратился к нему. Мне просто удалось воспроизвести проблему, пока я копировал код jquery с веб-страницы.

Когда это произошло: Копирование текста из Google Chrome версии 41.0.2272.118 м (не протестировано с другими браузерами) в окно кода Dreamweaver. Это скопировали нежелательные символы вдоль кода, как это происходит здесь.

вы скопировали текст с веб-страницы как

$('.btn-pageMenu').css('display'​​​​​​​​​​​​​​​​​​​​​​​​​​​,'block');​​​​​​

за кадром, это то, что делает эту строку

<code><span class="pun">&#8203;</span><span class="pln">$</span><span class="pun">(</span><span class="str">'.btn-pageMenu'</span><span class="pun">).</span><span class="pln">css</span><span class="pun">(</span><span class="str">'display'</span><span class="pun">&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;,</span><span class="str">'block'</span><span class="pun">);&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;</span></code>

Скопировано в расширенный редактор, как вы упомянули, или Dreamweaver дает ошибки в браузере, возможно, также не работает код javascript

Uncaught SyntaxError: Unexpected token ILLEGAL

Решение: когда это произойдет, обнимите стоимость блокнота, пока это не будет исправлено большими парнями. Это больше связано с редактором, чем с браузерами.

Ответ 3

Спустя более 6 лет я получаю ту же проблему, но я могу ее воспроизвести.

Я изучаю JavaScript из этого blog, который содержит фрагменты кода. Всякий раз, когда я копирую весь код из фрагмента и вставляю его в JavaScript-редакторы JS Fiddle или JS Bin, я получаю красные токены, распространяемые в код. Вот скриншоты первого фрагмента кода из вышеупомянутого сообщения в блоге в JS Fiddle и JS Bin. Наведение указателя мыши на один из этих красных жетонов показывает подсказку: " пространство с нулевой шириной).

Я работаю над Linux Ubuntu 16.04, и если я вставляю код в один из моих редакторов (Atom 1.22.1 или Geany 1.32), а затем открываю файл в веб-браузерах, я получаю следующие ошибки в консоли:

  • Chrome 63 → SyntaxError: недопустимый или неожиданный токен
  • Firefox 57 → СинтаксисError: незаконный символ

Надеюсь, это поможет немного понять, почему эти пространства нулевой ширины копируются в буфер обмена.

Ответ 4

Это случилось со мной, когда я скопировал исходный код с другого сайта в мой редактор. Если вы используете Visual Studio код или редактор Atom, это выделит эти надоедливые символы пробел нулевой ширины и т. \u200b)

Ответ 5

Это должно исправить это для вас:

var element = $('<input size="3" id="foo" name="elements[foo][0]" />'); $('#bar').append(element);

или вы можете сделать это таким образом, чтобы сделать его более чистым:

$('#bar').append($('<input />').attr({ size: '3', id: 'foo', name: 'elements[foo][0]' }));