Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Не работает onclick (https://javascript.ru/forum/misc/73304-ne-rabotaet-onclick.html)

Dimasikylll 05.04.2018 03:39

Не работает onclick
 
let flips = document.querySelectorAll('.flip');

onclick = (event) => {
	if(flips[5] === event.target)
	{
	       alert("hello");
	}

   ...   //другие работающие функции
}

Почему не выводится hello при клике на флипс? Ошибок никаких не показывает и просто не хочет работать, но работает с другим вариантом:

flips[5].onclick = () => {
  alert('hello');
}


Оба варианта ведь должны работать, разве нет?

j0hnik 05.04.2018 03:56

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div class="flip">0</div>
<div class="flip">1</div>
<div class="flip">2</div>
<div class="flip">3</div>
<div class="flip">4</div>
<div class="flip">5</div>
	<script>

let flips = document.querySelectorAll('.flip');

flips.forEach((el,i)=>el.onclick = (event) => {
	if(i==5) alert("hello");
});

	</script>
</body>
</html>


У вас обработчик на воздух навешивается?

Dimasikylll 05.04.2018 04:11

В первом варианте клик считывается на всех элементах и таргет указывает, на каком именно элементе клик нужен, разве нет?

sortarray 05.04.2018 10:45

Цитата:

Сообщение от Dimasikylll (Сообщение 482355)
В первом варианте клик считывается на всех элементах и таргет указывает, на каком именно элементе клик нужен, разве нет?

Вообще то не на все, а на window

Но код работает

<html>
<head>
<meta charset = "utf-8" />
<style>
</style>
</head>

<body>

<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>
<div class = "flip">flip</div>

<script>

const flips = document.querySelectorAll(".flip")

onclick = function(event){
   if(flips[2] === event.target) alert(100)
}


</script>

</body>
</html>

Посмотрите, нет ли других ошибок

Dimasikylll 05.04.2018 14:13

Не выдаёт никаких ошибок и работает только при навешивании клика на каждый элемент, без понятия почему

Nexus 05.04.2018 14:38

Dimasikylll, вы все обработчики события click вешаете через свойство и на глобальный объект window?
Почитайте: https://learn.javascript.ru/introduc...82%D0%B2%D0%BE

Dimasikylll 05.04.2018 14:58

Я не вешаю несколько обработчиков на один элемент. Либо проверяю клик через window, либо просто вешаю клик на элемент. По отдельности оба способа должны работать, но у меня работает только при навешивании клика на элемент.

sortarray 05.04.2018 15:10

Цитата:

Сообщение от Nexus
Dimasikylll, вы все обработчики события click вешаете через свойство и на глобальный объект window?
Почитайте: https://learn.javascript.ru/introduc...82%D0%B2%D0%BE

То что там написано, это правда, но про "фундаментальный недостаток" автор явно погорячился, это фиксится парой строк.
С другой стороны, расхваливаемые им функции, типа addEventListener имеют свои недостатки, и они даже, по-моему, посерьезней

Так что этот способ вполне годный. Нет смысла отказываться от него.

Malleys 05.04.2018 15:21

Если что-то не получается или работает не как ожидалось, можно вывести в в консоль

onclick = event => {
    console.log(event, event.target);
};

Nexus 05.04.2018 15:23

Цитата:

Сообщение от sortarray
про "фундаментальный недостаток" автор явно погорячился, это фиксится парой строк.

Если вас не затруднит написать эти пару строк, продемонстрируйте их, пожалуйста.
Цитата:

Сообщение от sortarray
С другой стороны, расхваливаемые им функции, типа addEventListener имеют свои недостатки, и они даже, по-моему, посерьезней

Можете объяснить недостаток объявления обработчика этим методом?

sortarray 05.04.2018 15:36

Цитата:

Сообщение от Nexus
Если вас не затруднит написать эти пару строк, продемонстрируйте их, пожалуйста.

<html>
<head>
<meta charset = "utf-8" />
<style>
</style>
</head>

<body>

<div id = "foo">click me</div>

<script>

foo.storage = []
foo.onclick = function(){var self = this; foo.storage.forEach(function(f){f.call(self)})}
with(foo){
 storage.push(function(){alert(this.innerHTML)})
 storage.push(function(){alert(this.id)})
 storage.push(function(){alert("fuck addEventListener")})
}

</script>

</body>
</html>

Цитата:

Сообщение от Nexus
Можете объяснить недостаток объявления обработчика этим методом?

Там их целая куча -- невозможность удаления без сохранения ссылок, отсутствие гибкости, тормоза и т.д

Dimasikylll 05.04.2018 15:44

Malleys, спасибо. Там оказывается клик считывался на дочернем элементе с абсолютным позиционированием.

Nexus 05.04.2018 15:49

sortarray, это вот ваше решение проблемы?
Прошу прощения, но каким образом ваш код избавит меня от затирания прошлого обработчика события на "левом" элементе?
Более того, если я не буду знать о вашем костыле и объявлю новый обработчик элементу #foo через свойство, то все ваши handler'ы нафиг поотваливаются.

Цитата:

Сообщение от sortarray
невозможность удаления без сохранения

Ну, ваш вариант тут тоже не блещет, мягко говоря.
Цитата:

Сообщение от sortarray
отсутствие гибкости

Можете пояснить?
Цитата:

Сообщение от sortarray
тормоза

Если левой ногой программировать, то тормозить будет любой код :)

