Чому мій JavaScript не працює в JSFiddle?


114

Я не можу з’ясувати, у чому проблема цього JSFiddle .

HTML:

<input type="button" value="test" onclick="test()">

JavaScript:

function test(){alert("test");}

А коли натискаю кнопку - нічого не сталося. На консолі написано "тест не визначений"

Я читав документацію JSFiddle - там написано, що додається JS-код і додається <head>HTML-код <body>(тому цей JS-код раніше, ніж html і повинен працювати).


Видалення круглих дужок також може працювати в звичайних невірних обставинах, хоча, безумовно, є корисним поради якнайбільше відокремити js від HTML. Я дозволяю собі лише стиль CSS style = "display: none" вбудований CSS "ні".
Адріан Варфоломій

Відповіді:


60

Функція визначається всередині навантажувача вантажу і, таким чином, знаходиться в іншій області. Як зазначає @ellisbben у коментарях, ви можете це виправити, чітко визначивши його на windowоб’єкті. Краще все ж змінити його, щоб ненав’язливо застосувати обробник до об'єкта: http://jsfiddle.net/pUeue/

$('input[type=button]').click( function() {
   alert("test");   
});

Зверніть увагу, якщо застосувати обробник таким чином, а не вбудованим, зберігає ваш HTML чистим. Я використовую jQuery, але ви можете це зробити з рамкою або без неї, або використовуючи інший фреймворк, якщо вам подобається.


@Innuendo - jsFiddle використовує окремі кадри для таблиць коду / html / стилів. вам потрібно буде посилатися на кадр у виклику функції, але насправді це не простий спосіб зробити це, оскільки кадр не має імені. Це справді проблема через те, як працює jsfiddle, але все-таки хороша ідея зберегти ваш JavaScript повністю відокремленим.
tvanfosson

5
@ tvanfosson - ваше рішення працює, але jsfiddle не використовує окремі кадри для показу результату; див. jsfiddle.net/Yazpj/show . Причина, коли вона не працювала спочатку, полягає в тому, що вона testбула визначена всередині onLoadфункції; використання window.test = function(){/*...*/}змушує його працювати прекрасно.
ellisbben

@ellisbben - якщо я використовую Firebug для огляду DOM, кожна з 4 окремих панелей існує в окремому iframe.
tvanfosson

1
Так, але якщо ви вивчите єдиний кадр iframe, який використовується для показу прикладу, ви побачите, що він розміщує весь код на одній сторінці, яка не використовує кадри, отже, ці кадри не можуть порушити ваш приклад. Додайте showбудь-яку URL-адресу jsfiddle, щоб побачити, про що я говорю: jsfiddle.net/Yazpj/show
ellisbben

100

Якщо не вказати параметр обтікання, він за замовчуванням має значення "onLoad". Це призводить до того, що весь JavaScript буде завернуто в функцію, запущену після завантаження результату. Всі змінні є локальними для цієї функції, тому недоступні в глобальній області.

Змініть налаштування обгортання на "без обгортання", і воно буде працювати:

http://jsfiddle.net/zalun/Yazpj/1/

Я переключив рамку на "Без бібліотеки", оскільки ви не використовуєте жодну.


22

Є й інший спосіб, оголосити свою функцію такою змінною:

test = function() {
  alert("test");
}

jsFiddle


Деталі

EDIT (на основі коментарів @nnnnnn)

@nnnnnn:

чому б сказати test =(без var) це виправить?

Коли ви визначаєте функцію, як це:

var test = function(){};

Функція визначається локально, але коли ви визначаєте свою функцію без var:

test = function(){};

testвизначається на windowоб'єкті, що знаходиться на найвищому рівні.

чому це працює?

Як @zalun кажуть:

Якщо не вказати параметр обтікання, він за замовчуванням має значення "onLoad". Це призводить до того, що весь JavaScript буде завернуто в функцію, запущену після завантаження результату. Всі змінні є локальними для цієї функції, тому недоступні в глобальній області.

Але якщо ви використовуєте цей синтаксис:

test = function(){};

У вас є доступ до функції, testоскільки вона визначена в усьому світі


Список літератури:


2
Це дійсно найпростіший підхід - ви просто тестуєте крихітний шматочок коду в JSFiddle.
DOK

Але чому це працює? Надане вами посилання "Більше інформації" не пояснює, що проблема пов’язана зі сферою дії, або чому вирішення test = (без var) вирішило б її.
nnnnnn

@ R3tep добре, що ваше перше посилання, яке: jsfiddle.net/R3tep/Yazpj/1406, попередження нічого не робить для мене. Я на хромі.
Сід

@ R3tep так, це працює з console.log. Я опублікую запитання на ТАК, тому що я вважаю, що факт, що у мене немає вікна оповіщення, пов'язаний з іншою проблемою, що стосується iframes.
Сід

1
@ R3tep Я думаю, ви мене зрозуміли неправильно, але я не впевнений. Ваш код є / був хорошим. Існує проблема з тим, як кодується JSFiddle (відсутнє значення в атрибуті пісочниці iframe, який вони використовують для відображення результату). Це робить його таким, що він не працюватиме на якійсь версії хрому. Я надіслав звіт про випуск на їхній github. Мене це дуже зацікавило, тому що я вважав, що проблема, що виникає на моєму веб-сайті, була однаковою, але ні. Ура.
Ced

3

Змініть налаштування обгортання на панелі «Рамки та розширення» на «Немає підключення <body>»


-1

Немає проблем з вашим кодом. Просто виберіть розширення onLoad () з правого боку.



-3
Select OnDomready

HTML:

<input id="dButton" type="button" value="test"/>

JavaScript:

addEventListener('load', init, false);

function init()
{
  oInput = document.getElementById('dButton');
  oInput.onclick = test;
}

function test(){
  alert("test");
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.