Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Помогите понять логику (https://javascript.ru/forum/misc/52070-pomogite-ponyat-logiku.html)

ShutTap 03.12.2014 09:04

Помогите понять логику
 
Здравствуйте.
Как я понял, использование глобальных переменных - это плохо.
По-этому первый вопрос: как от них можно избавиться?
У меня есть скрипт onmouseover и onmouseout на элементе div, который при наведении увеличивает размеры элемента, а при убирании курсора - уменьшает. Плавно, по таймеру. Глобальная переменная нужна для запоминания размеров элемента на момент наведения или убирания курсора, для того, чтобы дальнейшие изменения размера начинались с момента текущего размера когда навели/убрали курсор, а не с "крайних" размеров.
Так же размеры элемента изменяются в соответствии с пропорциями ширина/высота, которые высчитываются в скрипте каждый раз заново. Ведь это нерациональная нагрузка, так? Ведь соотношение это не меняется на протяжении выполнении скрипта, а считать нужно каждый раз заново. Как сделать так, чтобы оно считалось только перый раз, а дальше бралось запомненное? Через глобальную переменную нельзя, так как скрипт может использоваться на нескольких элементах, и у каждого может быть разное соотношение сторон. Каждый раз передавать в функцию? И если передалость что-то, использовать его, а нет - высчитывать и передавать?

Второй вопрос такой: если я хочу изменять размеры не прописывая у каждого элемента onmouseover и onmouseout, а через аналогичные события addEventListener, как назначить их сразу всем элементам? Например элементам div с атрибутом zoom. А не каждому по отдельности. Или такое невозможно, и надо сначала взять все элементы getElementsByTagName('div') , а потом в цикле проверять, есть ли у него атрибут zoom, и если нет - удалять элемент, а потом опять в цикле с оставшимися элементами каждому назначать обработчик?

krutoy 03.12.2014 09:20

Цитата:

Сообщение от ShutTap
как от них можно избавиться?

Используй объекты в качестве неймспейсов, убирай в лексичкий скоп, типа
(function(){var a=1, b=2; dosuff}())

по ситуации. И в глобальных переменных ничего плохого нет, это базворд, по большому счету. Используй их когда это удобно.
Цитата:

Сообщение от ShutTap
Глобальная переменная нужна для запоминания размеров элемента на момент наведения или убирания курсора

можешь заменить ее свойством объекта, работать все будет также.

krutoy 03.12.2014 09:24

Цитата:

Сообщение от ShutTap
как назначить их сразу всем элементам? Например элементам div с атрибутом zoom. А

Прогони в цикле просто, если один обработчик, пройдись циклом по коллекции, и навесь каждому элементу обработчик.
<html>
<head></head>

<body>

<p a=1>foo</p>
<p a=1>foo</p>
<p>foo</p>
<p a=1>foo</p>
<p a=1>foo</p>



<script>

pCollect=document.querySelectorAll("p")
for(var i=0; i<pCollect.length; i++){
   if(pCollect[i].getAttribute("a")) pCollect[i].addEventListener("click", function(){alert(this.getAttribute("a"))})
}

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

krutoy 03.12.2014 09:53

Цитата:

Сообщение от ShutTap
Как сделать так, чтобы оно считалось только перый раз, а дальше бралось запомненное? Через глобальную переменную нельзя, так как скрипт может использоваться на нескольких элементах, и у каждого может быть разное соотношение сторон. Каждый раз передавать в функцию? И если передалость что-то, использовать его, а нет - высчитывать и передавать?

В этом случае, обычно, используют замыкания
mkCounter=function(start){return function(callb){start++; return callb(start)}}

counter1=mkCounter(10)
counter2=mkCounter(20)

counter1(function(x){console.log(x)})
counter1(function(x){console.log(x)})
counter1(function(x){console.log(x)})
counter2(function(x){console.log(x)})
counter2(function(x){console.log(x)})
counter2(function(x){console.log(x)})
// ::: 11
// ::: 12
// ::: 13
// ::: 21
// ::: 22
// ::: 23

каждая из ф-ций counter, имеет свое собственное состояние. Можно и объекты использовать для этих целй, разумется.
Counter=function(start){
   this.start=start
}
Counter.prototype.get=function(){return this.start}
Counter.prototype.set=function(){this.start++}

counter1=new Counter(10)
counter2=new Counter(20)

counter1.set()
counter1.set()
counter1.set()
console.log(counter1.get())

counter2.set()
counter2.set()
counter2.set()
console.log(counter2.get())

// ::: 13
// ::: 23

рони 03.12.2014 09:59

ShutTap,
document.querySelectorAll("[zoom]")
и есть же css3 scale

ShutTap 03.12.2014 16:58

спасибо за ответы) буду пробовать, разбираться переделывать все)