sortarray 05.04.2018 15:55

Nexus,
Цитата:

Сообщение от Nexus
Прошу прощения, но каким образом ваш код избавит меня от затирания прошлого обработчика события на "левом" элементе?
Более того, если я не буду знать о вашем костыле и объявлю новый обработчик через свойство, то все ваши handler'ы нафиг поотваливаются.

Это какая-то непонятная для меня хрень. Тут все от рук зависит
Цитата:

Сообщение от Nexus
Ну, ваш вариант тут тоже не блещет, мягко говоря.

В моем можно удалять обычным способом, по индексу, сигнатуре функции и т.д
Никаких ограничений.
Цитата:

Сообщение от Nexus
Можете пояснить?

Там, опять же, тма тмущая. Например, можно шарить поведение между двумя объектами. Прозрачность, опять же.
Цитата:

Сообщение от Nexus
Если левой ногой программировать, то тормозить будет любой код

Но от нативных тормозов хороший код не избавит

Nexus 05.04.2018 16:06

Цитата:

Сообщение от sortarray
Это какая-то непонятная для меня хрень. Тут все от рук зависит

Что непонятного?
Вы в проекте все обработчики на 1 элемент вешаете или для каждого будете создавать отдельное хранилище и пушить в него хандлеры?
Ваше решение работоспособно до тех пор, пока я не захочу объявить обработчик через свойство, а не через ваш велосипед.
foo.storage = []
foo.onclick = function(){var self = this; foo.storage.forEach(function(f){f.call(self)})}
with(foo){
 storage.push(function(){alert(this.innerHTML)})
 storage.push(function(){alert(this.id)})
 storage.push(function(){alert("fuck addEventListener")})
}
foo.onclick=()=>{
alert(prompt('Угадайте сколько раз вылезет alert',0)==1);
};


Цитата:

Сообщение от sortarray
В моем можно удалять обычным способом, по индексу
Никаких ограничений.

В вашем случае точно также нужно хранить индекс записанного обработчика.
Цитата:

Сообщение от sortarray
сигнатуре функции

Пример можно?

Цитата:

Сообщение от sortarray
Но от нативных тормозов хороший код не избавит

Он их не допустит, имхо. Можете привести пример тормозящего addEventListener'а?

Nexus 05.04.2018 16:17

Не очень решение для нескольких элементов + страшно представить код для обработки второго события )
<html>
<head>
<meta charset = "utf-8" />
<style>
</style>
</head>

<body>

<div id = "foo">click me</div>
<div id = "bar">click me</div>

