如何通过函数调用向页面添加新元素,并将事件处理程序附加到它们,而不在函数内指定它们?

时间:2022-11-05 16:55:05

So I have an app. It's written on jQuery(UI & Mobile).

所以我有一个应用程序。它是在jQuery(UI和Mobile)上编写的。

I have this page structure:

我有这个页面结构:

Main Page:

    <!-- Main Page -->
    <div data-role="page" id="home">
        <header data-role="header" data-theme="a">
            <h1>Running Tracker</h1>
        </header>
        <div data-role="navbar">
            <ul>
                <li>
                    <a href="#add" data-transition="fade" data-icon="plus">Add Run</a>
                </li>
            </ul>
        </div>
        <div data-role="content">
            <h3>Welcome to the RunningTracker App</h3>
            <p>
                With this app you can track your running, jogging or walking.
            </p>

            <h3>Your Latest Runs:</h3>

            <ul id="stats" class="current"  data-role="listview" data-filter="true" data-filter-placeholder="Filter runs by date or distance." data-inset="true" ></ul>
            <br/>
            <button id="clearRuns" onclick="return confirm('Are You Sure?')">
                Clear Data
            </button>
        </div>
        <footer data-role="footer">
            <h4>RunningTracker &copy; 2015 GZ</h4>
        </footer>
    </div>

Add New Entry Page:

添加新条目页面:

        <!-- Add Run Page -->
        <div data-role="page" id="add">
            <header data-role="header" data-theme="a">
                <h1>Running Tracker</h1>
            </header>
            <div data-role="navbar">
                <ul>
                    <li>
                        <a href="#home" data-transition="fade" data-icon="home">Home</a>
                    </li>
                </ul>
            </div>
            <div data-role="content">
                <h3>Add Run</h3>
                <form id="addForm">
                    <label for="km">Enter Kilometres:</label>
                    <input type="number" id="addKms" required>
                    <label for="km">Enter Date:</label>
                    <input type="date" data-role="date" class="date" id="addDate" data-inline="true" required>
                    <button id="submitAdd" class="ui-btn ui-corner-all">
                        Add Run
                    </button>
                </form>
            </div>
            <footer data-role="footer">
                <h4>RunningTracker &copy; 2015 GZ</h4>
            </footer>
        </div>

And I have a function to add new Runs, so when you are adding a new entry, application replaces current home page with edit page by using data-transition method.

我有一个添加新运行的功能,因此当您添加新条目时,应用程序使用数据转换方法将当前主页替换为编辑页面。

On that page I enter all the needed data to the form and submit it using this function:

在该页面上,我将所有需要的数据输入到表单并使用此函数提交:

addRun:

function addRun() {
            /*
             * Data Manipulation Here
             */

            //Redirect back to Home page after form is submitted
            $("body").pagecontainer("change", "#home", {
                transition : "fade",
                reverse : true
            });

            //Here I hide all Original Entries that are currently displayed(they have class "original"
            $('.original').hide();
            //Here I display all the entries again, including the new ones
            showRuns();
            //Here I add EventHandlers again, to newly created Elements
        }
    }

So as you can see I have to replicate same actions in every function I execute if I want to keep all the needed handlers on elements.

因此,如果我想在元素上保留所有需要的处理程序,我必须在我执行的每个函数中复制相同的操作。

So in a nutshell why I am doing it like this:

所以简而言之,为什么我这样做:

1) I load my current view like this:

1)我加载我的当前视图:

    $(document).on("pagecreate", "#home", function() {
        //Showing All Current Entries
        showRuns();
        //Attaching Event Handlers
        $('#submitAdd').on('tap', addRun);
        $('#submitEdit').on('tap', editRun);
        $('.editLink').on('tap', setCurrent);
        $('.deleteLink').on('tap', function() {
            var confirmation = confirm("Are you sure?");
            if (confirmation) {
                setCurrent.call(this);
                deleteRun.call(this);
            }
        });
        $('#clearRuns').on('tap', clearAll);

        //Declaring all functions that I use in eventHandlers below

});

2) Then I switch to #add page to add new entry.

2)然后我切换到#add页面添加新条目。

3) I add add new entry and get switched back to the main page. If I do so without calling showRuns function inside my addRuns function, I won't see the new entry I've just added, I will have to reload the page to see it.

3)我添加新条目并切换回主页面。如果我这样做而没有在我的addRuns函数中调用showRuns函数,我将不会看到我刚刚添加的新条目,我将不得不重新加载页面来查看它。

4) If I will call showRuns function inside my addRuns function I will see duplicated entries, because function will be called again on each addRun call.

4)如果我将在addRuns函数中调用showRuns函数,我将看到重复的条目,因为在每次addRun调用时将再次调用函数。

5) To see new entry after I add it I have to remove all other entries from main page, that have class current and after that I call showRuns function that will add all entries to the main page again, BUT they won't have any event handlers because they were created after page was loaded.

5)要在添加它之后查看新条目,我必须从主页中删除所有其他条目,其中包含当前类,然后我调用showRuns函数,它将所有条目再次添加到主页,但它们将没有任何条目事件处理程序,因为它们是在页面加载后创建的。

6) So now I have to add all the handlers again.

6)所以现在我必须再次添加所有处理程序。

I have a feeling there must be a better way to do what I want - to add new elements to the page, without the need to do all the steps I've described above.

我觉得必须有更好的方法来做我想要的 - 向页面添加新元素,而不需要完成我上面描述的所有步骤。

I've tried reloading the page-container by using it like this:

我试过像这样使用它重新加载页面容器:

$("body").pagecontainer("change", "#home", {
                transition : "fade",
                reload : true
            });

But If I do so, it has no effect.

但如果我这样做,它就没有效果了。

Here is live Demo: http://runningtracker.herokuapp.com/

这是现场演示:http://runningtracker.herokuapp.com/

1 个解决方案

#1


2  

Have you tried using event delegation: http://learn.jquery.com/events/event-delegation/

您是否尝试过使用事件委派:http://learn.jquery.com/events/event-delegation/

This lets you put the event on the container and then delegate it to elements within the container whether they exist at design time or not.

这使您可以将事件放在容器上,然后将其委托给容器中的元素,无论它们是否在设计时存在。

Change

    $('.editLink').on('tap', setCurrent);
    $('.deleteLink').on('tap', function() {...

To

    $(document).on('tap','.editLink', setCurrent);
    $(document).on('tap','.deleteLink', function() {...

#1


2  

Have you tried using event delegation: http://learn.jquery.com/events/event-delegation/

您是否尝试过使用事件委派:http://learn.jquery.com/events/event-delegation/

This lets you put the event on the container and then delegate it to elements within the container whether they exist at design time or not.

这使您可以将事件放在容器上,然后将其委托给容器中的元素,无论它们是否在设计时存在。

Change

    $('.editLink').on('tap', setCurrent);
    $('.deleteLink').on('tap', function() {...

To

    $(document).on('tap','.editLink', setCurrent);
    $(document).on('tap','.deleteLink', function() {...