每次在 CRUD 函数上渲染时 Django 闪烁/闪烁[关闭]

Posted

技术标签:

【中文标题】每次在 CRUD 函数上渲染时 Django 闪烁/闪烁[关闭]【英文标题】:Django Flashing/Flickering on each Render on CRUD function [closed] 【发布时间】:2021-07-19 21:53:46 【问题描述】:

我正在处理 Django REST 框架任务。每次我执行创建、检索、更新和删除功能时,div 的列表项都会闪烁。

如何停止这种闪烁/闪烁?

从 API URL 我必须显示分页数据。如果我单击下一页,也会发生闪烁。我怎样才能摆脱这个闪烁/闪烁的问题?

ma​​in.html

% extends 'todo/index.html' %
% block content %
<div class="center-column" id="center-column">
    <h5 class="card-title" id="welcome" data-id= request.user.id >
        Hello  request.user.username , Create your todo list
    </h5>
    <div id="addTodoForm">
        <form action="" method="">
            <div class="input-group-append">
                <input type="text" class="title-input" required name="title" placeholder="e.g. Chemistry">
                <button type="submit" class="form-control btn btn-primary mr-sm-2" id="addTodobtn">
                    Add Todo
                </button>
            </div>
        </form>
    </div>
</div>
<div class="row" id="row">
    <div class="col-sm-5">
        <div class="card">
            <div class="card-body">
                <h5 class="card-title">
                    Incomplete Todo Items
                </h5>
                <hr />
                <div class="list-group" id="incompleteTodo">
                </div>
                <hr>
                <nav aria-label="..." id="incompletePagination">
                    <ul class="pagination justify-content-center">
                        <li class="page-item">
                            <button class="page-link" tabindex="-1" id="prevPageI">&laquo</button>
                        </li>
                        <li class="page-item"><button class="page-link" id="currPageI">1</button></li>
                        <li class="page-item"><button class="page-link" id="nextPageI">&raquo</button></li>
                    </ul>
                </nav>
            </div>
        </div>
    </div>
    <div class="col-sm-5">
        <div class="card">
            <div class="card-body">
                <h5 class="card-title">
                    Completed Todo Items
                </h5>
                <hr>
                <div class="list-group" id="completedTodo">
                </div>
                <hr>
                <nav aria-label="..." id="completedPagination">
                    <ul class="pagination justify-content-center">
                        <li class="page-item">
                            <button class="page-link" tabindex="-1" id="prevPageC">&laquo</button>
                        </li>
                        <li class="page-item"><button class="page-link" id="currPageC">1</button></li>
                        <li class="page-item"><button class="page-link" id="nextPageC">&raquo</button></li>
                    </ul>
                </nav>
            </div>
        </div>
    </div>
</div>
% endblock %

ma​​in.js

function getCookie(name) 
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') 
        const cookies = document.cookie.split(';');
        for (let todo = 0; todo < cookies.length; todo++) 
            const cookie = cookies[todo].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) 
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            
        
    
    return cookieValue;

var csrftoken = getCookie('csrftoken');

function taskStatus(item) 
    return `
        $item.map(task =>
            `
            <div class="card list-group-item list-group-item-danger mt-1" id="task_$task.id">
                <span class="font-italic">$task.heading</span>
                <div class="float-right">
                    <badge type="submit" class="badge badge-light" id="complete-task_$task.id">
                        &#10004;
                    </badge>
                    <badge type="submit" class="badge badge-warning ml-1" id="delete-task_$task.id">
                        ❌
                    </badge>
                </div>
                <div class="float-right">
                    <badge type="submit"
                            class="badge badge-dark mr-1 edit-task"
                            id="edit-task_$task.id"
                            data-target="#updateTaskModal_$task.id"
                            data-toggle="modal">
                        edit
                    </badge>

                    <div class="modal fade" id="updateTaskModal_$task.id" tabindex="-1" role="dialog"
                            aria-hidden="true">
                        <div class="modal-dialog" role="document">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <h5 class="modal-title">Update Todo</h5>
                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                        <span aria-hidden="true">&times;</span>
                                    </button>
                                </div>
                                <div class="modal-body">
                                    <div class="list-group-item list-group-item-warning">
                                        <input type="text" required id='updateTaskInp_$task.id' size='45'
                                            name="heading_$task.id" value="$task.heading">
                                    </div>
                                </div>
                                    <div class="modal-footer">
                                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                                    <button type="button" class="btn btn-primary" id="updateTaskModalSubmit_$task.id"
                                        data-dismiss="modal">
                                        Submit
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>`
                
        ).join('')
    `
