【問題解決】前端學習踩坑記錄

 

最近在學做前端,小白一枚,做個踩坑記錄


20191021 更新:

此網站似乎使用 scroll-linked 定位效果。這可能無法與異步平移一起使用;

	<script>
		$(function(){
			 $(window).on("scroll",function(){
				var offset = $("html.body").scrollTop(); // 獲取網頁滾動偏移位
				if (offset>=100) {$("img").show(1000);}
				else {$("img").hide(1000);}
			});		
		});

	</script>

一個簡單的通過監聽頁面滾動顯示或隱藏圖片的js,在Firefox中運行報錯:

且無法實現圖片展示與隱藏的效果。

 

解決方案:

	<script>
		$(function(){
			 $(window).on("scroll",function(){
				var offset = $(document).scrollTop(); // 獲取網頁滾動偏移位
				if (offset>=100) {$("img").show(1000);}
				else {$("img").hide(1000);}
			});		
		});

	</script>

雖然仍然會顯示warning,但是可以實現滾動監聽綁定的動畫效果。可能的原因是Firefox定位滾輪移動距離的方式與其他瀏覽器不同。


20191029更新:

Forbidden (CSRF token missing or incorrect.): /xxx/xxx/

基於django後端框架下的ajax數據傳輸,如果需要保留django自帶的CSRF驗證,則需要在js腳本中加入

        $.ajaxSetup({
            data:{
                csrfmiddlewaretoken:'{{ csrf_token }}'
            }
        })