<script>

foo.storage = []
foo.onclick = function(){var self = this; foo.storage.forEach(function(f){f.call(self)})}
with(foo){
 storage.push(function(){alert(this.innerHTML)})
 storage.push(function(){alert(this.id)})
 storage.push(function(){alert("fuck addEventListener")})
}

bar.storage = []
bar.onclick = function(){var self = this; foo.storage.forEach(function(f){f.call(self)})}
with(bar){
 storage.push(function(){alert(this.innerHTML)})
 storage.push(function(){alert(this.id)})
 storage.push(function(){alert("fuck addEventListener")})
}

</script>

</body>
</html>

+ Вы начинали с того, что хвалили объявление обработчиков через свойство, однако один фиг от него ушли, ибо ваше решение его просто не поддерживает (писал выше).

sortarray 05.04.2018 16:23

Nexus,
Я полагаю этот спор пустым, мне не интересно что-то доказывать. Кто понимает, тот и без того понимает
Вообще, в программировании всегда действует принцип "явное лучше неявного".
Если даже реализовать addEventListener с тем же поведением, что нейтив, самостоятельно, это будет лучше хардкора

Nexus 05.04.2018 16:27

sortarray, отчего же пустым?
Если вы докажете свою точку зрения, то те "заблудшие души", что объявляют event listener'ы через метод "addEventListener" задумаются о эффективности такого подхода и, возможно, перейдут на использование вашего велосипеда.
В противном случае, я таки надеюсь, вы задумаетесь о эффективности уже вашего решения etc.

Nexus 05.04.2018 16:31

Цитата:

Сообщение от sortarray
Кто понимает, тот и без того понимает

Если есть тут другие понимающие, приведите, пожалуйста, пример кода, где будет показана неэффективности объявления обработчика через "addEventListener" в пользу предлагаемого уважаемым sortarray метода.

Nexus 05.04.2018 16:37

Цитата:

Сообщение от sortarray
Вообще, в программировании всегда действует принцип "явное лучше неявного".

document.querySelector('#id').storage.click.push(function(){});//Т.е. объявление обработчика события таким способом более "явное", чем строкой ниже?
document.querySelector('#id').addEventListener('click',function(){});

Цитата:

Сообщение от sortarray
Если даже реализовать addEventListener с тем же поведением, что нейтив, самостоятельно, это будет лучше хардкора

Голословное заявление.

Upd. https://jsfiddle.net/oL8z9r38/

sortarray 05.04.2018 16:54

Nexus,
Что касается тормозов нейтива, не поленился, протестил, резуьтат меня самого поразил, разница у меня в хроме X10 примерно. Я ожидал тормозов, но чтобы так.

<html>
<head>
<meta charset = "utf-8" />
<style>
</style>
</head>

<body>

<div id = "foo">click me foo</div>
<div id = "bar">click me bar</div>
<button id = "check">check</button>

<script>

foo.storage = []
foo.onclick = function(){var self = this; foo.storage.forEach(function(f){f.call(self)})}

var startTimeForCustom
var startTimeForNative 
var endTimeForCustom
var endTimeForNative

foo.storage.push(function(){startTimeForCustom = new Date()})
i = 10000
while(i--) foo.storage.push(function(){return 1 + 1})
foo.storage.push(function(){endTimeForCustom = new Date(); console.log("end custom")})


bar.addEventListener("click", function(){startTimeForNative = new Date()})
i = 10000
while(i--) bar.addEventListener("click", function(){return 1 + 1})
bar.addEventListener("click", function(){endTimeForNative = new Date(); console.log("end native")})

check.onclick = function(){
   console.log("custom: " + (endTimeForCustom - startTimeForCustom))
   console.log("native: " + (endTimeForNative - startTimeForNative))
}








</script>

</body>
</html>


И это при том, что перебор идет через нативный форич, то есть можно еще оптимизировать циклом.

sortarray 05.04.2018 16:56

Цитата:

Сообщение от Nexus
Если вы докажете свою точку зрения

Просто мне не интересно спорить о том, что для меня очевидно.
Единственное в чем было сомнение, это скорость

Nexus 05.04.2018 17:01

sortarray, и что вы замеряли в 21-м посту?
Скорость добавления в очередь?
Вам не кажется, что нужно замерять скорость её исполнения?

Смотрите 20-й пост.
Ваш метод стабильно на 200ms уступает.

sortarray 05.04.2018 17:05

Цитата:

Сообщение от Nexus
Скорость добавления в очередь?

не, исполнения

Nexus 05.04.2018 17:11

sortarray, согласен, на более тривиальных задачах ваш метод быстрее.

sortarray 05.04.2018 17:11

Цитата:

Сообщение от Nexus
Скорость добавления в очередь?

а скорость добавления вообще феерично

custom: 38.375244140625ms
native: 3365.93896484375ms

sortarray 05.04.2018 17:18

Цитата:

Сообщение от Nexus
на более тривиальных

на любых

Nexus 05.04.2018 17:22

sortarray,
Цитата:

Сообщение от sortarray
на любых

Боюсь нет.

sortarray 05.04.2018 17:24

Цитата:

Сообщение от Nexus
Боюсь

Не могу вас избавить от фобий, не специалист.

j0hnik 05.04.2018 17:35

querySelectorAll; в ~20 раз медленнее getElementsByClassName или getElementsByTagName, но вряд ли это-кто-то заметит если из не >100 000

sortarray 05.04.2018 17:40

Nexus,
Что касается вашего кода, то у меня там вся консоль засралась, я ничего не понял. Кто так тестит, что всю консоль выхлопом засирает? Убрал выхлоп, получилось примерно то же самое, что у меня. Так что не надо лапшу тут вешать

j0hnik 05.04.2018 17:42

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

j0hnik 05.04.2018 17:45

sortarray,
сам браузер тоже влияет, некоторые методы в FF выполняются в 5-10 раз быстрей чем в хроме, другие же наоборот.

Nexus 05.04.2018 17:47

sortarray, в Chrome в консоль выводится 4 строки, 2 из которых со счетчиком.

j0hnik 05.04.2018 17:48

https://jsperf.com/ -вот хороший сервис чтобы скорость тестировать

sortarray 05.04.2018 17:48

Цитата:

Сообщение от j0hnik
но вряд ли это-кто-то заметит

Смотря на какой задаче. Если много операций с DOM -- вполне. Они и сами по себе самые тормозные, а тут еще медленные селекторы

sortarray 05.04.2018 17:51

Цитата:

Сообщение от Nexus
в Chrome в консоль выводится 4 строки, 2 из которых со счетчиком.

Меня вывод в консоль самих колбеков не интересует, это вообще асинхронная операция. Короче, на вашем коде, который исправлен на нормальный, отслеживающий то-что нужно, addEventListener точно так же позорно слил

https://jsfiddle.net/asaLt1by/

j0hnik 05.04.2018 17:51

Цитата:

Сообщение от sortarray (Сообщение 482485)
Смотря на какой задаче.

;)

sortarray 05.04.2018 17:57

Цитата:

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

вопрос не только в самих абстракциях, но и возможности их реализации. Использование хардкорных абстракций тут только в минус.

Плюсом тут только универсальность кода при совместной разработке.
Почти все методы массивов можно написать и без нативной поддержки. Нативная поддержка нужна только для специфических фич, таких как Proxy, например

sortarray 05.04.2018 18:08

Цитата:

Сообщение от j0hnik
зачем нужны языки с динамической типизацией если на выполнение требуется больше процессорного времени?

Кстати, основная задача статической типизации не в скорости, а в проверке типов на стадии компиляции. Это еще не факт, что динамика во всех случаях сольет, взять хоть те же хаскель, жаву или решетку -- достаточно тормозные языки, в целом, особенно по памяти


Часовой пояс GMT +3, время: 04:19.