RSS
 

HTML5 Canvas – Hissə 1

26 Nov

Əvvəlcədən qeyd edim ki, bu məqalə hazırlanarkən oxucunun sadə HTML və Javascript biliklərinə malik olduğu nəzərdə tutulur. Bunun üçün də bacardığım qədər sadə dildə yazmağa çalışacam. Başlanğıc üçün sizə müasir brauzerlərdən biri (Google Chrome, Mozilla Firefox, Safari, Opera və ya İE9) və text editor (məs: notepad) kifayət edər.

HTML5 Canvas elementi veb səhifədə qrafika çəkmək üçün istifadə olunur. Özü-özlüyündə Canvas elementi qrafika üçün konteyner rolunu oynayır. Üzərində təsvir çəkmək üçün isə Javascript istifadə edilir. Canvas – hər bir pikselini sizin idarə etdiyiniz düzbucaqlı sahədir. Gəlin aşağıdakı kodu nəzərdən keçirək:

<!DOCTYPE HTML>
<html> 
    <head>
       <style type="text/css" rel="stylesheet">
           canvas { border: solid 1px #000; } 
       </style> 
       <script type="text/javascript"> 
           window.onload = function() { 
               var c = document.getElementById( "myCanvas" ); 
               
               //əgər brauzer canvas elementini dəstəkləyirsə 
               if ( c.getContext ) { 
                   var cxt = c.getContext( "2d" ); 
                   cxt.fillStyle = "#0f0"; 
                   cxt.fillRect( 0, 0, c.width, c.height ); 
               } 
               //canvas elementi dəstəklənmirsə 
               else { 
                   window.alert( "Sizin brauzer canvas elementini dəstəkləmir." ); 
               } 
           } 
       </script> 
    </head> 
    <body> 
        <canvas id="myCanvas" width="500" height="250"></canvas>
    </body> 
</html>

Burada biz, ilk olaraq veb brauzerə səhifənin HTML5 ilə hazırlandığını bildirmək üçün DOCTYPE instruksiyasından istifadə edirik. Qeyd edim ki, DOCTYPE HTML teq deyil, veb brauzer üçün instruksiyadır. HTML 4.01 versiyada üç növ DOCTYPE elan edə bilərdiksə, HTML 5-də yalnız 1 növ elan etmək mümkündür. Daha sonra səhifəyə <canvas> teqi əlavə edirik. Canvas-ın enini və uzunluğunu daxil edirik. Javascript vasitəsi ilə bu elementə müraciyət etmək üçün ona id attributu mənimsədirik (myCanvas). Skriptə baxdıqda isə görərik ki, Javascript canvas elementinə müraciət etmək üçün onun id-sindən istifadə edir.

<canvas id="myCanvas" width="500" height="250"></canvas>

<canvas> – müxtəlif render kontekstlərinə əsaslanan rəsm səthi (drawing surface) yaradır ki, bu kontekstlər də öz növbəsində həmin səth üzərində təsvir yaratmaq və manipulyasiya etmək üçün istifadə olunur. Biz məqalə boyu 2d render konteksti ətrafında danışacağıq. Digər kontekstlərə misal olaraq, OpenGL ES-ə əsaslanan 3d render kontekstini göstərmək olar.

Canvas elementi üzərində təsvir yaratmaq (çəkmək) üçün script ilk növbədə onun render kontekstinə müraciət etməlidir. Bunun üçün canvas elementinin getContext() adlanan DOM metodu var. Həmin metod parametr olaraq, kontekstin növünü qəbul edir və cavab olaraq özündə canvas üzərində çəkmək üçün metodları saxlayan HTML5 obyekti qaytarır. Brauzerin canvas elemetini dəstəkləyib, dəstəkləmədiyini də elə bu metoda müraciət edərək yoxlamaq olar. Aşağıdakı 2 sətir isə canvas elementinin uzunluğu və eni canvas elementinin uzunluğu və eninə bərabər olan qırmızı düzbucaqlı çəkir:

cxt.fillStyle = "#f00"; 
cxt.fillRect( 0, 0, c.width, c.height ); 

Bundan başqa yuxarıdakı koddan göründüyü kimi, biz canvas elementinə qara rəngli və 1px qalınlıqlı xətti sərhəd stili mənimsədirik.

Nəticə aşağıdakı kimi alınmalıdır.

Brazuer canvas elementini dəstəkləyirsə
Brazuer canvas elementini dəstəkləmirsə

Onu da qeyd edim ki, canvas elementi aşağıdakı brazuerlərdə dəstəklənir:

  • Internet Explorer 9
  • Firefox 3.0+
  • Safari 3.0+
  • Chrome 3.0+
  • Opera 10.0+

Koderlər və proqramçıların çox sevdikləri Internet Explorer 6-8 brauzerlərinə gəldikdə isə, burada canvas elementinin funksionallığından istifadəni mümkün edən ExplorerCanvas adlı 3rd-party kitabxana mövcuddur. Istifadə üçün səhifəyə yalnız bir Javascript faylı daxil etmək (include) kifayət edir. İE 6-8 versiyalarda bu kitabxananın köməyi ilə canvas elemetinin renderinqi çox zəif gedir və resurs istifadəsi cəhətdən sərfəli deyil. Ona görə o tərəfə çox da meyl etməsəniz məsləhətdir. Necə deyərlər:

« Internet Explorer — это такая программа, с помощью которой можно зайти на сайт www.mozilla.com и скачать себе браузер… »

Sonda, HTML5-də Canvas elementi sizə maraqlı gəldisə, istifadə istiqamətlərində ümumi təsəvvür yaransın deyə aşağıdakı nümunələri nəzərdən keçirə bilərsiniz:
1. agent 8 ball
2. HTML5 Canvas and Audio Experiment
3. Ball Pool
4. Canvas Cycle
5. Twitter user
6. Depth of field and more
7. Trail

Canvas elementi üzərində təsvir yaratmaq metodları haqqında isə məqalənin 2-ci hissəsində oxuya bilərsiniz.

 
 

HTML5 Canvas – Hissə 2

26 Nov

Məqalə oxucunun sadə HTML və Javascript biliklərinə malik olduğunu nəzərdə tutur.

Başlamazdan qabaq, tərkibində <canvas> elementi olan səhifə yaradaq.

<!DOCTYPE HTML>
<html>
    <head>
       <style type="text/css" rel="stylesheet">
           canvas { border: solid 1px #000; }
       </style>
       <script type="text/javascript" src="draw.js"></script>
    </head>
    <body>
        <canvas id="myCanvas" width="500" height="250">
        	Sizin brauzer canvas elementini dəstəkləmir
        </canvas>
    </body>
</html>

2D context API

Canvas elementinin 2D context API-da implementasiya olunmuş bəzi funksionallıqları nəzərdən keçirək:

Canvas state (canvasın vəziyyəti)

Hər bir context təsvir vəziyyətlərindən ibarət stekə malikdir. Bu stekdən istifadə etmək üçün aşağıdakı funksiyalardan istifadə edə bilərsiniz.
save() – contextin cari vəziyyətini stekə əlavə edir.
restore() – stekə ən son əlavə olunmuş vəziyyəti bərpa edir. Əgər stek boşdursa, heç nə etmir.

Rənglər

fillStyle – xassəsi fiqurların hansı rənglə rənglənməsini təyin etmək üçündür.
strokeStyle – xassəsindən xətlərin rəngini təyin etmək üçün istifadə olunur.

Xətt stilləri

lineWidth – təsvir çəkilən zaman xəttin qalınlığını təyin etmək üçün istifadə olunur.
lineCap – ilə xətt sonluğunun forması təyin edilir. butt, roundsquare qiymətlərindən birini alır.
lineJoin – ilə xəttin birləşmə stilini təyin etmək olar. bevel, roundmiter qiymətlərindən birini alır.

Sadə təsvirlər

Canvas üzərində düzbucaqlı dördbucaq (rectangle) çəkmək üçün 3 funksiya vardır. Bunlar aşağıdakı şəkildə təyin olunurlar:
1. clearRect(x, y, w, h) – funksiyası düzbucaqlının daxilinə düşən pixelləri tam şəffaf qara rəng ilə əvəz edir.
2. fillRect(x, y, w, h) – funksiyası fillStyle stilindən istifadə edərək düzbucaqlı sahə çəkir. Bu yolla dördbucaqlını rəngləmək olar.
3. strokeRect(x, y, w, h) – funcksiyası strokeStyle, lineWidth, lineJoinmiterLimit xassələrindən istifadə edərək düzbucaqlı fiquru çəkir. Dördbucaqlının çərçivəsini çəkir.

Hər 3 funksiya arqument olaraq 4 qiymət qəbul edir. Bunlardan ilk 2-si x və y – düzbucaqlının sol yuxarı koordinatlarını, digər 2-si h və w isə düzbucaqlının eni və uzunluğunu təyin edir.

Bir neçə nümuməni nəzərdən keçirək. Bunun üçün yuxarıdakı səhifəyə əlavə etdiyimiz draw.js faylından istifadə edə bilərik:

window.addEventListener('load', function () { 
    var c = document.getElementById( "myCanvas" ); 

    // əgər brauzer canvas elementini dəstəkləyirsə
    if ( c && c.getContext ) {
    	// hər bir canvas elementi üçün bir dəfə inisializasiya edə bilərsiniz
        var cxt = c.getContext( "2d" );
        
        cxt.fillStyle = "#f00";
        cxt.strokeStyle = "#00f";
        cxt.lineWidth = 3;
        
        cxt.fillRect( 20, 20, c.width/2, c.height/2 );
        cxt.strokeRect( 20,  20, c.width/2, c.height/2);
        cxt.clearRect( 75, 50, 30, 30 );
    }
    // canvas elementi dəstəklənmirsə
    else {
        window.alert( "Sizin brauzer canvas elementini dəstəkləmir." );
    }
}, false);

Nəticə aşağıdakı kimi olmalıdır:
canvas: nünumə 1

Xətt stillərini yoxlamaq üçün aşağıdakı nümunəyə baxaq:

var lineCaps = [ 'butt','round','square' ];

cxt.strokeStyle = '#0A0';
		
// xətlərin çəkilməsi
for ( var i=0; i < lineCaps.length; i++ ){
    cxt.lineWidth = 10;
    cxt.lineCap = lineCaps[i];

    cxt.beginPath();
    cxt.moveTo( 25, 30 + i*20 );
    cxt.lineTo( 175, 30 + i*20 );
    cxt.stroke();
}

Nəticə aşağıdakı kimidir:
canvas: nümunə 2

Mürəkkəb təsvirlər

Yollar (path)

Context obyekti həmişə bir cari yola malikdir. Yol sıfır və daha artıq altyollara malik olur. Canvas altyolları sizə müxtəlif mürəkkəblikdə fiqurlar çəkməyə imkan verir. Aşağıdakı metodları nəzərdən keçirək:

beginPath() – cari yolu sıfırlayır.

moveTo(x, y) – verilmiş nöqtə ilə altyol yaradır

closePath() – sonuncu altyolu bağlı olaraq işarələyir. Başlanğıcı – son altyolun başlanğıc nöqtəsi olan yeni altyol yaradır və onu yola əlavə edir.

lineTo(x, y) – altyolda ən son nöqtədən (x,y) nöqtəsinə düz xətt çəkir və daha sonra (x,y) nöqtəsini altyola əlavə edir. Başlanğıc nöqtəni göstərən altyol mövcud olmalıdır.

quadraticCurveTo(cpx, cpy, x, y) – altyolda ən son nöqtəni (x,y) nöqtəsinə cpx və cpy idarə nöqtələri ilə kvadratik Bezye əyrisi vasitəsilə birləşdirir. Daha sonra (x,y) nöqtəsini altyola əlavə edir. Bezye əyriləri haqda buradan oxuya bilərsiniz.

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) – altyolda ən son nöqtəni (x,y) nöqtəsinə cp1x, cp1y, cp2x, cp2y idarə nöqtələri ilə kubik Bezye əyrisi vasitəsilə birləşdirir. Daha sonra (x,y) nöqtəsini altyola əlavə edir. Bezye əyriləri haqda buradan oxuya bilərsiniz.

arc(x, y, radius, startAngle, endAngle [, anticlockwise ] ) – qövs çəkmək üçün istifadə olunur. Parametrlər aşağıdakı kimi təyin olunur:
x,y – qövsün mərkəzinin koordinatı
radius – qövsün radiusu
startAngle, endAngle – başlanğıc və son bucaq, radian ilə
anticlockwise – çəkmə istiqaməti

rect(x, y, w, h) – metodu ilk növbədə yola (x, y), (x+w, y), (x+w, y+h), (x, y+h) nöqtələrindən ibarət yeni altyol əlavə edir. Daha sonra bu nöqtələri düz xəttlə birləşdirir və alt yolu bağlı olaraq işarələyir. Daha sonra isə (x,y) nöqtəsindən ibarət yeni altyol yaradaraq əsas yola əlavə edir.

fill() – metodu cari yolun daxilindəki bütün altyolları fillStyle-a əsasən rəngləyir və həmin altyolları bağlı olaraq elan edir.

stroke() – metodu cari yolun daxilindəki bütün altyolları çəkilmə qaydalarını lineWidth, lineCap, lineJoin və miterLimit xassələrinə əsasən hesablayır və strokeStyle xassəsinə uyğun olaraq çəkir.

isPointInPath(x, y) – metodu verilmiş (x,y) nöqtəsinin cari yolun daxilinə düşüb-düşmədiyini təyin etmək üçündür.

Yuxarıdakı metodlardan bir neçəsini nümunə yoxlayaq:

window.addEventListener('load', function () { 
    var c = document.getElementById( "myCanvas" ); 

    // əgər brauzer canvas elementini dəstəkləyirsə
    if ( c && c.getContext ) {
    	// hər bir canvas elementi üçün bir dəfə inisializasiya edə bilərsiniz
        var cxt = c.getContext( "2d" );
        cxt.fillStyle = ' #00f';
        cxt.strokeStyle = '#f00';
        cxt.lineWidth = 2; 

        // düz xətt
        cxt.beginPath();
        cxt.moveTo(10, 10);
        cxt.lineTo(100, 100);
        cxt.moveTo(150, 100);

        // Bezye əyrisi 
        cxt.bezierCurveTo(180, 30, 250, 180, 300, 100); 
        cxt.stroke(); 
        cxt.closePath(); // Draw a circle using the arc  function.

        // çevrə
        cxt.beginPath(); 
        cxt.arc(125, 115, 30, 0, 360, false); 
        cxt.stroke(); 
        cxt.closePath();
    }
    // canvas elementi dəstəklənmirsə
    else {
        window.alert( "Sizin brauzer canvas elementini dəstəkləmir." );
    }
}, false);

Nəticə aşağıdakı kimi olacaq:
canvas: nümunə 3

Kölgələr

Canvas elementinə kölgə vermək üçün canvas contextinin shadowColor və shadowBlur xassələrindən istifadə edə bilərsiniz. Aşağıdakı nümunəni nəzərdən keçirək:


var canvas=document.getElementById("myCanvas");
var cxt =canvas.getContext("2d");
 
cxt.rect(20,20,200,100);
cxt.fillStyle="#8ED61F";
cxt.shadowColor="black";
cxt.shadowBlur = 10;
cxt.fill();

</script>

Nəticə:
canvas-shadow

Text

Aşağıdakı metod və xassələri nəzərdən keçirək:
font – bu xassə vasitəsilə contextin cari şriftini yoxlaya və ya dəyişə bilərsiniz. Sintaksis CSS font atributunun xassəsi kimidir.
textAlign – xassəsi vasitəsilə mətnin horizontal yerləşməsini yoxlamaq və dəyişmək olar. Qəbul olunan qiymətlər start, end, left, right və center qiymətləridir. Susmaya görə start qiyməti götürülür.
textBaseline – xassəsi vasitəsilə mətnin vertikal yerləşməsini yoxlamaq və dəyişmək olar. Aşağıda göstərilən qiymətlərdən birini alır: top, hanging, middle, alphabetic, ideographic və bottom.
measureText(text) – metodu vasitəsilə mətnin uzunluğunu yoxlaya bilərsiniz. Metod cavab olaraq TextMetrics tipli obyekti qaytarır.
fillText(text, x, y [, maxWidth ] ) – mətni rəngli şəkildə çəkilməsi üçündür. fillStyle xassəsinin qiymətinə əsasən mətni çəkir.
strokeText(text, x, y [, maxWidth ] ) – mətni xətti şəkildə çəkilməsi üçün istifadə olunur. strokeStyle xassəsinin qiymətinə əsasən mətni çəkir.

var metrics = context.measureText(text);
var width = metrics.width;

Yuxarıda qeyd etdiyimiz funksionallıqları aşağıdakı nümunədə yoxlayaq:

// hər bir canvas elementi üçün bir dəfə inisializasiya edə bilərsiniz
var cxt = c.getContext( "2d" ); 

var x = c.width / 2;
var y = c.height / 2 - 10;
	    
var text = "HTML5 Canvas";

// şrift
cxt.font = "italic 30pt Calibri";
// horizontal yerləşmə
cxt.textAlign = "center";
// vertikal yerləşmə
cxt.textBaseline = "middle";
// rəng
cxt.fillStyle = "blue";
// mətni çək
cxt.fillText( text, x, y );

// mətnin uzunluğunu götür
var metrics = cxt.measureText( text );
var width = metrics.width;
cxt.strokeStyle = "#003300";
cxt.font = 'italic 30px Calibri';
cxt.strokeText("uzunluq: " + width + "px", x, y + 40);

Nəticə aşağıdakı kimi olacaq:
canvas text

Şəkillər

Canvas üzərinə şəkil əlavə etmək üçün drawImage metodu istifadə oluna bilər. Bu metod 3 müxtəlif arqument siyahısı üzrə çağırıla bilər:
drawImage(image, dx, dy) – Burada dx və dy koordinatları şəklin canvas üzərində yerləşəcək sol yuxarı koordinatlarıdır.
drawImage(image, dx, dy, dw, dh) – Şəklin ölçüsünü təyin etmək üçün istifadə olunur. dw və dh arqumentləri uyğun olaraq şəklin uzunluğunu və enini göstərir.
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) – şəklin müəyyən hissəsini kəsmək (crop) üçün istifadə olunur. Yuxarıdakı parametlər şəkildən kəsmək istədiyimiz düzbucaqlı sahənin yerini (yuxarı sol koordinatlarını) və ölçülərini təyin edir.
Göstərilən hər 3 metod image arqumenti olaraq HTMLImageElement, HTMLCanvasElement, və ya HTMLVideoElement obyektlərindən birini qəbul edə bilər.
Aşağıdakı nümunəni nəzərdən keçirək:

window.addEventListener('load', function () { 
    var c = document.getElementById( "myCanvas" ); 

    // əgər brauzer canvas elementini dəstəkləyirsə
    if ( c && c.getContext ) {
    	// hər bir canvas elementi üçün bir dəfə inisializasiya edə bilərsiniz
        var cxt = c.getContext( "2d" ); 

	    var image = new Image();
	    image.src = "chrome.png";

		// şəklin yerləşməsi və ölçüsü
		var destX = 10;
        var destY = 10;
		var imageWidth = 100;
		var imageHeight = 100;
        
        var cropX = 20;
        var cropY = 20;
        var cropWidth = 50;
        var cropHeight = 50;
        
	        
	    image.addEventListener('load', function(){
	    	
	    	// şəklin canvas üzərində çəkilməsi : drawImage(image, dx, dy)
	    	cxt.drawImage( image, destX, destY );
	    	
	    	// şəklin ölçüsünün təyin olunması : drawImage(image, dx, dy, dw, dh)
	    	cxt.drawImage( image, destX + 110, destY, imageWidth * 2, imageHeight * 2 );
	    	
	        // şəklin kəsilməsi : drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
			cxt.drawImage( image, cropX, cropY, cropWidth, cropHeight, destX + 320 , destY, cropWidth, cropHeight );
			
	    });
	    
    }
    // canvas elementi dəstəklənmirsə
    else {
        window.alert( "Sizin brauzer canvas elementini dəstəkləmir." );
    }
}, false);

Nəticə aşağıdakı kimidir:
canvas-image

Canvas üzərində mousun koordinatının tapılması

Canvas üzərində mousun koordinatını aşağıdakı script vasitəsi ilə asanlıqla tapmaq olar:

NeatsUtils = {}

/**
 * Mouse-un cari mövqeyinin tapılması
 *
 * @param event : event obyekti
 * @returns cursor obyekti
 */
NeatsUtils.getPosition = function(event) {
	
    event = event || window.event;
    var cursor = { x:0, y:0 };
    
    if ( event.pageX == null && event.clientX != null ) {
	  var doc = document.documentElement, body = document.body;
	  event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
	  event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc   && doc.clientTop  || body && body.clientTop  || 0);
	}
	
	cursor.x = event.pageX - event.target.offsetLeft;
	cursor.y = event.pageY - event.target.offsetTop;
    
    return cursor;
}

window.addEventListener('load', function () { 
    var c = document.getElementById( "myCanvas" ); 

    // əgər brauzer canvas elementini dəstəkləyirsə
    if ( c && c.getContext ) {
    	// hər bir canvas elementi üçün bir dəfə inisializasiya edə bilərsiniz
        var cxt = c.getContext( "2d" ); 
        
		var x = c.width / 2;
		var y = c.height / 2 - 10;
		
		// şriftin xassələrini təyin et
		cxt.font = "italic 30pt Calibri";
		cxt.textAlign = "center";
		cxt.textBaseline = "middle";
		cxt.fillStyle = "blue";
		
		// koordinatları çap et
		cxt.fillText( "move mouse over me", x, y );
		
		c.addEventListener( 'mousemove', function(e) {
			// mousun mövqeyini təyin et
	    	var mouse = NeatsUtils.getPosition(e);
			var text = mouse.x + " " + mouse.y;
			
			// canvası təmizlə
			cxt.clearRect(0, 0, c.width, c.height );
			
			// koordinatları çap et
			cxt.fillText( text, x, y );
			
			cxt.closePath(); 
			
		});
	    
    }
    // canvas elementi dəstəklənmirsə
    else {
        window.alert( "Sizin brauzer canvas elementini dəstəkləmir." );
    }
}, false);

Nəticəni aşağıdakı kimidir

Canvas elementi haqda daha ətraflı məlumat almaq üçün Canvas elementinin spesifikasiyasından istifadə edə bilərsiniz.

Əlavə resurslar:

1. WHATWG Canvas Documentation

Nümunələr:

1. Sketchpad

 
 

Const istifadəsi

03 Jun

C++ proqramlaşdırma dilində const istifadə edərkən 2 müxtəlif yanaşma olur.

  1. const – pisdir. Onun xeyirdən çox ziyanı var. Hansısa əcaib səhvlər meydana gəlməyə başlayır. Yaxşısı budur ki, ondan heç istifadə etməyəsən.
  2. const – yaxşıdır. O, dəyişilməli olmayan obyektləri dəyişməyə qoymur və beləliklə də proqramı səhvlərdən qorumuş olur. Harada mümkündürsə, ondan istafadə etmək lazımdır.

Məncə ikinci variant daha yaxşıdır. const necə istifadə etməli olduğumuza aşağıdakı misallar vasitəsi ilə baxaq.

Const dəyişənlər

Ən sadə variant dəyişənlərdir. Dəyişən elan olunan kimi inisializasiya olunur və daha onun qiymətini dəyişmək olmur:

const int i = 12;
int const j = 1;
i = 5;   // səhvdir
j = 10;  // səhvdir

Const pointer-lər

Pointerlərlə iş bir az başqa cürdür. Bu zaman const istifadə etməyin 2 yolu var: siz ya pointerin qiymətini, ya da pointerin istinad etdiyi qiyməti dəyişə bilərsiniz. Sintaksis aşağıdakı kimidir:

// pointerin öz qiymətini dəyişilməkdən qorumaq
int i = 1;
int *const p1 = &i;
// pointerin istinad etdiyi yaddaşın qiymətini dəyişilməkdən qorumaq
int const* p2;
const int* p3;

Burada qayda belədir: Fikrinizdə * üzrə vertikal xətt keçirin. Sağda nə yerləşirsə dəyişənə, solda nə yerləşirsə pointerin istinad etdiyi tipə aid olur. Aşağıdakı misala baxaq:

int i = 1;
int j = 0;
int *const p = &i;    // dəyişən elan olunan kimi inisializasiya olunmalıdır
*p = 5;               // pointerin istinad etdiyi yaddaşın qiymətini dəyişmək OLAR
p = &j;               // pointerin öz qiymətini dəyişmək OLMAZ !!!

Göründüyü kimi, sağda p yerləşir, p-nin istinad etdiyi tip isə int-dir. Beləliklə int tipinə istinad edən konstant pointer alınır.
Indi isə digər yolu nəzərdən keçirək:

int i = 1;
const int *p;
p = &i;            // pointerin öz qiymətini dəyişmək OLAR
*p = 5;            // pointerin istinad etdiyi yaddaşın qiymətini dəyişmək OLMAZ !

Deyilənlər sinif və strukturlara da aid edilir

class foo {
   public:
      int x;
};

const foo* f = new foo;
f->x = 1;       // OLMAZ! Sinfin üzvlərinə qiymət mənimsətməyə icazə verilmir

Const funksiyalar

Əgər sizin const obyektiniz varsa və siz bu obyekti dəyişə biləcək metod çağırmaq istəmirsinizsə, onda konstant metodlardan istifadə edə bilərsiniz. const metodlar yeganə metodlardır ki, const obyektlərdə çağırıla bilər. Belə metodları elan etmək üçün sintaksis aşağıdakı kimidir:

<return-value> <class>::<member-function>(<args>) const
{
        // ...
}

Misal üçün:

int Person::someConstMethod() const
{
        return someProp1 * someProp2;
}

Qeyd etmək lazımdır ki, funksiyanın const olaraq elan olunması, onun const-olmayan funksiyalar tərəfindən istifadə olunmasını qadağan etmir. Qayda aşağıdakı kimidir:

  • Const funksiyalar həmişə çağırıla bilər
  • Const-olmayan funksiyalar yalnız const-olmayan obyektlər tərəfindən çağırıla bilər


Parametrlərin funksiyaya ötürülməsi

Əgər siz funksiyaya parametr ötürürsünüz və əmin olmaq istəyirsiniz ki, bu parametr dəyişilməyəcək, bu zaman da const istifadə edə bilərsiniz. Məsələn:

void func1( const int& i );
void func2( const int* i );
void func3( int i );

Birinci və ikinci üsulda funksiya daxilində parametrin dəyişilməsinə olunan cəhd kompilyasiya zamanı səhv verəcək. Üçüncü üsulda isə proseslər dəyişənin lokal kopyası ilə gedəcək. Yəni ötürülən dəyişən özü dəyişikliyə uğramayacaq.

 
No Comments

Posted in C++

 

Static və instance üzvlər

23 May

Ümumiyyətlə, Javascript proqramlaşdırma dilində obyektlər həm instance, həm də static üzvlərə (member) malik ola bilərlər. Onu qeyd edim ki, instance üzv dedikdə hər hansı bir obyektə bağlı olan üzvlər nəzərdə tutulur. Static üzv isə obyektin yarandığı siniflə (class) bağlı olur. Static üzv bir sinifdən əmələ gələn obyektlər üçün ümumi olan funksionallığı təyin etmək üçün istifadə olunur. Aşağıdakı nümunələri nəzərdən keçirək:

Beləliklə, tutaq ki siz aşağıdakı şəkildə bir sinif elan edirsiniz:

function calc() {

}

Instance üzvləri iki yoldan biri vasitəsilə elan edə bilərsiniz: ya sinfin konstruktoru daxilində ya da prototip vasitəsi ilə.
Yuxarıda elan etdiyimiz sinfə instance metod əlavə edək. İlk olaraq metodu konstruktor daxilində elan edək:

function calc() {
    this.add = function( a, b ) {
        return a + b;
    }
}

Indi isə metodu prototip vasitəsi ilə elan edək:

function calc() {

}

calc.prototype.add = function( a, b ) {
    return a + b;
}

Bu metoddan aşağıdakı şəkildə istifadə etmək olar:

var calculator = new calc();
window.alert( calculator.add( 1, 2 ) );

Bəzən isə elə üzvlər istifadə etməli oluruq ki, onlar hansısa sinifdən yaranan bütün obyektlər arasında paylanmalı olur, yəni heç bir konkret obyektdən asılı olmur. Belə üzvlər ancaq sinfə aid olur və statik üzvlər adlanlrlar. Statik üzvləri aşağıdakı yolla elan edirlər.

function calc()
{
}
 
calc.add = function( a, b )
{
	return ( a + b );
}

Static üzvlər okyektdən asılı olmadığı üçün heç bir obyekt inisializasiya etməyə ehtiyac qalmır. Birbaşa sinifdən istifadə etmək kifayət edir. Bunu aşağıdakı şəkildə edə bilərsiniz:

window.alert( calc.add( 2, 3 ) );

Onu da qeyd edim ki, static metodlar qeyri-static üzvlərdən istifadə edə bilməzlər. Bunun da izahı kifayət qədər aydındır. İnstance üzvlər obyektə bağlı olduğu halda, static üzvlər obyektə bağlı deyillər. Obyekt mövcud olmadıqda isə heç bir instance üzvün istifadəsindən söz gedə bilməz.

Resurslar

 
1 Comment

Posted in Javascript

 

Private, privileged və public üzvlər

23 May

Bu məqalədə Javascript proqramlaşdırma dilində private, privileged və public üzvərin necə elan olunması və istifadəsi haqqında danışacam. Çox uzatmadan keçək əsas məsələyə.
Javascript proqramlaşdırma dilində sinif elan edərkən private, privileged və public üzvlər istifadə edə bilərik. Bunu necə etməli olduğumuzu öyrənmək üçün həmin üzvlərin necə elan olunması qaydalarını bir sinif üzərində yoxlayaq.
Aşağıdakı kimi bir sinif elan edək:

function Person() {

}

Private xassə (property) və metodlar

İndi isə mövcud sinfə private üzvlər əlavə edək. Bildiyimiz kimi sinif daxilində elan edilən dəyişənlər yalnız həmin sinif daxilində mövcud olurlar. Bunun üçün də private üzvləri dəyişən olaraq aşağıdakı şəkildə elan edirlər:

function Person() {

    // private xassə
    var privateProp = "Mən private xassəyəm";

    // private metod
    var privateMethod= function() {
        // privateMetod üçün kod burada yerləşməli...
    }

}

Privileged metodlar

Privileged metodlar private üzvlərə müraciət edə bilir və eyni zamanda özünü public metod kimi aparır. Aşağıdakı şəkildə privileged metod elan edək:

function Person() {

    // private xassə
    var privateProp = "Mən private xassəyəm";

    // privileged metod
    this.getPrivateProp = function() {
        return privateProp;
    }

}

Public xassə ve metodlar

İndi isə yuxarıda qeyd etdiyim sinfə public üzvlər əlavə edək. Privileged metodlarda olduğu kimi public üzv elan edərkən this açar sözündən (keyword) istifadə etməlisiniz. Ya da bunu prototipin köməyi ilə də edə bilərsiniz. Hər 2 üsulu nəzərdən keçirək:

function Person( name ) {

    // public xassə
   this.name = name;

   // public metod
   this.getName= function () {
       return this.name;
   };

}

// public metod
Person.prototype.getName2 = function() {
    return this.name;
}

Public metodları prototype vasitəsi ilə elan etməyiniz daha məqsədə uyğundur.

Hamısı bir yerdə…

Gəlin yuxarıda qeyd etdiklərimizin hamısını bir sinif daxilində elan edək:

function Person(name) {

    // private xassə
    var privateProp = "Mən private xassəyəm";

    // private metod
    var privateMethod = function() {
        return "Mən private metodam";
    }

    // privileged metod
    this.getPrivateProp = function () {        
        var privateMethodResult = privateMethod();
        return privateProp;
    };

    // public xassə
    this.name = name;

}

// public metod
Person.prototype.getName = function () {
    return this.name;
};

İndi isə yuxarıda yazdığımız sinfin praktikada necə işləməyini yoxlamaq üçün, onun obyektini düzəldək, xassə və metodların görünmə aralığını yoxlayaq. Bunu aşağıdakı kimi edə bilərik:


// obyekt yaradaq
var person = new Person("Developer");

// private xassənin yoxlanılması
person.privateProp; // undefined

// private metodun yoxlanılması
person.privateMethod(); // undefined
 
// privileged metodun yoxlanılması
person.getPrivateProp(); // "Mən private xassəyəm"

// public xassənin yoxlanılması
person.name; // "Developer"

// public metodun yoxlanılması
person.getName(); // "Developer"

Yekun

Ümid edirəm ki, bu məqalə Javascript proqramlaşdırma dili ilə yeni başlayanlara müəyyən qədər kömək olacaq.

Diqqətiniz üçün təşəkkür edirəm.

 
 

Javascript – Dövrlər

01 May

Əvvəlcədən qeyd edim ki, bu məqalə Javascript proqramlaşdırma dili ilə yeni başlayanlar üçündür.

Dövrlər – hər hansı bir kod blokunu gostərilən say dəfə və ya müəyyən şərtin doğru olduğu müddətdə yerinə yetirmək üçündür.
Çox vaxt proqram yazarkən lazım olur ki, hər hansı bir kod bloku müəyyən şərtlər daxilində və ya müəəyən say qədər təkrar olunsun. Həmin kod blokunun dəfələrlə təkrarən yazmamaq üçün dövrlərdən istifadə edirlər.

Javascript proqramlaşdırma dilində 2 cür dövr işlətmək mümkündür:

  1. for – kod blokunu göstərilən say dəfə yerinə yetirmək üçün
  2. while – kod blokunu göstərilən şərtin doğru olduğu müddətdə yerinə yetirmək üçün

For dövrü

Əgər kod blokunun neçə dəfə yerinə yetirilməli olduğunu əvvəlcədən bilirsinizsə, onda for dövründən istifadə etməyiniz daha məqsədə uyğundur. Sintaksis aşağıdakı kimidir:

for ( variable = startvalue; variable <= endvalue; variable = variable + increment ) {
    // Yerinə yetirilməli olan kod bloku
}

Aşağıdakı nümunəni nəzərdən keçirək:

for (var i=1; i <= 5; i++ ) {
    document.write("i = " + i);
    document.write("<br />");
}

Nəticə:

i = 1
i = 2
i = 3
i = 4
i = 5

Burada, sayğac olaraq i dəyişəni elan edirik və ona başlanğıc qiymət kimi 0 mənimsədirik (var i = 0). Sonra dövrün neçə dəfə təkrar olunmasını təyin etmək üçün ( i <= 5 ) şərti qoyuruq. Yəni nə qədər ki bu şərt doğrudur, dövr daxilindəki kod bloku təkrarən yerinə yetiriləcək. Daha sonra sayğacın dəyişmə qaydasını (i++) olaraq müəyyən edirik. Bu isə o deməkdir ki, hər bir dövr başa çatdıqdan sonra i dəyişəninin qiyməti 1 vahid artacaq. Beləliklə, yuxarıda müəyyən etdiyimiz şərt və qaydalara əsasən kod bloku 5 dəfə yerinə yetirilmiş olacaq.

For dövrünü bir az mürəkkəb nümunədə də izah etmək olar. Aşağıdakı kodu nəzərdən keçirək:

for (var i=1, j = 10; i <= 5, j > 0; i++, j -= i ) {
    document.write("i = " + i + "; j = " + j);
    document.write("<br />");
}

Nəticə:

i = 1; j = 10
i = 2; j = 8
i = 3; j = 5
i = 4; j = 1

For … in dövrü

For … in dövrü obyektin xassələri üzrə dövr etmək üçün istifadə olunur. Sintaksis aşağıdakı kimidir:

for ( property in object ) {
    // yerinə yetirilməli olan kod bloku
}

Qeyd edim ki, dövrün daxilində yazdığımız kod bloku obyektin hər bir xassəsi üçün bir dəfə yerinə yetirilir. Aşağıdakı nümunəni nəzərdən keçirək:

var developer = { 
                           ad: "Niyaz", 
                           soyad: "Abbasov", 
                           bilik: "C/C++, PHP, Javascript" 
                         };

for ( property in developer )
{
    document.write( property + ": " + developer[property] + "<br/>");
}

Nəticə:

ad: Niyaz
soyad: Abbasov
bilik: C/C++, PHP, Javascript

While dövrü

While dövrü kod blokunu göstərilən şərt doğru olduğu müddət ərzində təkrar edir. Sintaksis aşağıdakı kimidir:

while ( şərt ) {
    // yerinə yetirilməli olan kod bloku
}

Aşağıdakı nümunəni nəzərdən keçirək:

var i = 0, j = 10;
while ( i != j ) {
    document.write("i = " + i + "; j = "+ j + "<br/>");
    i++;
    j--;
}

Nəticə:

i = 0; j = 10
i = 1; j = 9
i = 2; j = 8
i = 3; j = 7
i = 4; j = 6

Göründüyü kimi, ilk olaraq i və j dəyişənləri elan olunur və onlara başlanğıc qiymətlər mənimsədilir. Daha sonra while dövrü qurulur və şərt olaraq i və j dəyişənlərinin bir birindən fərqlənməsi şərti götürülür. Bu o deməkdir ki, nə qədər ki i və j dəyişənlərinin qiymətləri bir-birindən fərqlənir, dövr daxilində yazılmış kod bloku təkrarən yerinə yetiriləcək. Dövrün daxilində isə i dəyişəninin qiymətini 1 vahid artırır, j dəyişəninin qiymətini isə 1 vahid azaldırıq. Beş dövrdən sonra i və j dəyişənlərinin qiymətləri 5-ə bərabər olacaq və dövr dayandırılacaq.

do … while dövrü

do … while dövrünün sintaksisi aşağıdakı kimidir:

do  {
    // yerinə yetirilməli olan kod bloku
}
while ( şərt );

Bu dövrün while dövründən yeganə fərqi ondadır ki, dövr daxilində yazılmış kod bloku MÜTLƏQ ən azı bir dəfə yerinə yetirilir. Aşağıdakı nümunəni nəzərdən keçirək:

var i = 10;
do {
    document.write( "i = " + i);
    i++;
} while ( i < 0 );

Nəticə:

i = 10

Göründüyü kimi, dövr üçün müəyyən olunan ( i < 0 ) şərti heç vaxt doğru olmasa belə dövr ən azı bir dəfə yerinə yetirilir.

Break və continue

Bəzən müəyyən bir addımda dövrün yerinə yetirilməsini dayandırmaq lazım olur. Bunu etmək üçün break komandasından istifadə edirlər. Sonsuz bir dövr quraq və break komandası vasitəsilə müəyyən bir addımda dövrün yerinə yetirilməsini dayandıraq.

for ( var i = 0; true; i++) {
    if ( i == 5 ) {
        break;
    }
    document.write("i = " + i + "<br />");
}
document.write("Dövr sona yetdi...");

Nəticə:

i = 0
i = 1
i = 2
i = 3
i = 4
Dövr sona yetdi...

Göründüyü kimi, dövrün sonsuz olaraq yerinə yetirilmək üçün nəzərdə tutulmasına baxmayaq, break komandası i dəyişəni 5-ə bərabər olduğu zaman dövrü dayandırmağa və proqramın qalan hissəsinin işini davam etdirməyə imkan verir.

Continue komandası isə dövrün cari addımını saxlamağa və növbəti addım ilə davam etməyə imkan verir. Aşağıdakı kodu nəzərdən keçirək:

for ( var i = 0; i < 10; i++) {
    if ( (i % 2) == 0 ) {
        continue;
    }
    document.write("i = " + i + "<br />");
}

Nəticə:

i = 1
i = 3
i = 5
i = 7
i = 9

Burada 10 addımdan ibarət bir dövr qururuq. Və yalnız tək ədədləri çıxışa vermək üçün (i % 2) == 0 şərti ödənilən addımlarda continue komandasının köməyi ilə həmin addımın yerinə yetirilməsini dayandırırıq və növbəti addımla davam etmiş oluruq.

 
 

Javascript Date obyekti

28 Apr

Javascript proqramlaşdırma dilində tarix və vaxt-la işləmək üçün Date obyektindən istifadə olunur.

Date obyekti Date() konstruktoru vasitəsilə yaradılır. Bunu aşağıdakı 4 üsuldan biri ilə etmək olar:

var date = new Date();
var date = new Date(date);
var date = new Date(milliseconds);
var date = new Date(year, month, day, hours, minutes, seconds, milliseconds);

Date obyekti yaradıldıqdan sonra bir neçə metod sizə həmin obyekt üzərində müxtəlif əməliyyatlar aparmağa imkan yaradır. Obyektin xassə və metodlarını nəzərdən keçirək.

Date obyektinin xassələri

constructor – Date obyektinin prototipini yaradan funksiyanı qaytarır

var d=new Date();
document.write(d.constructor);

Nəticə:

function Date() { [native code] }

prototype – obyektə yeni xassə və metodlar əlavə etməyə imkan verir

function person( firstName, lastName )
{
    this.firstName = firstName;
    this.lastName = lastName;
}

var turgut = new person( "Turgut", "Mehdiyev" );
person.prototype.age = null;
turgut.age = 24;

document.write( "Turgut's age is: <br/>" + turgut.age );

Nəticə:

Turgut's age is:
24 

Date obyektinin metodları

getDate() – ayın gününü qaytarır [1-31]

getDay() – həftənin gününü qaytarır [0-6]

getFullYear() – ili qaytarır [dörd rəqəmli]

getHours() – saatı qaytarır [0-23]

getMilliseconds() – millisaniyəni qaytarır [0-999]

getMinutes() – dəqiqəni qaytarır [0-59]

getMonth() – ayı qaytarır [0-11]

getSeconds() – saniyəni qaytarır [0-59]

getTime() – 1970-ci il Yanvarın 1-dən etibarən saniyəni qaytarır

getTimezoneOffset() – GTM və local vaxt arasında fərqi dəqiqələrlə qaytarır

getUTCDate() – UT-yə nəzərən ayın gününü qaytarır [1-31]

getUTCDay() – UT-yə nəzərən həftənin gününü qaytarır [0-6]

getUTCFullYear() – UT-yə nəzərən ili qaytarır [dörd rəqəmli]

getUTCHours() – UT-yə nəzərən saatı qaytarır [0-23]

getUTCMilliseconds() – UT-yə nəzərən millisaniyəni qaytarır [0-999]

getUTCMinutes() – UT-yə nəzərən dəqiqəni qaytarır [0-59]

getUTCMonth() – UT-yə nəzərən ayı qaytarır [0-11]

getUTCSeconds() – UT-yə nəzərən saniyəni qaytarır [0-59]

parse() – date sətrini parse edir və 1970-ci il Yanvarın 1-dən etibarən millisaniyələri qaytarır

setDate() – ayın gününü təyin edir [1-31]