п.с. про zoom это я как пример

ShutTap 04.12.2014 10:16

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

krutoy 04.12.2014 10:43

ShutTap,
сколько выполняется -- очень просто
console.time("mark")
//code here
console.timeEnd("mark")

данные выводятся в консоль. Остальное -- в различных отладчиках.

kostyanet 04.12.2014 12:59

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

kostyanet 04.12.2014 13:04

Цитата:

Сообщение от ShutTap
Как я понял, использование глобальных переменных - это плохо.

Это хорошо, просто их надо складывать не в корень диска, а в папочку. Представьте если бы все файлы у вас лежали навалом на диске С.

В парадигме программирования та самая папочка это namespace. Функция или объект.

var MyLovelyFunction = function(){
 var one_global_in_the_function_variable = 1,
      the_two_one = one_global_in_the_function_variable + 1;
// и так далее
};


если надо сразу что-то сделать без деклараций независимости то заключаете функцию в скобки со скобками для аргументов (они там даже могут быть)

(function(){
 var one_global_in_the_function_variable = 1,
      the_two_one = one_global_in_the_function_variable + 1;
// и так далее
})();

kostyanet 04.12.2014 13:08

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

kostyanet 04.12.2014 13:11

Цитата:

Сообщение от ShutTap
как назначить их сразу всем элементам? Например элементам div с атрибутом zoom. А не каждому по отдельности. Или такое невозможно,

Делается в html родитель, который и отвечает за всех своих отпрысков. На него вешается опекунство addEventListener('mouseover',expand); и в функции expand(event){// получаем наведенный элемент через event.target}

Но если только они в куче. А если в разброде - то по классу выбираете и каждому фтыкаете в цикле.

tsigel 04.12.2014 18:09

kostyanet,
Глобальные переменные - это плохо. В большом проекте и если вы работаете в команде нельзя делать глобальные переменные. Пользуют requirejs для ослеживания зависимостей и получения объектов. В глобале только функция которая дает тебе объекты.

ShutTap 05.12.2014 13:00

а еще такой вопрос, назначил элементам обработчик циклом, один для всех. как в первом примере чтоб изменялись размеры у div.
Изменяются плавно по таймеру, и если поменяться размер не успел, а я навел на другой, анимация стопорится и анимируется следующий. то есть, для всех дивов один таймер, одна функция. как сделать так, чтобы элементы были независимы, чтобы доиграла анимация до конца независимо от того, что на другой тоже навелись. Пусть играют параллельно. Так понимаю, надо как-то делать копии функций и вызывать их или что-то типа того?

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

ShutTap 06.12.2014 17:04

и еще такой вопрос, допустим, есть функция, которая возвращает высоту и ширину какого-то элемента, return elemHeight и elemWidth
если я беру значение var Height = somfunc(elem).elemHeight
в таком случае функция считает только elemHeight или считает и elemHeight и elemWidth, но выводит только elemHeight?

то есть, с точки зрения скорости, получается лучше на каждую переменную в return писать свою функцию, чтобы при обращении к одному значению остальные не считались?

ShutTap 10.12.2014 08:34

так?


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