;

function taskCompleted(item) 
    return `
        $item.map(task => 
            `
            <div class="list-group-item bg-danger mb-1">
                <span class="text-light font-italic">$task.heading</span>
                <div class="float-right">
                    <badge type="submit" class="badge badge-warning ml-1" id="delete-task_$task.id">
                        ❌
                    </badge>
                </div>
            </div>
            ` 
        ).join('')
    `
;

$(document).ready(function() 
    const incompleteHome = '/api/todo-incomplete/?incomplete=1';
    const completedHome = '/api/todo-completed/?completed=1';
    todoIncompleteItems(incompleteHome);
    todoCompletedItems(completedHome);
    // Create Todo Item
    $('#addTodobtn').click(function(e) 
        e.preventDefault();
        var title = $(".title-input").val();
        var user_id = $('#welcome').data('id');
        console.log("Title: ", title)
        $.ajax(
            url: "api/create-todo/",
            type: "POST",
            headers:
                "X-CSRFToken":csrftoken
            ,
            data: 
                "title": title,
                "user_id": user_id,
            ,
            success: function(data) 
                $("#incompleteTodo").html('');
                todoIncompleteItems(incompleteHome);
            ,
            error: function(err) 
                alert("check the console for errors");
                console.log("Create Todo Item Error: ", err)
            
        )
        $(".title-input").val('');
    )

    var nextIncomplete = null;
    var prevIncomplete = null;
    var currentPageIncomplete = null;
    var currentIncomplete = null;

    $('#nextPageI').click(function() 
        currentIncomplete +=1
        $('#currPageI').html(currentIncomplete)
        todoIncompleteItems(nextIncomplete);
    )

    $('#prevPageI').click(function() 
        currentIncomplete -= 1
        $('#currPageI').html(currentIncomplete)
        todoIncompleteItems(prevIncomplete);
    )

    // Page wise Incomplete Todo Items
    function todoIncompleteItems(incompleteUrl) 
        $('#incompleteTodo').html('');
        $.ajax(
            url: incompleteUrl,
            type: 'GET',
            success: function(data) 
                currentPageIncomplete = `api/todo-incomplete/?incomplete=$data.current_page_no`;
                currentIncomplete = data.current_page_no;

                nextIncomplete = data.next;
                if (data.next != null) 
                    $('#nextPageI').css("visibility", "visible")

                 else 
                    $('#nextPageI').css("visibility", "hidden")
                

                prevIncomplete = data.previous;
                if (data.previous != null) 
                    $('#prevPageI').css("visibility", "visible")
                 else 
                    $('#prevPageI').css("visibility", "hidden")
                

                if (data.next === null && data.previous === null) 
                    $('#incompletePagination').css("visibility", "hidden")
                 else 
                    $('#incompletePagination').css("visibility", "vidible")
                

                let todoItems = data.results;
                for (let todo in todoItems) 
                    $('#incompleteTodo').append(
                        `<div class="list-group-item list-group-item-primary mb-1" id="todo-$todo"
                            data-id="$todoItems[todo].id">
                            <span class="font-weight-bold">$todoItems[todo].title</span>
                            <div class="float-right">
                                <badge type="submit" class="badge badge-warning" id="deleteTodo_$todoItems[todo].id">
                                    ❌
                                </badge>
                            </div>
                            <div class="float-right">
                                <badge type="submit" class="badge badge-light mr-1"
                                    id="completed-todo_$todoItems[todo].id">
                                    &#10004;
                                </badge>
                            </div>          
                            <div class="float-right">
                                <badge type="submit" class="badge badge-dark mr-1 edit"
                                data-target="#updateTodoModal_$todoItems[todo].id" data-toggle="modal">
                                    edit
                                </badge>
                                <div class="modal" id="updateTodoModal_$todoItems[todo].id" tabindex="-1"
                                    role="dialog" aria-labelledby="staticBackdropLabel" aria-hidden="true">
                                    <div class="modal-dialog" role="document">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h5 class="modal-title">Update Todo</h5>
                                                <button type="button" class="close" data-dismiss="modal"
                                                    aria-label="Close">
                                                    <span aria-hidden="true">&times;</span>
                                                </button>
                                            </div>
                                            <div class="modal-body">
                                                <div class="list-group-item list-group-item-warning">
                                                    <input type="text" id='updateTodoInp_$todoItems[todo].id'
                                                        size="45" value="$todoItems[todo].title">
                                                </div>
                                            </div>
                                                <div class="modal-footer">
                                                <button type="button" class="btn btn-secondary" data-dismiss="modal">
                                                    Close
                                                </button>
                                                <button type="button" class="btn btn-primary"
                                                    id="updateModalSubmit_$todoItems[todo].id" data-dismiss="modal">
                                                    Submit
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="float-right mr-1">
                                <badge type="submit" class="badge badge-primary add-task" data-toggle="modal" 
                                    data-target="#addTaskModal_$todoItems[todo].id">
                                    &#x271A;
                                </badge>

                                <div class="modal" id="addTaskModal_$todoItems[todo].id" tabindex="-1" role="dialog"
                                    aria-labelledby="taskModalLabel" aria-hidden="true">
                                    <div class="modal-dialog" role="document">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h5 class="modal-title" id="taskModalLabel">
                                                    Add New Task for $todoItems[todo].title
                                                </h5>
                                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                                <span aria-hidden="true">&times;</span>
                                                </button>
                                            </div>
                                            <div class="modal-body">
                                                <div class="list-group-item list-group-item-dark">
                                                    <input type="text" required id='addTaskInp_$todoItems[todo].id' size="45"
                                                        name="heading" placeholder="Enter the task name here...">
                                                </div>  
                                            </div>
                                            <div class="modal-footer">
                                                <button type="button" class="btn btn-secondary closeModal"
                                                    data-dismiss="modal">
                                                    Close
                                                </button>
                                                <button type="button" class="btn btn-primary"
                                                    id="taskSubmit_$todoItems[todo].id" data-dismiss="modal">
                                                    Submit
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>                        
                            <div class="mt-3 incompleteTodo-task">
                                $todoItems[todo].tasks ? taskStatus(todoItems[todo].tasks) : '' 
                            </div>   
                        </div>
                        `
                    )
                ;
                for (var todo in todoItems) 
                    var deleteTodoBtn = document.querySelector(`#deleteTodo_$todoItems[todo].id`)
                    var taskSubmitBtn = document.querySelector(`#taskSubmit_$todoItems[todo].id`)
                    var editTodoBtn = document.querySelector(`#updateModalSubmit_$todoItems[todo].id`)
                    var completedTodoBtn = document.querySelector(`#completed-todo_$todoItems[todo].id`)

                    deleteTodoBtn.addEventListener('click', (function(element) 
                        return function() 
                            deleteTodo(element)
                        
                    )(todoItems[todo]))

                    taskSubmitBtn.addEventListener('click', (function(element) 
                        return function() 
                            addTaskItem(element)
                        
                    )(todoItems[todo]))

                    editTodoBtn.addEventListener('click', (function(element) 
                        return function() 
                            editTodoItem(element)
                        
                    )(todoItems[todo]))

                    completedTodoBtn.addEventListener('click', (function(element) 
                        return function() 
                            completedTodo(element)
                        
                    )(todoItems[todo]))

                    var taskItems = todoItems[todo].tasks
                    for (var task in taskItems) 
                        var deleteTaskBtn = document.querySelector(`#delete-task_$taskItems[task].id`)
                        var completeTaskBtn = document.querySelector(`#complete-task_$taskItems[task].id`)
                        var editTaskBtn = document.querySelector(`#updateTaskModalSubmit_$taskItems[task].id`)

                        deleteTaskBtn.addEventListener('click', (function(element) 
                            return function() 
                                deleteTask(element)
                            
                        )(taskItems[task]))

                        completeTaskBtn.addEventListener('click', (function(element) 
                            return function() 
                                completedTask(element)
                            
                        )(taskItems[task]))

                        editTaskBtn.addEventListener('click', (function(element) 
                            return function() 
                                editTaskItem(element)
                            
                        )(taskItems[task]))

                        if(taskItems[task].completed === true) 
                            $(`#task_$taskItems[task].id`).removeClass("list-group-item-danger")
                            $(`#task_$taskItems[task].id`).addClass("list-group-item-dark")
                            $(`#edit-task_$taskItems[task].id`).remove()
                            $(`#complete-task_$taskItems[task].id`).remove()
                        
                        
                
            ,
            error: function(err) 
                console.log(err)
            
        );
    

    var nextCompleted = null;
    var prevCompleted = null;
    var currentPageCompleted = null;
    var currentCompleted = null;
    $('#nextPageC').click(function() 
        currentCompleted +=1
        $('#currPageC').html(currentCompleted)
        todoCompletedItems(nextCompleted);
    )

    $('#prevPageC').click(function() 
        currentCompleted -=1
        $('#currPageC').html(currentCompleted)
        todoCompletedItems(prevCompleted);
    )
    // Page wise Completed Todo Items
    function todoCompletedItems(CompletedUrl) 
        $('#completedTodo').html('');
        $.ajax(
            url: CompletedUrl,
            type: 'GET',
            success: function(data) 
                var todoItems = data.results;  
                currentPageCompleted = `api/todo-completed/?completed=$data.current_page_no`
                currentCompleted = data.current_page_no

                nextCompleted = data.next;
                if (data.next != null) 
                    $('#nextPageC').css("visibility", "visible")

                 else 
                    $('#nextPageC').css("visibility", "hidden")
                

                prevCompleted = data.previous;
                if (data.previous != null) 
                    $('#prevPageC').css("visibility", "visible")
                 else 
                    $('#prevPageC').css("visibility", "hidden")
                

                if (data.next === null && data.previous === null) 
                    $('#completedPagination').css("visibility", "hidden")
                 else 
                    $('#completedPagination').css("visibility", "visible")
                

                for (var todo in todoItems) 
                    $('#completedTodo').append(
                        `
                        <div class="list-group-item bg-success mb-1"
                            id="todo_$todoItems[todo].id" data-id="$todoItems[todo].id">
                            <span class="text-light font-weight-bold">$todoItems[todo].title</span>
                            <div class="float-right">
                                <badge type="submit" class="badge badge-warning mr-2"
                                    id="deleteTodo_$todoItems[todo].id">
                                    ❌
                                </badge>
                            </div>
                            <div class="completedTodoTask mt-3">                  
                                $todoItems[todo].tasks ? taskCompleted(todoItems[todo].tasks) : ''
                            </div>  
                        </div>
                        `
                    )
                

                for (var todo in todoItems) 
                    var deleteTodoBtn = document.getElementById(`deleteTodo_$todoItems[todo].id`)

                    deleteTodoBtn.addEventListener('click', (function(item) 
                        return function() 
                            deleteTodo(item)
                        
                    )(todoItems[todo]))

                    var taskItems = todoItems[todo].tasks
                    for (var task in taskItems) 
                        var deleteTaskBtn = document.getElementById(`delete-task_$taskItems[task].id`)

                        deleteTaskBtn.addEventListener('click', (function(element) 
                            return function() 
                                deleteTask(element)
                            
                        )(taskItems[task]))
                    
                

            ,
            error: function(err) 
                console.log(err);
            
        )
    

    function editTodoItem(item) 
        var user_id = $('#welcome').data('id');
        var title = $(`#updateTodoInp_$item.id`).val();
        $.ajax(
            url: `api/update-todo/$item.id/`,
            type: 'POST',
            headers:
                "X-CSRFToken":csrftoken
            ,
            data: 
                'title': title,
                'user_id': user_id,
            ,
            success: function(data) 
                todoIncompleteItems(currentPageIncomplete);
            ,
            error: function(data) 
                alert("check the console for errors")
                console.log('Problem in updating todo item: ', data)
            
        )
    

    function addTaskItem(item) 
        var heading = $(`#addTaskInp_$item.id`).val();
        var user_id = $('#welcome').data('id')
        $.ajax(
            url: 'api/create-task/',
            type: 'POST',
            data: 
                'heading': heading,
                'user': user_id,
                'todo': item.id,
                'csrfmiddlewaretoken': csrftoken,
            ,
            success: function(data) 
                todoIncompleteItems(currentPageIncomplete);
            ,
            error: function(data) 
                alert("check the console for errors")
                console.log('Problem in adding new task item: ', data)
            
        )
    

    function completedTodo(item) 
        var user_id = $('#welcome').data('id')
        $.ajax(
            url: `api/completeTodoTask/$item.id/`,
            type: 'POST',
            headers:
                "X-CSRFToken":csrftoken
            ,
            data: 
                'title': item.title,
                'user_id': user_id,
                'completed': true,
            ,
            success: function(data) 
                todoIncompleteItems(currentPageIncomplete);
                todoCompletedItems(completedHome);
            ,
            error: function(data) 
                alert("check the console for errors")
                console.log('Problem in Completing Todo item: ', data)
            
        )
    

    function deleteTodo(item) 
        $.ajax(
            url: `api/delete-todo/$item.id/`,
            type: 'DELETE',
            headers: 
                "X-CSRFToken": csrftoken,
            ,
            success: function(data) 
                todoIncompleteItems(currentPageIncomplete);
                todoCompletedItems(currentPageCompleted);
            ,
            error: function(data) 
                alert("check the console for errors")
                console.log("There was an error while deleting Todo Item: ", data)
            
        )
    


    function editTaskItem(item) 
        var user_id = $('#welcome').data('id');
        var heading = $(`#updateTaskInp_$item.id`).val();
        $.ajax(
            url: `api/update-task/$item.id/`,
            type: 'POST',
            headers:
                "X-CSRFToken":csrftoken
            ,
            data: 
                'heading': heading,
                'user': user_id,
                'todo': item.todo,
            ,
            success: function(data) 
                todoIncompleteItems(currentPageIncomplete);
            ,
            error: function(err) 
                alert("check the console for errors")
                console.log("There was an error while deleting Task Item: ", data)
            
        )
    

    function completedTask(item) 
        var user_id = $('#welcome').data('id')
        $.ajax(
            url: `api/complete-task/$item.id/`,
            type: 'POST',
            data: 
                'heading': item.heading,
                'user': user_id,
                'completed': true,
                'title': 'title',
                'user_id': user_id,
                'csrfmiddlewaretoken': csrftoken,
            ,
            success: function(data) 
                todoIncompleteItems(currentPageIncomplete);
                todoCompletedItems(completedHome);
            ,
            error: function(data) 
                console.log('Problem in Completing Task item: ', data)
            
        )
    

    function deleteTask(item) 
        console.log("Delete Task Button Clicked: ", item.heading)
        $.ajax(
            url: `api/delete-task/$item.id/`,
            type: 'DELETE',
            headers: 
                "X-CSRFToken": csrftoken,
            ,
            success: function(data) 
                todoIncompleteItems(currentPageIncomplete);
                todoCompletedItems(currentPageCompleted);
            ,
            error: function(data) 
                alert("check the console for errors")
                console.log("There was an error while deleting Task Item: ", data)
            
        )
    

)