如果這個方法不行還可以試試這樣寫,前提頁面中已經存在{% csrf_token %}:

               var csrfToken = $("[name='csrfmiddlewaretoken']").val();// 獲取csrf_token
                $.ajax({
                    type: "POST",
                    url: "{% url 'space:change_profile' %}",
                    data: formData,
                    headers: {"X-CSRFToken": $.cookie('csrftoken')},
                    async: false,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function(response){
                        alert(reponse.toString());
                    },
                    error: function(e){
                        alert('Network Failure');
                    }

即手動添加headers中的CSRF_Token信息。

當然所有的html中涉及POST請求的部分都要加入

{% csrf_token %}

例如一個簡單的註冊頁面的表單部分:

            <form class="m-t" role="form" id="form" method="post" action="{% url 'main:register' %}" enctype="multipart/form-data">
                {% csrf_token %}
                <div class="form-group">
                    <label>學號</label>
                    <input type="text" name="uid" maxlength="20" placeholder="請輸入您的學號" required id="id_uid" class="form-control">
                </div>
                <div class="form-group">
                    <label>用戶名</label>
                    <input type="text" name="username" maxlength="20" placeholder="請設置您的用戶名" required id="id_username" class="form-control">
                </div>
                <div class="form-group">
                    <label>密碼</label>
                    <input type="password" name="password" maxlength="16" placeholder="請輸入密碼" required id="id_password" class="form-control">
                </div>
                <div class="form-group">
                    <label>再次輸入密碼</label>
                    <input type="password" name="password_rep" maxlength="20" placeholder="請再次輸入密碼" required id="id_password_rep" class="form-control">
                </div>
                <div class="form-group">
                    <label>名字</label>
                    <input type="text" name="first_name" maxlength="30" placeholder="請留下您的名字" id="id_first_name" class="form-control">
                </div>
                <div class="form-group">
                    <label>姓氏</label>
                    <input type="text" name="last_name" maxlength="30" placeholder="請留下您的姓氏" id="id_last_name" class="form-control">
                </div>
                <div class="form-group">
                    <label>頭像</label>
                    <input type="file" name="profile" placeholder="點擊選擇您的頭像" id="id_profile" class="form-control" onchange="verificationPicFile(this)">
                </div>
                <div>
                    <label>電子郵件地址</label>
                    <div class="row">
                        <div class="form-group col-md-8">
                            <input type="email" name="email" maxlength="40" placeholder="請設置您的驗證郵箱" id="id_email" class="form-control">
                        </div>
                        <div class="form-group col-md-2 offset-1">
                            <button type="button" class="ladda-button btn btn-primary" id="send-email-button" data-style="zoom-in">Send</button>
                        </div>
                    </div>
                </div>
                <div>
                    <label>驗證碼</label>
                    <input type="text" name="code" maxlength="4" placeholder="請輸入驗證碼" id="id_code" class="form-control">
                </div>
                <div class="form-group">
                    <div class="checkbox i-checks"><label> <input type="checkbox"><i></i> Agree the terms and policy </label></div>
                </div>
                <button type="submit" class="btn btn-primary block full-width m-b">Register</button>

20191029更新:

Django接收ajax傳輸的圖片數據

JS部分:

                var csrfToken = $("[name='csrfmiddlewaretoken']").val();// 獲取csrf_token
                $.ajax({
                    type: "POST",
                    url: "{% url 'space:change_profile' %}",
                    data: formData,
                    headers: {"X-CSRFToken": $.cookie('csrftoken')},
                    async: false,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function(response){
                        alert(reponse.toString());
                    },
                    error: function(e){
                        alert('Network Failure');
                    }
                });

視圖函數:

def change_profile(request):                                                                                             # 獲取頭像
    if request.method == "POST":
        profile = request.POST.get("profile")                                                                           # 獲取用戶設置的驗證郵箱
        print("PROFILE的內容爲",profile)
        return ajax_response("0", "Successfully reponsed", {"profile_token": 1})
    else:
        raise InvalidOperation("無效的請求")

發現後端始終無法獲取到ajax傳輸到的圖片,其實之前獲取不到出的是另外一個問題就是:

urlpatterns = [
	url(r"^(?P<username>\w+)/$",views.center,name="center"),															# 用戶中心頁面
	url(r"^change_profile/",views.change_profile,name="change_profile"),												# 修改頭像
]

當我URL如此配置時如果我修改用ajax將圖片傳至change_profile()視圖函數,則會匹配到第一個name爲center的URL中,原因是沒有精準匹配。

修改了change_profile的URL爲

urlpatterns = [
	url(r"^(?P<username>\w+)/$",views.center,name="center"),															# 用戶中心頁面
	url(r"^user/change_profile/",views.change_profile,name="change_profile"),												# 修改頭像
]

後發現視圖函數中獲取到的圖片始終爲None,原因是圖片沒有保存在request.POST對象中,而是request.FILES中:

def change_profile(request):                                                                                             # 獲取頭像
    if request.method == "POST":
        profile = request.FILES.get("profile")                                                                           # 獲取用戶設置的驗證郵箱
        print("PROFILE的內容爲",profile)
        return ajax_response("0", "Successfully reponsed", {"profile_token": 1})
    else:
        raise InvalidOperation("無效的請求")

20191030更新

JS刷新圖片元素

用戶重新上傳圖片更新頭像後,頁面上的圖片仍然沒有發生變化。刷新頁面後用戶頭像發生變化。我們當然不希望頁面全部重新加載,而只希望相應的img標籤重新加載。

我試着找了一些方法後發現沒有特別靠譜的局部刷新圖片的方法,一種可行的方法是在img標籤的src屬性值後添加一段隨機值(如日期),則可以實現用戶上傳圖片文件,後端修改服務器圖片文件,前端頁面立即更新到新的圖片。

                var csrfToken = $("[name='csrfmiddlewaretoken']").val();// 獲取csrf_token
                $.ajax({
                    type: "POST",
                    url: "{% url 'space:change_profile' username %}",
                    data: formData,
                    headers: {"X-CSRFToken": $.cookie('csrftoken')}, // 這裏的值可以用csrfToken替代!否則需要預先導入jquery.cookie.js
                    async: false,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function(response){// 成功修改則即刻更新圖片
                        console.log("勞資來更新頭像了。。。");
                        var profileSrc = $("img#showImg").attr("src");
                        var date = new Date()
                        $("img#showImg").attr("src",profileSrc+"?"+date.getTime());
                    },
                    error: function(e){
                        alert('Network Failure');
                    }
                });

20191101更新

$.ajax()中無法爲全局變量賦值問題

        $("button.m-b").click(function(){
            var csrfToken = $("[name='csrfmiddlewaretoken']").val();
            var username = $("input[name='username']").val();
            var password = $("input[name='password']").val();
            var flag = false // 控制事件冒泡
            $.ajax({
                type: "POST",
                url: {% url 'main:validate_login_formdata' %},
                data: {'username': username, 'password': password},
                headers: {"X-CSRFToken": csrfToken},
                success: function(response){// 成功修改則即刻更新圖片
                    response = JSON.parse(response);
                    if(response.code=='0') {
                        alert(response.msg);
                    }
                    else {
                        console.log("我也曾來過這裏")
                        flag = true;}
                },
                error: function(e){
                    alert('Network Failure');
                }
            });
            console.log(flag)
            return flag;

一段控制提交按鈕點擊的ajax,希望在用戶名密碼不匹配時不發生事件冒泡(即return flag=false),而匹配時希望在success中修改flag從而使得返回值爲true發生事件冒泡(頁面跳轉)。但是實際操作過程中flag始終都是false,頁面始終不會跳轉。

原因是同步加載,當$.ajax()中未設置async屬性參數時,默認會先運行到return flag,然後纔是$.ajax()中的內容,如果需要同步運行,需要設置async:false即可:

        $("button.m-b").click(function(){
            var csrfToken = $("[name='csrfmiddlewaretoken']").val();
            var username = $("input[name='username']").val();
            var password = $("input[name='password']").val();
            var flag = false // 控制事件冒泡
            $.ajax({
                type: "POST",
                url: {% url 'main:validate_login_formdata' %},
                data: {'username': username, 'password': password},
                headers: {"X-CSRFToken": csrfToken},
                async: false,
                success: function(response){// 成功修改則即刻更新圖片
                    response = JSON.parse(response);
                    if(response.code=='0') {
                        alert(response.msg);
                    }
                    else {
                        console.log("我也曾來過這裏")
                        flag = true;}
                },
                error: function(e){
                    alert('Network Failure');
                }
            });
            console.log(flag)
            return flag;

20191108更新

canvas畫布標籤之context.drawImage()函數不顯示圖片的問題:

最近在https://www.w3school.com.cn/tags/canvas_drawimage.asp上學習入門級的canvas標籤使用,遇到了drawImage函數(親自試一試https://www.w3school.com.cn/tiy/t.asp?f=html5_canvas_drawimage),看着它給的例子我整了半天沒搞清楚這個函數要做什麼,還以爲是可以用鼠標在那個白板上畫東西。

最後才弄明白是圖片沒展示出來所以是個白板,原因是在加載到JS中的ctx.drawImage時頁面上的圖片尚未加載完成,所以canvas上是個白板。解決辦法是用windows.onload套住ctx.drawImage即可:

改自https://www.w3school.com.cn/tiy/t.asp?f=html5_canvas_drawimage

<!DOCTYPE html>
<html>
<body>

<p>要使用的圖像:</p>
<img id="tulip" src="/i/eg_tulip.jpg" alt="The Tulip" />

<p>畫布:</p>
<canvas id="myCanvas" width="500" height="300" style="border:1px solid #d3d3d3;background:#ffffff;">
Your browser does not support the HTML5 canvas tag.
</canvas>

<script>

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("tulip");
window.onload = function(){
  ctx.drawImage(img,10,10);
}
</script>

</body>
</html>

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章