setFullYear() – ili təyin edir [dörd rəqəmli]

setHours()) – saatı təyin edir [0-23]

setMilliseconds() – millisaniyəni təyin edir [0-999]

setMinutes() – dəqiqəni təyin edir [0-59]

setMonth() – ayı təyin edir [0-11]

setSeconds() – saniyəni təyin edir [0-59]

setUTCDate() – UT-yə nəzərən ayın gününü təyin edir [1-31]

setUTCFullYear() – UT-yə nəzərən ili təyin edir [dörd rəqəmli]

setUTCHours() -UT-yə nəzərən saatı təyin edir [0-23]

setUTCMilliseconds() – UT-yə nəzərən millisaniyəni təyin edir [0-999]

setUTCMinutes() – UT-yə nəzərən dəqiqəni təyin edir [0-59]

setUTCMonth() – UT-yə nəzərən ayı müəyyən edir [0-11]

setUTCSeconds() – UT-yə nəzərən saniyəni müəyyən edir [0-59]

toDateString() – date obyektinin tarix hissəsini string obyektinə çevirərək qaytarır

toLocaleDateString() – date obyektinin tarix hissəsini lokal seçimlərə əsasən string obyektinə çevirir

toLocaleTimeString() – date obyektinin vaxt hissəsini lokal seçimlərə əsasən string obyektinə çevirir.

toLocaleString() – date obyektini lokal seçimlərə əsasən string obyektinə çevirir

toString() – date obyektini string obyektinə çevirir

toTimeString() – date obyektinin vaxt hissəsini string obyektinə çevirir

toUTCString() – UT-yə nəzərən date obyektini string obyektinə çevirir

valueOf() – date obyektinin qiymətini qaytarır


var date = new Date();
document.write("toString() : " + date.toString() + "<br/>");
document.write("getDate() : " + date.getDate() + "<br/>");
document.write("getDay() : " + date.getDay() + "<br/>");
document.write("getFullYear() : " + date.getFullYear() + "<br/>");
document.write("getHours() : " + date.getHours() + "<br/>");
document.write("getMilliseconds() : " + date.getMilliseconds() + "<br/>");
document.write("getMinutes() : " + date.getMinutes() + "<br/>");
document.write("getMonth() : " + date.getMonth() + "<br/>");
document.write("getSeconds() : " + date.getSeconds() + "<br/>");
document.write("getTime() : " + date.getTime() + "<br/>");
document.write("getTimezoneOffset() : " + date.getTimezoneOffset() + "<br/>");
document.write("getUTCDate() : " + date.getUTCDate() + "<br/>");
document.write("getUTCDay() : " + date.getUTCDay() + "<br/>");
document.write("getUTCFullYear() : " + date.getUTCFullYear() + "<br/>");
document.write("getUTCHours() : " + date.getUTCHours() + "<br/>");
document.write("getUTCMilliseconds() : " + date.getUTCMilliseconds() + "<br/>");
document.write("getUTCMinutes() : " + date.getUTCMinutes() + "<br/>");
document.write("getUTCMonth() : " + date.getUTCMonth() + "<br/>");
document.write("getUTCSeconds() : " + date.getUTCSeconds() + "<br/>");
toString() : Fri Apr 29 2011 00:06:52 GMT+0500 (Azerbaijan Daylight Time)
getDate() : 29
getDay() : 5
getFullYear() : 2011
getHours() : 0
getMilliseconds() : 692
getMinutes() : 6
getMonth() : 3
getSeconds() : 52
getTime() : 1304017612692
getTimezoneOffset() : -300
getUTCDate() : 28
getUTCDay() : 4
getUTCFullYear() : 2011
getUTCHours() : 19
getUTCMilliseconds() : 692
getUTCMinutes() : 6
getUTCMonth() : 3
getUTCSeconds() : 52
 
 

Sayt kimin üçündür?

02 Apr

Fərz edək ki, hər hansı bir şirkət özünə sayt açmaq qərarına gəlir. Və bir müddətdən sonra şirkətin internet saytı hazır olur. Bir çox hallarda sayt – açılış nitqi, şirkətin missiyası, kollektivin professionallığı, müdriyyətin müdrikliyi və direktorun “Mən və mənim biznesim” stilində çəkilmiş şəkli ilə bəzədilmiş müraciətindən ibarət olur. Nəticə olaraq sayt – şirkətin özü üçün hazırlanır demək olar. Bu problem əksər saytlarda bu və ya digər şəkildə özünü göstərməkdədir. Bəzi hallarda şirkətin konkret olaraq nə ilə məşğul olduğu və hansı məhsullar satdığı barədə yazmaq da unudulur.

Bunu heç də axmaqlığın bir növü kimi qiymətləndirməyə dəyməz. Bu əksər insanlara xas olan xüsusiyyətdir. Fərz edək ki, siz dostunuzun ad gününə hədiyyə almalısınız. Bu zaman siz öz istək və zövqünüzü deyil, dostunuzun təcrübəsini istifadə edərək qərar verməlisiniz. Çoxları isə bu qərarı öz zövqlərinə uyğun verir. Kobud misal da olsa, eyni qərar bu və ya digər şəkildə şirkətin internet saytı yazadılan zaman mütləq nəzərə alınmalıdır.

Ən dəhşətlisi budur ki, şirkətinizin saytı heç də sizin xoşunuza gəlmək məcburiyyətində deyil ! Amma o, mütləq istifadəçilərin xoşuna gəlməlidir…

Qeyri-adi şirkəti üçün adi sayt yaratmaq istəyən direktoru təsəvvür edin. İlk növbədə o, tanış proqramçı tapır. 1-2 cümlə vasitəsilə nələrin olmasını istədiyi barədə məlumat verir. Daha pis halda, hər hansı oxşar saytı göstərərək, ona oxşar bir saytın hazırlanmasını istəyə bilər. Beləliklə, bir neçə vaxtdan sonra proqramçılar texniki tapşırığı hazırlayırlar və vicdanla bütün müddəaları yerinə yetirərək saytı işə salırlar…

Sayta 1 ay ərzində 10-larla robot və bir neçə təsadüfi istifadəçi daxil olur. Daha sonra, iclasların birində direktora SEO (Search Engine Optimization) haqqında məlumat verirlər və o, bunun üçün növbəti 3 ay ərzində aylıq 1000 AZN ayırmalı olur. Saytın axtarış sistemlərində yuxarı pillələrə qalxması nəticəsində ziyarətçilərin sayı artıq. Şirkətə hər ay 10-20 nəfər zəng edir, sayta baxdıqları və məhsullar haqqında sualları olduğu barədə məlumat verir. Nəticədə real olaraq 1-3 müştəri məhsul almış olur. (P.S. Göstərilən rəqəmlər süni olsada, bir çox hallarda reallığa uyğundur.)

Saytın bu cür işini araşdırdıqda bir neçə versiya ortaya atılır:

  • SEO-ya bir az da maddi vəsait ayrılmaq
  • saytın sosial reklamının artırılmaq
  • marketinqi inkişaf elətdirmək
  • daha məhsuldar olacağı ümidilə yeni saytın yaradılması

Və ya araşdırmaları metafizika sahəsində davam etdirsələr…

  • saytın hostinqi qədim hind qəbirsanlığında yerləşir
  • sayta ftp vasitəsi ilə göz dəyib
  • hostinq yerləşən server otağa cadu ediblər
  • və s…

Problem nədədir?

Problemin nədə olduğunu araşdıraq. Şirkət pis şirkətdir və ya məhsulları pisdir? Nəticə alınır ki, yox. Proqramçılar pisdir və sayt keyfiyyətsiz hazırlanıb? Nəticə alınır ki, saytın texniki işində heç bir problem yoxdur. Bəs problem nədir?

Məqalənin əvvəlində qeyd etdiyimiz kimi, direktor proqramçını çağıraraq saytda nələri görmək istədiyini deyir və proqramçı deyilənləri olduğu kimi qeyd edir. Stop !!! Bu da elə problemlərin başlandığı andır. Direktor, saytda nələrin olmağı haqqında danışır. Bəs o bunu hardan bilsin?

Saytdan onun biznesi üçün nəyin tələb olunduğunu bilməyinə heç şübhə etmirəm. Amma bunun necə həyata keçirilməsi qərarını vermək üçün onun heç bir qabiliyyəti yoxdur. Qabiliyyəti haradan olsun ki? Onun veb-texnologiyalar ilə təcrübəsi yoxdur. O, veb-saytların layihələndirilməsi haqqında heç nə bilmir, amma eyni zamanda praktiki olaraq bununla məşğul olur. Buna görə nəticənin gözlənilən olmaması heç şübhə doğurmur.

Problemin həlli yolu…

