简体   繁体   中英

jQuery/Javascript code repetition

I am trying to use the scrollTop function for my program, but I am finding that I am writing a lot of repetitive code.

This is an example:

<div id="table_contents >
    <ul>
        <li id="one"> title One </li>
        <li id="two"> title Two </li>
    </ul>
</div>


<div id="content">
    <p id="target_one"> I am content one </p>

    <p id="target_two"> I am content two </p>
</div>

If i was to click on 'title One' I want to scroll to 'I am content one' Likewise for title two and content two.

This is easy enough to do with jQuery/JS

$("#one").click(function() {
        $('html, body').animate({
            scrollTop: $("#target_one").offset().top -20
        }, 800);
    });

But say for example my table of contents has 15 elements in it, and I want to make each clickable to scroll to its content. For this I would have to repeat the above code 15 times for each element.

Is there a better way than that?

Just change your script to :

Method 1

$("#table_contents").on("click","li",function() {
        $('html, body').animate({
            scrollTop: $("#target_"+$(this).prop('id')).offset().top -20
        }, 800);
    });

In this method, the id of the clicked element will be appended to "target_", to locate the "target id". This method will work even for the dynamically added li elements.


Method 2 : Without ids [but same order]:

$("#table_contents").on("click","li",function() {
        $('html, body').animate({
            scrollTop: $("#content p").eq($(this).index()).offset().top -20
        }, 800);
    });

in this method, the index of the element li is mapped to the index of the p elements to locate the scroll location.

And done!!

http://jsfiddle.net/bmL0o9ez/

http://jsfiddle.net/bmL0o9ez/2/

LIVE FIDDLE DEMO

$("#table_contents ul li").click(function () {

    var theIdAttr = $(this).attr("id");

    $("html, body").animate({
        scrollTop: $("#target_" + theIdAttr).offset().top -20
    });

});

You can use a more generic selector for type sort of thing where each element requires identical behavior.

$("#table_contents li").click(function() {
        var liElement = $(this);
        $('html, body').animate({
            scrollTop: $("#target_" + liElement.attr('id')).offset().top -20
        }, 800);
    });

You can build the id of the paragraph dynamically based on the id of the li.

HTML

    title One title Two

<div id="content">
    <p id="target_one"> I am content one </p>

    <p id="target_two"> I am content two </p>
</div>

Javascript:

$("#table_contents li").click(function() {
    $('html, body').animate({
        scrollTop: $('#target_' + $(this).attr('id')).offset().top -20
    }, 800);
 });

Make it generic, like:

$("#table_contents ul li").click(function() {
        $('html, body').animate({
            scrollTop: $('#target_'+ $(this).attr("id")).getId.offset().top -20
        }, 800);
    });

if you keep the content in order you could even go ultra generic, like:

$("#table_contents ul li").click(function() {
        var index = $(this).index();
        $('html, body').animate({
            scrollTop: $('#content:nth-child('+index+')').getId.offset().top -20
        }, 800);
    });

Not tested, but it should give you an idea

cheer mate

Here's a solution that doesn't rely on using IDs at all, but instead uses jQuery's index() function:

$("#table_contents li").click(function () {
    $('html, body').animate({
        scrollTop: $("p").eq($(this).index()).offset().top - 20
    }, 800);
});

jsFiddle example

I do

$("#content p").each(function() {
    var heights = [];
    heights.push($(this).offset().top);
});

Then do

heights[your_target_as_index];

Done?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM