Меня троллит джаваскрипт
Имеется такая фабрика объектов:
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...) для дальнейшей работы. |
Меня опять троллит джаваскрипт!
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)) и работает как надо. |
Починил вроде. Всем спасибо за помощь.
( 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; })(); |
Цитата:
|
Опять не получается.
Пишу 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" или любую другую, то он перестаёт работать. Стеснительный. |
Опять какая-то шизофрения.
Задача: сделать плагин 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,Разрезать картинку
|
Цитата:
|
Цитата:
|
Цитата:
А мне надо разрезать элемент вне зависимости от position. |
А, понял.
При position=fixed по умолчанию устанавливается по умолчанию top=0; left=0, а если у меня картинка разрезается посередине окна, то эти разрезанные части изображения просто не видно. В jQuery UI Explode это как-то решили. Назначай любой position, сдвигай через margin / padding / top, left куда угодно, всё равно всё разрезается правильно. Компромисс - сделать explode только для картинок, игнорировать стили, тупо брать src. function Explode( elem, num ) { num = num || 3; 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 ); 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.overflow = "hidden"; var tileContent = document.createElement( "IMG" ); tile.appendChild( tileContent ); tileContent.src = elem.src; tileContent.height = elem.clientHeight; tileContent.width = elem.clientWidth; tileContent.style.marginTop = -height * i; tileContent.style.marginLeft = -width * j; Explode.animate( tile, left + width * j, top + height * i, Explode.direction( i, j, num ) ); } } elem.parentNode.removeChild( elem ); } Explode.animate = function ( elem, posX, posY, dir ) { var mY = dir[0]; var mX = dir[1]; var start = new Date().getTime(); setTimeout( animate, 10 ); var toY = posY - 50 * mY; var toX = posX + 50 * mX; function animate () { var m = (new Date().getTime() - start) / 500; if (m > 1) m = 1; elem.style.top = posY + (toY - posY) * m; elem.style.left = posX + (toX - posX) * m; elem.style.opacity = 1 - m; if (m < 1) setTimeout( animate, 10 ); } }; Explode.direction = function ( i, j, num ) { return [ (num-1) / 2 - i, j - (num-1) / 2 ] }; |
Часовой пояс GMT +3, время: 02:31. |