【问题讨论】:

可以发一下闪动的gif或者视频吗?这将比阅读整个代码容易得多。 Link to the video of flashing/flickering 【参考方案1】:

起初,我已经从 ma​​in.js 文件中删除了$("#incompleteTodo").html("")

然后,在函数外创建let todo_incomplete = [];用于存储数据 在本地添加 ed

let todoItems = data.results;
for (let todo in todoItems) 
      try 
          document.getElementById(`todo_$todo`).remove();
       catch(err)

循环结束后,我添加了

if(todo_incomplete.length > todoItems.length)
     for (var i = todoItems.length; i < todo_incomplete.length; i++)
          document.getElementById(`todo_$i`).remove();
      

todo_incomplete = todoItems;

我使用了这种方法,效果很好。我还没有找到任何解决方案。 在为 completed_Items 实现相同的方法时,我能够在 bot 列表中实现。

你可以查看这个YouTube video,时间戳49:00

【讨论】:

以上是关于每次在 CRUD 函数上渲染时 Django 闪烁/闪烁[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用vue时会出现加载渲染页面时闪烁问题

解决vue渲染时闪烁{{}}的问题

Django 多模板渲染

ReactJS网站在移动浏览器上重新渲染和闪烁[关闭]

解决使用angularjs时页面因为{{ }}闪烁问题的两种方式ngBind,ngCloak

渲染时 TextInput 闪烁/断断续续的行为