顯示具有 jQuery 標籤的文章。 顯示所有文章
顯示具有 jQuery 標籤的文章。 顯示所有文章

2014年10月15日 星期三

JQuery 的 on() 原理


在JavaScript中,大多數事件會在DOM裡往上一層一層的泡浮,也就是說,當一個元素觸發一個事件時,她會在DOM一直往上泡浮到 document 層級

舉例,現在有個基本的html:
<div>
   <span>1</span>
   <span>2</span>
</div>
現在,我們採用事件委託:
$('div').on('click', 'span', fn);
該事件處理程序僅僅連接到 div 元素,由於 span 是在 div 裡面,對 span click 會往上泡浮到 div,並觸發 div 的 click 事件處理器,同時,剩下要做的就是檢查 event.target 是否符合我們指定的目標(範例中為 span)

看看更複雜點的範例:
<div id="parent">
    <span>1</span>
    <span>2 <b>another nested element inside span</b></span>
    <p>paragraph won't fire delegated handler</p>
</div>
下面是一些基礎邏輯:

// 對祖先附加處理程序
document.getElementById('parent').addEventListener('click', function(e) {
    // 過濾 event target
    if (e.target.tagName.toLowerCase() === 'span') {
        console.log('span inside parent clicked');
    }
});
上面的程式中,當 event.target 是被嵌套在過濾器裡面時就無法匹配(例如第二個span裡面有b,click她時,會被上面的程式過濾掉),所以我們需要一些迭代邏輯
document.getElementById('parent').addEventListener('click', function(e) {
    var failsFilter = true,
        el = e.target;
    while (el !== this && (failsFilter = el.tagName.toLowerCase() !== 'span') && (el = el.parentNode));
    if (!failsFilter) {
        console.log('span inside parent clicked');
    }
});












2014年9月29日 星期一

JQuery的套件Uploadify, 無法使用的替代方法

FireFox必須額外安裝flash player才能使用Uploadify套件, 在要使用該套件的情況下, 遇到不能使用該套件的時後, 自行改寫ajax上傳功能 :


// 上傳頭圖 (上傳圖片到資料夾, 不進行存檔到資料庫, 上傳的圖片名稱會經由程式改成和電影名稱一樣
$('#file_upload').uploadify({
    // .... 省略 uploadify 部分的設定 ....
    onSWFReady: function () {
        // 可以使用 uploadify
    },
    onFallback: function () {
        // 無法使用 uploadify
        // console.log('Flash was not detected or flash version is not supported.');
 
        // 新增一個可上傳檔案的 form
        $('#file_upload').after('<form enctype="multipart/form-data" method="post" name="filefox" id="filefox" style="display: initial;">' +
            // 可加入一些必要的數值到 type="hidden" 欄位
            '<input type="file" name="pic" id="pic">' + // 選圖檔案
            '</form>').remove();
        // 選擇圖片後就自動上傳
        $('#pic').change(function () {
            var fd = new FormData($('#filefox')[0]); // your form element, 使用FormData對象發送文件
            // fd.append("CustomField", "This is some extra data"); // 額外添加對象
            $.ajax({
                type: 'POST',
                url: '/upload/test/',
                data: fd,
                // 如果在 Chrome 上顯示下面這個錯誤 
                // Uncaught TypeError: Illegal invocation (未捕獲類型錯誤:非法調用)
                // 指jQuery的AJAX報錯:檢查jQuery的文檔後發現,如果它不是一個字符串,jQuery嘗試將數據轉換成一個字符串。
                processData: false, // 在這裡告訴jQuery不要碰我的數據
                contentType: false, // 防止jQuery來為你添加一個Content-Type頭
                success: function (data) {
                    changeBanner(true);
                }
            });
        });
    }
});

2013年7月1日 星期一

ASP.NET MVC使用AJAX方式撈取資料

1.可能要撈取的條件不只是一筆資料, 例如使用兩部電影ID去撈取各自的資料, 因此在jQuery組成JSON字串

        // 撈出頁面資料放到陣列
        var $video = $('.video');
        var videoIdArr = [];
        $video.each(function (index, element) {
            videoIdArr.push($(element).attr('data-videoid'));
        });
        videoIdArr = $.unique(videoIdArr);
        var url = '@Url.Action("GetVideos", "Video")';
        // 使用JSON.stringifyJavaScript值轉換成以JSON表示的字串
        var data = { videoIds: JSON.stringify(videoIdArr) };
 
        // dataservicereturnJSON 格式之內容
        $.post(url, data, function (data) {
            $(data).each(function (index, element) {
                $('.video_' + element.VideoID).text(element.Name);
            });
        });

        // MVCController Action :
        [HttpPost]
        public ActionResult GetVideos(string videoIds)
        {
            var db = new HappyMovieEntities();
            var Serializer = new JavaScriptSerializer();
 
            // 將指定的 JSON 字串轉換成 T 型別的物件。
            // (此範例是將videoIds轉換成List<string>)
            var _videoIds = Serializer.Deserialize<List<string>>(videoIds);
            var query = db.Video.Where(x => _videoIds.Contains(x.VideoID)).Select(x => new
            {
                x.VideoID,
                x.Picture,
                x.Name,
                ReleaseYear = x.ReleaseDate.Value.Year,
            });
            return Json(query);
        }

* 備註 :
因為Action裡面有解序列化的程式, 所以接收的資料一定要是Json格式的字串
如果要client端發送的只有一筆可以這樣寫 :
        var vid = '@Model.VideoId';
        var data = { videoIds: JSON.stringify([vid]) };
如果不傳入資料 :
        var data = { videoIds: undefined };
但是server端要加入判斷是否接收到的是null
-----------------------------------------------------------------------------------
1. 使用 autocomplete (jQuery UI)
        // 輸入文字搜尋人名
        $('#search_user').autocomplete({
            source: "@Url.Action("UserName""Search")",
            minLength: 2,
            select: function (event, ui) {
                $('#ReceiverId').val(ui.item.id); // 將真正的值放到指定元素
            }
        });

        // MVCController Action :
        // autocompelete送出的請求url : UserName?term=
        // 所以接收的參數必須命名為 term
        public ActionResult UserName(string term)
        {
            var _db = new HappyMovieEntities();
            var query = _db.UserProfile.Where(x => x.NickName.Contains(term))
            .OrderBy(x => x.NickName)
            .Select(x => new
            {
                id = x.UserId, // 真正的值
                label = x.NickName, // 顯示於搜尋結果
                value = x.NickName, // 被選取後帶回欄位的值
            });
            return Json(query, JsonRequestBehavior.AllowGet);
        }