31.01.2017, 17:42
|
Кандидат Javascript-наук
|
|
Регистрация: 21.01.2017
Сообщений: 139
|
|
Меня троллит джаваскрипт
Имеется такая фабрика объектов:
function $() {
var res = $.proto;
res.length = arguments.length;
for ( var i = 0; i < arguments.length; i++ ) {
res[i] = arguments[i];
}
return res;
}
$.proto = {};
Хочу переставить все объекты в обратном порядке, создаю метод, но при создании нового объекта this затирается!
$.proto.reverse = function () { // здесь this нормальный (проверка алертом)
var res = $(); // а здесь уже пустой $()
for ( var i = 0; i < this.length; i++ ) {
res[i] = this[this.length - i - 1];
}
res.length = this.length;
return res;
};
$( 0, 1, 2, 3, 4, 5 ).reverse(); // в любом случае пустой $()
Почему создание нового $()-объекта затирает this?
Причём есть идентичный по структуре метод extract, который достаёт элементы между позицией A и B:
$.proto.extract = function ( from, to ) {
var res = $();
for ( var i = 0; i < to - from; i++ ) {
res[i] = this[from + i];
}
res.length = to - from;
return res;
};
$( 0, 1, 2, 3, 4, 5 ).extract( 2, 4 ); // возвращает объект $( 2, 3 )
И тут this не затирается, всё работает как надо.
Тут так же создаю новый $(), вставляю элементы, а потом возвращаю $(e1, e2...) для дальнейшей работы.
Последний раз редактировалось Diphenyl Oxalate, 31.01.2017 в 17:47.
|
|
02.02.2017, 03:59
|
Кандидат Javascript-наук
|
|
Регистрация: 21.01.2017
Сообщений: 139
|
|
Меня опять троллит джаваскрипт!
Animate.color = function ( elem, attr, to, time ) {
// поскольку на вход могут подать название цвета ("pink") или hex-значение (#ff69b4)
// преобразуем его в rgb(205, 105, 180), заставив браузер вычислить его
var I = document.createElement( "DIV" );
I.style.backgroundColor = to;
document.body.appendChild( I );
var colorEnd = getComputedStyle( I ).backgroundColor.match( /(\w{1,3})/g ); // получаем [205, 105, 180]
document.body.removeChild( I ); // убираемся за собой
var colorStart = getComputedStyle( elem )[attr].match( /(\w{1,3})/g ); // начальный цвет элемента
var start = new Date().getTime();
setTimeout( function () {
var diff = new Date().getTime() - start;
if ( diff < time ) { // alert(diff) даёт 10
elem.style[attr] = "rgb(" + A( colorStart[0], colorEnd[0], diff/time ) + ", " + A( colorStart[1], colorEnd[1], diff/time ) + ", " + A( colorStart[2], colorEnd[2], diff/time ) + ")";
setTimeout( arguments.callee, 10 ); // НО НОВЫЙ SETTIMEOUT ПРОСТО НЕ ВЫЗЫВАЕТСЯ, ХОТЬ ТЫ ТРЕСНИ
}
}, 10 );
};
function A ( x, y, z ) { // вспом. ф-я для выч. from + (to - from) * (diff / time)
return +x + (+y - +x) * +z;
}
Вызывается так:
Animate.color( document.getElementById("foo"), "backgroundColor", "black", 1000 );
Причём есть аналогичная функция для изменения других параметров (ширина, высота и т.д.), там всё считается по той же формуле ( from + (to - from) * (diff / time)) и работает как надо.
Последний раз редактировалось Diphenyl Oxalate, 02.02.2017 в 04:07.
|
|
02.02.2017, 13:57
|
Кандидат Javascript-наук
|
|
Регистрация: 21.01.2017
Сообщений: 139
|
|
Починил вроде. Всем спасибо за помощь.
( function () {
var Anim = {};
Anim.fxHelper = function ( elem, attr, to, dur ) {
var from = getComputedStyle( elem )[attr];
from = +from.replace( "px", "" );
var start = new Date().getTime();
var animation = function () {
var m = (new Date().getTime() - start) / dur;
if (m > 1) m = 1;
elem.style[attr] = from + (to - from) * m;
if (m < 1) setTimeout( animation, 10 );
};
setTimeout( animation, 10 );
};
Anim.fx = function ( elem, data, dur ) {
for ( var i in data ) {
if ( i.indexOf("olor") != -1 ) {
Anim.color( elem, i, data[i], dur );
continue;
}
Anim.fxHelper( elem, i, data[i], dur );
}
};
Anim.color = function ( elem, attr, to, time ) {
var I = document.createElement( "DIV" );
I.style.backgroundColor = to;
document.body.appendChild( I );
var colorEnd = getComputedStyle( I ).backgroundColor.match( /(\d{1,3})/g );
document.body.removeChild( I );
var colorStart = getComputedStyle( elem )[attr].match( /(\d{1,3})/g );
var start = new Date().getTime();
var animation = function () {
var m = (new Date().getTime() - start) / time;
if (m > 1) m = 1;
elem.style[attr] = "rgb(" + A( colorStart[0], colorEnd[0], m ) + ", " +
A( colorStart[1], colorEnd[1], m ) + ", " +
A( colorStart[2], colorEnd[2], m ) + ")";
if (m < 1) setTimeout( animation, 10 );
};
setTimeout( animation, 10 );
};
function A ( x, y, z ) {
x = +x;
y = +y;
return (x + (y - x) * z).toFixed(0);
}
window.Animate = Anim.fx;
})();
|
|
02.02.2017, 14:09
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,231
|
|
Сообщение от Diphenyl Oxalate
|
Починил вроде
|
Т.е. дело не в бабине?
|
|
02.02.2017, 15:22
|
Кандидат Javascript-наук
|
|
Регистрация: 21.01.2017
Сообщений: 139
|
|
Опять не получается.
Пишу jQuery-подобную библиотеку, создаю методы:
$.proto.import( {
html : function ( content ) {
return this.attr( "innerHTML", content );
},
val : function ( content ) {
return this.attr( "value", content );
},
id : function ( content ) {
return this.attr( "id", content );
}
);
Всё работает, но это индусский код. У меня же там будет ещё и .href(), .name(), .title(), .src(), ну в общем все стандартные атрибуты.
Решил сделать так:
var attrs = {
"html" : "innerHTML",
"val" : "value",
"href" : 0,
"src" : 0
};
for ( var i in attrs ) {
$.proto[ i ] = function ( content ) {
return this.attr( attrs[i] || i, content );
}
}
Но метод перестаёт работать.
И что самое странное, если в attrs оставить только одну пару, например "html" : "innerHTML", то метод .html() начинает работать исправно! А если добавить пару "val" : "value" или любую другую, то он перестаёт работать. Стеснительный.
|
|
04.02.2017, 11:07
|
Кандидат Javascript-наук
|
|
Регистрация: 21.01.2017
Сообщений: 139
|
|
Опять какая-то шизофрения.
Задача: сделать плагин explode (при клике элемент "разлетается" на части).
План:
- создать NxN ячеек с overflow=hidden (с этим проблем нет)
- поместить туда копии элемента (вот здесь проблема)
- сдвинуть маргинами, анимировать
Никак не могу поместить копии элемента в ячейки.
Если поставить var tileContent = elem.outerHTML; (восьмая строчка в коде), то оригинальный элемент чудесным образом не удаляется, а в ячейки не добавляются! Если же вместо outerHTML поставить innerHTML, то всё работает, но стили оригинального элемента теряются, чего допустить нельзя. cloneNode не помогает, эффект такой же, как с outerHTML.
function Explode( elem, num ) {
num = num || 3; // num*num ячеек
var pos = elem.getBoundingClientRect();
var top = pos.top;
var left = pos.left;
var width = Math.round( elem.clientWidth / num );
var height = Math.round( elem.clientHeight / num );
var tileContent = elem.outerHTML;
elem.parentNode.removeChild( elem );
for ( var i = 0; i < num; i++ ) {
for ( var j = 0; j < num; j++ ) {
var tile = document.createElement( "DIV" );
document.body.appendChild( tile );
tile.style.position = "fixed";
tile.style.width = width;
tile.style.height = height;
tile.style.top = top + height * i;
tile.style.left = left + width * j;
tile.style.border = "1px solid #000000";
tile.style.overflow = "hidden";
tile.innerHTML = tileContent;
}
}
}
UPD: этот глюк только если у оригинального элемента position=fixed.
Последний раз редактировалось Diphenyl Oxalate, 04.02.2017 в 11:11.
|
|
04.02.2017, 11:19
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,130
|
|
|
|
04.02.2017, 11:35
|
Кандидат Javascript-наук
|
|
Регистрация: 21.01.2017
Сообщений: 139
|
|
Перестаёт работать, если назначить position=fixed.
|
|
04.02.2017, 11:52
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,130
|
|
Сообщение от Diphenyl Oxalate
|
Перестаёт работать, если назначить position=fixed.
|
не осилил
|
|
04.02.2017, 12:38
|
Кандидат Javascript-наук
|
|
Регистрация: 21.01.2017
Сообщений: 139
|
|
Сообщение от рони
|
не осилил
|
Если картинке назначить position=fixed, то скрипт перестаёт работать.
А мне надо разрезать элемент вне зависимости от position.
|
|
|
|