Bir dəqiqə… Bu ki, proqramçının səlahiyyəti sahəsinə daxildir. Ona məhz buna görə pul ödəyirlər! Şübhəsiz ki, bu belə olmalıdır. Təəssüf ki, belə olmur çox vaxt. Sifarişçi ilə mübahisə etmək və ona bu yanaşmanın doğru olmadığını izah etmək, bir çox hallarda “veb studiyaların” və ya sadəcə “proqramçıların” maraqları xaricində olur. Düşünürəm ki, sifarişçinin proyektin layihələndirilməsi mərhələsində iştirakı işin xeyrinə deyil.

Belə layihələndirilmənin adı User Experience Design (UX Design) və ya Azərbaycan dilində desək “İstifadəçi ilə qarşılıqlı əlaqənin layihələndirilməsi”. Adından da göründüyü kimi, layihələndirmə – istifadəçi üzərində fokuslanıb və istifadəyə rahatlıq(usability), dizayn, matketing, psixologiya, sosialogiya və s. kimi müxtəlif metodların birləşməsinə əsaslanır. Bir tərəfdən sistemin məqsəd və tapşırıqları, digər tərəfdən isə istifadəçilərin məqsəd və tələbləri müəyyən olunur. Və tapşırıq qoyulur ki, sistemi elə layihələndirmək lazımdır ki, bunlar bir-birinə uyğun olaraq nəzərə alınsın.

Ux Design haqqında daha ətraflı növbəti məqalədə yazacam…

Resurslar

  1. What Is User Experience Design
  2. How To Quantify The User Experience
  3. Wiki: User Experience
  4. Nine Essential Characteristics of Good UX Designers
  5. The Science of UX Design
 
5 Comments

Posted in Web

 

Asynchronous JavaScript and XML – AJAX

25 Mar

Bu məqalə yeni başlayanlar üçün Ajax texnologiyası haqqında qısa məlumat vermək üçündür.

AJAX texnologiyası sizə sürətli və dinamik veb saytların yaradılması üçün imkan yaradır. Bu texnologiyadan istifadə edərək siz bütün səhifəni yeniləmədən serverə sorğu göndərə və serverdən aldığınız cavaba əsasən veb səhifənin bir hissəsinin yeniləyə bilərsiniz.

Texnologiya olaraq AJAX – aşağıda göstərilən 2 əsas prinsipə əsaslanır:

  1. bütün səhifəni yeniləmədən, serverə dinamik sorğu göndərmək texnologiyaları ( XMLHttpRequest, Remote Scripting )
  2. səhifənin strukturunun və ya məzmununun dinamik dəyişilməsi üçün DHTML-in isitfadəsi


AJAX termini ilk dəfə 2005-ci il, fevralın 18-də Cessi Ceyms Qaret-in (Jesse James Garrett) “Veb-proqramlara yeni yanaşma” adlı məqaləsində istifadə olunmuşdur.

Üstünlükləri

  • Trafikə qənaət – AJAX texnologiyası ilə səhifənin bir hissəsini yeniləmək, bütün səhifəni yeniləməyə nəzərən daha az trafik işlətmiş olur
  • Serverin yüklənməsini azaltmaq
  • İnterfeysin reaksiyasını sürətləndimək – səhifənin bir hissəsi yeniləndiyi üçün istifadəçi nəticəni daha tez görür

Serverdən məlumatı çox vaxt brauzerə XML və ya JSON formatda ötürürlər

XMLHttpRequest obyekti

Bütün müasir brauzerlər XMLHttpRequest obyektini dəstəkləyir. (IE5 və IE6 ActiveXObject istifadə edir)

XMLHttpRequest obyektini yaratmaq üçün sintaksis aşağıdakı kimidir:

var xmlhttp = new XMLHttpRequest();

Internet Explorerin köhnə versiyaları ActiveXObject istifadə edir. Bunun üçün sintaksis aşağıdakı kimi olacaq:

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

Beləliklə, bütün brauzerlərin dəstəkləməyini təmin etmək üçün aşağıdakı koddan istiafadə edə bilərsiniz:

var xmlhttp;
// IE7+, Firefox, Chrome, Opera, Safari üçün
if (window.XMLHttpRequest) {
  xmlhttp=new XMLHttpRequest();
}
// IE6, IE5 üçün
else{
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

Serverə necə sorğu göndərməli?

Serverə sorğu göndərmək üçün XMLHttpRequest metodunun open(method, url, async) və send() metodlarında istifadə etməliyik.

xmlhttp.open( "POST", "users.php", true );
xmlhttp.send();

open( method, url, async ) metodunun parametrlərini nəzərdən keçirək:

  • method – Sorğunun tipini təyin edir, POST və ya GET. Http sorğu tiplərini müqayisə etdikdə, onu demək olar ki, GET POST-a nəzərən daha sadə və sürətlidir. Amma POST metodunu aşağıdakı hallarda istifadə etməyiniz məsləhətə uyğundur.
    • Böyük həcmdə məlumat göndərən zaman. POST metodu göndərilən məlumatın həcmi üçün limit qoymur
    • istifadəçi haqda konfidensial məlumat göndərdiyiniz zaman. POST metodu GET metoduna nəzərən daha təhlükəsizdir.
  • url – sorğunun serverdə hansı fayla göndərilməli olduğunu təyin edir
  • async – true və ya false qiymətlərini alır.
    • async = true. Asinxron üsulla serverə sorğu göndərilən zaman Javascript, sorğunun bitməyini gözləmək məcburiyyətində qalmır. Bu zaman sorğunun bitdiyi zaman çağrılacaq funksiyanı elan etmək lazımdır. Məsələn:
      xmlhttp.onreadystatechange = function() {
        if ( xmlhttp.readyState== 4  && xmlhttp.status==200 ) {
          // Serverin cavabını burada işləməli ...
        }
      }
      xmlhttp.open( "POST", "users.php", true );
      xmlhttp.send();
      
    • async = false. Sinxron üsulla serverə sorğu göndərilən zaman Javascript, serverdən cavabın gəlməyini gözləyir və cavab gəlməyənə kimi heç bir iş görülmür. Bu zaman serverdən gələn cavabı işləmək üçün kodu sorğunu göndərmək üçün çağırdığımız send() metodundan sonra birbaşa yaza bilərik. Daha onreadystatechange hadisəsini elan etməyə ehtiyac qalmır.

Ajax üçün nümunə:

Ajax-in işini praktikada görmək üçün çox sadə bir misala baxaq: Bu nümunə üçün biz 3 fayldan istifadə edəcəyik: index.html, ajax.jsusers.php

Ilk öncə index.php faylının strukturuna baxaq:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>
            Ajax-in istifadəsi
        </title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <style type="text/css">
            #container {
                font-family: Tahoma; font-size: 10pt;
                border:solid 1px brown;
                color: black;
                background-color: burlywood;
                width: 300px;
                padding: 10px;
            }
        </style>
        <script type="text/javascript" src="ajax.js"></script>
    </head>
    <body>
        <input type="button" onclick="AjaxManager.getData()" value="Serverdən məlumat al" />
        <br /><br />
        <div id="container">
            Burada serverdən alınan məlumat yerləşəcək
        </div>
    </body>
</html>

Indi isə ajax.js faylı daxilində AjaxManager sinfi yaradaq və getData() metodunu implementasiya edək:

AjaxManager = function() {

    // XMLHttpRequest obyektini yaradırıq
    function createRequest() {
        var request;

        // IE7+, Firefox, Chrome, Opera, Safari üçün
        if (window.XMLHttpRequest) {
          request=new XMLHttpRequest();
        }
        // IE6, IE5 üçün
        else {
          request=new ActiveXObject("Microsoft.XMLHTTP");
        }
        return request;
    }

    return {

        // serverə müraciət etmək üçün metod
        getData: function() {

            // XMLHttpRequest obyekti düzəldirik
            var request = createRequest();

            // sorğu bitən zaman çağrılacaq funksiyanı elan edirik
            request.onreadystatechange=function() {
              // əgər sorğu uğurla başa çatıbsa
              if ( request.readyState== 4 && request.status == 200 ) {
                // səhifədə div elementinin mətnini dəyişirik
                document.getElementById("container").innerHTML = request.responseText;
              }
            }
            // sorğunun parametrlərini elan edirik
            request.open( "POST", "users.php", true );
            // sorğunu göndəririk ...
            request.send();
        }
    }
}();

Burada göründüyü kimi AjaxManager sinfi daxilində getdata() public metodu yaradırıq. XMLHttpRequest obyektini isə private createRequest funksiyası daxilində yaradırıq. Serverdən sorğunun cavabı gələn zaman hansı funksiyanın işə düşəcəyini elan edirik. Həmin funksiya daxilində isə səhifənin <div id=”container”> elementinin məzmunu sorğunun cavabı ilə əvəz edirik:

document.getElementById("container").innerHTML = request.responseText;

Daha sonra sorğunun parametrlərini təyin edəndən sonra, sorğunu göndəririk.

Nəhayət, “users.php” faylının məzmunu aşağıdakı kimi olacaq:

<?php

$response = "Cari istifadəçilər<br/>\n";
$response .= "admin, turgut, adil";

echo $response;

?>

Proqramın nəticəsi aşağıdakı kimi olacaq:
Sadə AJAX nümunəsi

Sadə AJAX nümunəsi

Sadə AJAX nümunəsi

Resurslar

Demo

Proqramın demo versiyasına buradan baxa bilərsiniz

Yükləmə

İstifadı olunan proqramın kodunu buradan yükləyə bilərsiniz

 
 

Ext.Ajax-in istifadəsi

23 Mar

Bu məqalə Ext.Ajax sinfi vasitəsi ilə serverə sadə sorğunun göndərilməsi haqda. Funksionallığın demonstrasiyası üçün istifadəçi adının sistemdə mövcud olub-olmamasını yoxlamaq üçün sadə bir proqram yazaq. Beləliklə proqram aşağıdakı fayllardan ibarət olacaq:

index.html
ajax.js
users.php

Ilk olaraq index.html faylının strukturunu nəzərdən keçirək:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd" />
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <link rel="stylesheet" type="text/css" href="../extjs/resources/css/ext-all.css" />

    <script type="text/javascript" src="../extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../extjs/ext-all.js"></script>

    <script type="text/javascript" src="ajax.js"></script>
    <script  type="text/javascript">
        Ext.onReady(function(){

            Ext.QuickTips.init();

            var ajax = new ns.ajax.main();
            ajax.showFormPanel();

        });
    </script>
    <title>Ext.Ajax vasitəsi ilə istifadəçi adının yoxlanılması</title>
</head>
<body>

</body>
</html>

Burada göründüyü kimi, səhifənin DOM-i hazır olan kimi Ext.QuickTips.init() metodunu çağıraraq, tooltip-ləri inisializasiya edirik. Daha sonra isə aşağıda yaradacağımız ns.ajax namespace-ində elan etdiyimiz main sinfinin obyektini düzəldərək, həmin obyektin shoüFormPanel metodunu çağırırıq.

İndi isə ajax.js faylının mətninə baxaq:

/*
 * @description     Ext.Ajax sinfindən istifadə edərək serverə 
 *                  sorğu göndərmək üçün sadə proqram
 * @author          Turgut Mehdiyev
 * @date            23/03/2011
 *
 **/


Ext.ns('ns.ajax');

ns.ajax.main = function() {

    /*
     * @namespace       ns.ajax
     * @class           main
     * @name            ajaxForm
     * @description     Serverə Ajax sorğu göndərmək üçün komponent
     * @extends         Ext.form.FormPanel
     * @scope           private
     */
    var ajaxForm =  Ext.extend(Ext.form.FormPanel, {
        initComponent: function() {
            var config = {
                frame             : true,
                border            : false,
                items             : [   
                    new Ext.form.TextField({
                        id              : 'txtUsername',
                        fieldLabel      : 'İstifadəçi adı',
                        allowBlank      : false,
                        blankText       : 'İstifadəçi adını daxil edin',
                        msgTarget       : 'side',
                        anchor          : '-20'
                    })
                ],
                buttons: [
                    new Ext.Button({
                        text        : 'Yoxla',
                        listeners   : {
                            click: function() {
                                if (this.ownerCt.ownerCt.getForm().isValid() ) {
                                    sendRequest();
                                }
                            }
                        }
                    })
                ]
            };
            Ext.apply(this, Ext.apply(this.initialConfig, config));
            ajaxForm.superclass.initComponent.apply(this, arguments);
        }
    });
    // ajaxForm sinfini xtype olaraq qeydiyyatdan keçiririk
    Ext.reg('ajaxForm', ajaxForm);

    /*
     * @namespace       ns.ajax
     * @class           main
     * @name            sendRequest
     * @description     İstifadəçi adının yoxlanılması üçün serverə sorğu göndərir
     * @scope           private
     **/
    var sendRequest = function() {
        var username =  Ext.getCmp('txtUsername').getValue();
        if ( username != "" ) {
            Ext.Ajax.request({
               url             : 'users.php',
               
               // Əgər url-də təyin olunmuş fayl serverdə tapılmayıbsa
               failure         : function( response, options ) {
               },
               
               // Əgər fayl serverdə tapılıbsa
               success         : function(response, options) {
                    var result = Ext.decode( response.responseText );

                    // Əgər serverdeən gələn cavab uğurludursa, yəni { success: true }
                    if ( true == result.success ) {
                        Ext.Msg.show({
                            title          :'Bildiriş',
                            msg            : result.message,
                            modal          : true,
                            icon           : Ext.Msg.INFO,
                            buttons        : Ext.Msg.OK
                        });
                    }

                    // Əgər serverdeən gələn cavab uğursuzdursa, yəni { success: false }
                    else {
                        Ext.Msg.show({
                            title          :'Bildiriş',
                            msg            : result.message,
                            modal          : true,
                            icon           : Ext.Msg.ERROR,
                            buttons        : Ext.Msg.OK
                        });
                    }
                },

                // serverə əlavə parametrlərin göndərilməsi
                params      : { name: username }
            });
        }
    }          


    /*
     * @namespace         ns.ajax
     * @class             main
     * @name              showFormPanel
     * @description       Formanın pəncərədə göstərilməsi
     * @scope             public
     */
    this.showFormPanel = function() {

        var ajaxWin = new Ext.Window({
            title         : 'Istifadəçi adının yoxlanılması',
            modal         : true,
            width         : 320,
            draggable     : false,
            resizable     : false,
            closable      : false,
            minimizable   : false,
            items         : [{
                    xtype: 'ajaxForm'
            }]
        });

       ajaxWin.show();
    }

}

Deməli, bu faylda ilk olaraq ns.ajax namespace-ini qeydiyyatdan keçiririk. Daha sonra həmin namespace daxilində main sinfi elan edirik. Bundan sonra Ext.form.FormPanel sinfinin genişləndirilmiş sinfini düzətdib ajaxForm private dəyişəninə mənimsədirik. Göründüyü kimi forma bir Ext.form.TextField və Ext.Button komponentlərindən ibarətdir. Yoxla düyməsi basıldığı zaman sendRequest() metodu çağırılır. Məhz bu metodun tərkibində serverə sorğu göndərilməsi həyata keçirilir. Bu, Ext.Ajax.request() metodunun köməyilə baş verir.

Konfiqurasiya obyektləri

url sorğu göndəriləcək faylın ünvanı
params serverə hansı parametrlərin ötürüləcəyini müəyən edən JSON obyektdir
method sorğu üçün istifadə olunacaq HTTP metod
success sorğu uğurla başa çatıbsa, bu konfiqurasiyada təyin olunmuş funksiya çağırılır.
failure sorğu uğursuz başa çatıbsa, bu konfiqurasiyada təyin olunmuş funksiya çağırılır.
timeout sorğunun maximal müddətini təyin etmək üçün bu konfiqurasiyadan istifadə olunur. Susma prinsipinə görə sorğunun müddəti 30 saniyədir.

Ext.Ajax sinfi və Ext.Ajax.request() metodu barədə əlavə məlumat əldə etsəniz daha məqsədə uyğun olar.

Indi isə users.php faylının mətninə baxaq:

<?php
$users = array( "turgut", "admin" );

$username = $_POST['name'];

$isAvailable = true;

foreach( $users as $user ) {
    if ( $user == $username ) {
        $isAvailable = false;
    }
}

$msg = ( $isAvailable ) ? "İstifadəçi adı sistemdə mövcüd deyil"
                                     : "İstifadəçi adı artıq sistemdə mövcuddur";

$result = array( "success" => $isAvailable, "message" => $msg );

header("Content-Type: application/json");
echo json_encode($result);
?>

Burada ilk olaraq istifadəçilərin adında ibarət $users massivi elan edirik. Sonra səhifəyə HTTP POST metodu ilə göndərilən name dəyişəninin qiymətini götürürük və həmin qiyməti massivlə müqayisə edib, uyğun elementin olub-olmadığını yoxlayırıq. Nəticəni klientə JSON obyekt kimi qaytarırıq.

Nəticə aşağıdakı şəkildə olmalıdır:
Ajax sorğu göndərmək üçün form
Ajax sorğu göndərmək üçün form
Ajax sorğu göndərmək üçün form
Ajax sorğu göndərmək üçün form

Demo

Proqramın demo versiyasına buradan baxa bilərsiniz

Yükləmə

Proqramın kodunu buradan yükləyə bilərsiniz

 
1 Comment

Posted in Ext JS