var getProperty = function(obj, propertySrc) {
var src = propertySrc.split('.');
var res = obj;
for (var i = 0, l = src.length; i < l; ++i) {
if (!(src[i] in res)) {
return void(0);
}
res = res[src[i]];
}
return res;
};
Working example:
http://jsfiddle.net/gkucmierz/5Df5D/
Pokazywanie postów oznaczonych etykietą JavaScript. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą JavaScript. Pokaż wszystkie posty
poniedziałek, 30 czerwca 2014
get nested property of object
Function that allows to get nested property of object. If it is not defined, function will return undefined.
niedziela, 23 lutego 2014
sort - stabilność sortowania
Kod JavaScript, którym można sprawdzić czy zaimplementowany algorytm sortowania jest stabilny czy nie.
Przykład jsfiddle: http://jsfiddle.net/gkucmierz/WWGa8/1/
var a = [
{n: 1, str: 'first'},
{n: 2, str: 'stable check 1'},
{n: 2, str: 'stable check 2'},
{n: 3, str: 'last'}
];
a.sort(function(a, b) {
return a.n - b.n;
});Przykład jsfiddle: http://jsfiddle.net/gkucmierz/WWGa8/1/
wtorek, 28 stycznia 2014
recursiveEach
recursiveEach - rekursywna iteracja po obiekcie. Funkcja do prawidłowego działania wymaga również 2 innych funkcji znajdujących się na tym blogu: getType oraz each.
Funkcję można dodatkowo rozbudować. Np. idealnie byłoby, gdyby w docelowej funkcji zamiast samej wartości klucza zwracała tablicę stringów wskazujących na ścieżkę do tego klucza w głównym obiekcie.
Przy pomocy tej funkcji łatwo zaimplementować funkcję flatten. Do funkcji flatten można przekazać zarówno obiekt jak i tablicę.
Funkcję można dodatkowo rozbudować. Np. idealnie byłoby, gdyby w docelowej funkcji zamiast samej wartości klucza zwracała tablicę stringów wskazujących na ścieżkę do tego klucza w głównym obiekcie.
var recursiveEach = function recur(obj, fn, depth) {
if (typeof depth === 'undefined')
depth = -1;
var res = {};
if (getType(obj) === 'Object' && depth !== 0) {
each(obj, function (el, key) {
res[key] = recur(el, fn, depth - 1);
});
return res;
}
return fn(obj);
};var getType = function (obj) {
return ({}).toString.call(obj).slice(8, -1);
};
var each = function (obj, fn) {
var res = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
res[i] = fn.call(obj, obj[i], i);
}
}
return res;
};Przy pomocy tej funkcji łatwo zaimplementować funkcję flatten. Do funkcji flatten można przekazać zarówno obiekt jak i tablicę.
var flatten = function(obj) {
var res = [];
recursiveEach(obj, function(val) {
res.push(val);
});
return res;
};
środa, 22 stycznia 2014
asyncMap - asynchroniczne iterowanie po tablicy
Funkcja pozwalająca na iterację po tablicy w sposób asynchroniczny. Można dzięki niej w genialnie prosty sposób wykonać np. kolejkę zadań, które wymagają wykonania asynchronicznych akcji np. zapytanie do innego serwera.
var asyncMap = function(arr, fn, endFn) {
var i = 0,
len = arr.length,
res = [];
(function callee() {
fn(arr[i], i, function(singleRes) {
res.push(singleRes);
if (++i < len) {
callee();
} else {
endFn(res);
}
}, arr);
})();
};
prosty przykład użycia: http://jsfiddle.net/gkucmierz/QzLP5/
niedziela, 29 września 2013
DialogsControl - kontrolowanie domyślnych okien dialogowych
Prosta funkcja/klasa pozwalająca kontrolować (udawać) okna dialogowe.
Przy pomocy metody disable możemy wyłączyć wyświetlanie wszystkich okien dialogowych. oba parametry tej metody pozwalają ustawić wartości zwracane przez funkcje confirm oraz prompt. Domyślne ich wartości to odpowiednio true oraz '' (pusty string).
Metoda restore pozwala przywrócić domyślne wartości tych funkcji czyli oryginalne okna dialogowe w obiekcie window. Domyślne pod warunkiem, że nie były one modyfikowane przez inny skrypt.
Gotowy kod z przykładami wywołania można przetestować tutaj http://jsfiddle.net/a8BvR/
Przy pomocy metody disable możemy wyłączyć wyświetlanie wszystkich okien dialogowych. oba parametry tej metody pozwalają ustawić wartości zwracane przez funkcje confirm oraz prompt. Domyślne ich wartości to odpowiednio true oraz '' (pusty string).
Metoda restore pozwala przywrócić domyślne wartości tych funkcji czyli oryginalne okna dialogowe w obiekcie window. Domyślne pod warunkiem, że nie były one modyfikowane przez inny skrypt.
var DialogsControl = function(w){
w = w || window;
var d = {
alert: w.alert,
confirm: w.confirm,
prompt: w.prompt
};
return {
disable: function(confirmRet, promptRet){
if (typeof confirmRet === 'undefined')
confirmRet = true;
if (typeof promptRet === 'undefined')
promptRet = '';
w.alert = function(){};
w.confirm = function(){return confirmRet;};
w.prompt = function(){return promptRet;};
},
restore: function(){
w.alert = d.alert;
w.confirm = d.confirm;
w.prompt = d.prompt;
}
};
};Gotowy kod z przykładami wywołania można przetestować tutaj http://jsfiddle.net/a8BvR/
onContentChange
Troszkę słabe rozwiązanie, ale pozwala wykryć zdarzenie zmiany treści na dowolnej stronie.
Zdarzenie po wykryciu odpina się automatycznie.
Przykład wywołania:
jsfiddle: http://jsfiddle.net/f82Um/1/
var onContentChange = function(htmlEl, fn) {
var content = htmlEl.innerHTML;
(function callee(){
if (htmlEl.innerHTML !== content) {
fn(htmlEl.innerHTML, content);
return;
}
setTimeout(callee, 50);
})();
};Zdarzenie po wykryciu odpina się automatycznie.
Przykład wywołania:
onContentChange(document.querySelector('div'), function(n, o){
alert(
'changed'+"\n"+
'old value: '+o+"\n"+
'new value: '+n
);
});jsfiddle: http://jsfiddle.net/f82Um/1/
czwartek, 12 września 2013
waitFor - zaczekaj na pojawienie się obiektu
Funkcja, która w bardzo prymitywny sposób czeka na pojawienie się oczekiwanego obiektu w bliżej nie określonym czasie. Czasami takie coś może się przydać jeśli inny skrypt tworzy obiekty i nie wiemy kiedy się pojawią.
var waitFor = function(obj, srcArr, fn, opt){
opt = opt || {t: 50};
(function callee(){
var tmp = obj;
var tid = setTimeout(callee, opt.t);
for (var i = 0; i < srcArr.length; ++i) {
if (typeof tmp[srcArr[i]] !== 'undefined') {
tmp = tmp[srcArr[i]];
} else {
return;
}
}
clearTimeout(tid);
fn(tmp, obj);
})();
};
Poniżej przykład użycia:
waitFor(window, 'abc.def'.split('.'), function(data, obj){
alert('jest: ' + data);
});
setTimeout(function(){
window.abc = {};
setTimeout(function(){
window.abc.def = 'obiekt/dane';
}, 1e3);
}, 1e3);
uruchamianie chrome script w oryginalnym window
Jak wiadomo w rozszerzeniach google chrome, kiedy chcemy użyć obiektu window i wykonać interakcję z istniejącymi skryptami na stronie, lub zostawić dostęp do funkcji tak aby była widoczna z konsoli mamy mocno utrudnione zadanie ponieważ przeglądarka tworzy specjalnie dla skryptu nowy wirtualny obiekt window.
Poniżej stworzyłem kawałek kodu - hack, który pozwala na wykonanie naszego userscript w oryginalnym scope.
Może da się to zrobić jakoś lepiej. Zapraszam do komentowania.
Poniżej stworzyłem kawałek kodu - hack, który pozwala na wykonanie naszego userscript w oryginalnym scope.
Może da się to zrobić jakoś lepiej. Zapraszam do komentowania.
"use strict";
(function main(w){
if (chrome.extension) {
var s = document.createElement('script');
s.src = 'data:text/javascript;base64,' + btoa('('+main.toString()+')(window);');
document.getElementsByTagName('head')[0].appendChild(s);
return;
}
w.test = "ta zmienna powinna byc widoczna z konsoli";
})(window);
niedziela, 10 lutego 2013
Odblokowanie prawego klawisza myszy
Niektóre strony blokują prawy klawisz myszy w dokumencie. Przykładowy, kod który to realizuje znajduje się pod adresem pastebin.com/jyKeaZpZ.
Aby sobie z tym poradzić bez wyłączania JavaScript wystarczy wkleić poniższy kod do paska adresu.
Aby sobie z tym poradzić bez wyłączania JavaScript wystarczy wkleić poniższy kod do paska adresu.
javascript:document.oncontextmenu=function(){};
środa, 6 lutego 2013
Global scope
Przydatne do sprawdzania co jest w przeglądarce. Co zostało dodane przez skrypty a nie jest natywnym elementem JavaScript`u czy DOM.
(function(){
var w = window.open('about:blank');
var res = [];
for( var i in window ){
if( typeof w[i] === 'undefined' ){
res.push(i);
}
}
w.close();
return res;
})().join('\n');
środa, 23 stycznia 2013
odpowiednik htmlspecialchars w js
Odpowiednik funkcji htmlspecialchars znanej z PHP.
var htmlspecialchars = function(html){
return [
[/&/g, '&'],
[/</g, '<'],
[/>/g, '>'],
[/"/g, '"'],
[/'/g, ''']
].reduce(function(h, r){
return h.replace(r[0], r[1]);
}, html);
};
Funkcja przydatna np. do umieszczania kodu na tym blogu. Przykład użycia:
prompt('skopiuj kod HTML', htmlspecialchars(prompt('podaj kod HTML')));
poniedziałek, 21 stycznia 2013
Binary - operacje na bitach
Funkcja upraszczająca operacje na bitach w JavaScript.
var Binary = function(val){
val = val || 0;
return {
value: function(v){
if( typeof v === 'undefined' )
return val;
val = v;
},
bit: function(n, v){
if( typeof v === 'undefined' )
return val & (1<<n) ? 1 : 0;
if( v ){
val |= 1<<n;
}else{
val &= ~(1<<n);
}
},
toString: function(){
return val.toString(2);
}
};
};
Warto pamiętać, że operacje bitowe w JavaScript są powolne, ponieważ JavaScript przechowuje wszystkie liczby (Number) jako double. W związku z tym każda operacja bitowa (przesunięcie bitowe, suma bitowa czy iloczyn bitowy) wymusza konwersję double na int.
// utworz nowa wartosc 5 var b = new Binary(5); // odczytaj drugi bit console.log(b.bit(2)); // ustaw pierwszy bit na 1 b.bit(1, true); // odczytaj wartosc liczbowa console.log(b.value());
sobota, 5 stycznia 2013
getForm oraz getFormInputs
Dwie przydatne funkcje przy sprawdzaniu pól formularza na stronie.
Pierwsza funkcja getForm wyszukuje formularz zawierający podany jako argument element.
var getForm = function(htmlObj){
return htmlObj.form || (function callee(o){
return o.tagName === 'FORM' ? o : o.parentNode && callee(o.parentNode);
})(htmlObj);
};
Kolejna funkcja getFormInputs znajduje wszystkie pola wysyłane do serwera. Zwraca obiekt z kluczami zawierającymi name pola oraz im odpowiadającymi wartościami zawierającymi value pola.
var getFormInputs = function(form){
var res = {};
[].concat(
[].slice.call(document.getElementsByTagName('textarea')),
[].slice.call(document.getElementsByTagName('input'))
).map(function(obj){
if( typeof obj.name !== 'undefined' ){
res[obj.name] = obj.value;
}
});
return res;
};
piątek, 28 grudnia 2012
Breakpoint js
Breakpoint - przydatna funkcja do przerywania asynchronicznego kodu.
Wymaga obecności DOM (Document Object Model). Tworzy w nim przycisk, który umożliwia ręczne wywołanie zatrzymanych fragmentów kodu. Funkcja pozwala sprawnie śledzić błędy w ekstremalnych warunkach :)
var Breakpoint = (function(doc){
doc = doc || document;
var fns = [];
var btn = doc.createElement('button');
btn.innerHTML = 'Breakpoint';
btn.addEventListener('click', function(e){
fns.shift().call();
update();
});
doc.body.appendChild(btn);
var update = function(){
btn.disabled = !fns.length;
};
update();
return {
add: function(fn){
fns.push(fn);
update();
}
};
})();
Przykład użycia:
// bez Breakpoint:
var test = function(){
// czynnosc A
// czynnosc B
};
// to samo z Breakpoint:
var test = function(){
// czynnosc A
Breakpoint.add(function(){
// czynnosc B
});
};
sobota, 3 marca 2012
Array unique - czyli pozbywamy się duplikatów
Funkcja jako argument przyjmuje tablicę z danymi dowolnego typu. W rezultacie funkcja zwraca tablicę zawierającą tylko unikalne elementy tablicy źródłowej.
var unique = function(arr){
return arr.filter(function(el, i){
return arr.indexOf(el, i+1) === -1;
});
};Poniżej zamieszczam funkcję robiącą to samo co powyższa funkcja z drobnym wyjątkiem. Poniższa funkcja zawiera dwa dodatkowe wykonania funkcji reverse co pozwoliło na zachowanie naturalnej kolejności elementów występujących w tablicy. Pierwsze wystąpienie danego elementu pozostaje w tym samym miejscu, kolejne wystąpienia tego samego elementu są ignorowane. W poprzedniej wersji funkcji to ostatni element zostałby zachowany. var unique = function(arr){
return arr.reverse().filter(function(el, i){
return arr.indexOf(el, i+1) === -1;
}).reverse();
};let unique = [...new Set(myArray)];
środa, 22 lutego 2012
getType - sprawdzenie typu, pewniejsze od typeof
Poniżej zamieszczam funkcję zwracającą typ danej. Funkcja w przeciwieństwie do operatora typeof znacznie skuteczniej oddaje typ przekazanej danej. Pomysł został zaczerpnięty z serwisu JavaScript Garden. Funkcja do sprawdzenia typu wykorzystuje generyczną funkcję toString podstawowego obiektu.
var getType = function(obj){
return ({}).toString.call(obj).slice(8, -1);
};
Poniżej szybkie sprawdzenie różnic funkcji getType oraz operatora typeof. Pomaga on uświadomić sobie, z jakimi problemami mamy do czynienia, jeśli używamy operatora typeof.
[{}, [], '', 0, 1/0, false, function(){}, /./, null, undefined].map(function(obj){
return [getType(obj), typeof obj];
});
Tak naprawdę operator typeof JavaScriptu ma tylko jedno uzasadnione zastosowanie.
typeof variable === 'undefined';
wtorek, 14 lutego 2012
Object each - iteracja po obiekcie
Poniżej zamieszczam bardzo przydatną funkcję pozwalającą w prosty sposób iterować po obiekcie.
var each = function(obj, fn){
var res = {};
for( var i in obj ){
if( obj.hasOwnProperty(i) ){
res[i] = fn.call(obj, obj[i], i);
}
}
return res;
};
Przykład zastosowania:
each({
name: 'Grzegorz',
job: 'web developer',
website: 'gkucmierz.blogspot.com'
}, function(value, key){
alert([key, ': ', value].join(''));
});
poniedziałek, 13 lutego 2012
Twoja przeglądarka nie obsługuje JavaScript
Przeglądając kod źródłowy pewnej strony natknąłem się na ciekawy kawałek kodu. Na szczególną uwagę zasługuje linijka 902 :)
sobota, 11 lutego 2012
Array shuffle
Implementacja funkcji mieszającej elementy tablicy w języku JavaScript.
Array.prototype.shuffle = function(){
return this.sort(function(){
return Math.random() - 0.5;
});
};Przykład użycia: [1, 2, 3].shuffle();Poniżej inna implementacja bez użycia prototypów.
var shuffle = function(arr){
return arr.sort(function(){
return Math.random() - 0.5;
});
};
piątek, 10 lutego 2012
Pobranie treści strony przy pomocy XMLHttpRequest
Poniższa funkcja pozwala pobrać treść podstrony przy pomocy JavaScript.
var get = function(url, fn){
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onabort = xhr.onerror = function(){
fn(false);
};
xhr.onreadystatechange = function(resp){
if( xhr.readyState === 4 ){
fn(resp.target.responseText, resp);
}
};
xhr.send();
};
Subskrybuj:
Posty (Atom)
