Функция JavaScript, ошибки, связанные с параметром функции - PullRequest
0 голосов
/ 19 ноября 2018

Приношу свои извинения, что этот вопрос сложно сформулировать, название может вводить в заблуждение. Вопрос в основном связан с передачей параметров в функцию в JavaScript.

Эти коды ниже являются функцией, которая позволяет элементу перемещаться горизонтально. Он используется в слайдере. Мой вопрос конкретно связан с двумя строчками, которые я прокомментировал .

Я написал функцию, как показано ниже, в отдельном файле .js с именем common.js , и она отлично работает:

(обратите внимание на две строки, которые я прокомментировал)

function animateX(element, target, stepWidth) {     // the stepWidth parameter
    clearInterval(element.timerId);
    element.timerId = setInterval(function () {
        var current = element.offsetLeft;
        var step = stepWidth;                       // This line
        step = current < target ? step : -step;
        current += step;
        if (Math.abs(target - current) > Math.abs(step)) {
            element.style.left = current + "px";
        } else {
            clearInterval(element.timerId);
            element.style.left = target + "px";
        }
    }, 10);
}

Однако, если я напишу это таким образом, будет ошибка:

Переход исчез, когда я нажимаю на стрелки, картинка сразу перемещается к цели, а не скользит к цели.

function animateX(element, target, step) {     // the parameter uses the same name as the local variable
    clearInterval(element.timerId);
    element.timerId = setInterval(function () {
        var current = element.offsetLeft;
        var step = step;                       // This line: stepWidth -> step
        step = current < target ? step : -step;
        current += step;
        if (Math.abs(target - current) > Math.abs(step)) {
            element.style.left = current + "px";
        } else {
            clearInterval(element.timerId);
            element.style.left = target + "px";
        }
    }, 10);
}  

Более того, если я напишу это таким образом, это ухудшится:

Изображение не будет двигаться как запланировано, оно будет немного двигаться, а затем дрожать.

function animateX(element, target, step) {          // This line
    clearInterval(element.timerId);
    element.timerId = setInterval(function () {
        var current = element.offsetLeft;
       // Now I understand why this one is wrong.
        // I changed it to step = current < target ? Math.abs(step) : -Math.abs(step);
        // Problem solved.
        step = current < target ? step : -step;
        current += step;
        if (Math.abs(target - current) > Math.abs(step)) {
            element.style.left = current + "px";
        } else {
            clearInterval(element.timerId);
            element.style.left = target + "px";
        }
    }, 10);
}

Я полностью думал, что эти три пути одинаковы, но они дали мне совершенно разные результаты.

Я тоже думал, что третий путь лучше, потому что в нем меньше строк. Тем не менее, это не работает.

Может кто-нибудь, пожалуйста, объясните мне разницу? Буду очень признателен!

Ниже приведены html-коды, если у вас есть время, просто скопируйте и попробуйте. Этот HTML-файл и функция js - все, что вам нужно для его работы. Вы можете увидеть разницу без картинок.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0
        }

        ul {
            list-style: none
        }

        img {
            vertical-align: top;
        }

        .box {
            width: 960px;
            height: 540px;
            margin: 100px auto;
            padding: 5px;
            border: 1px solid #ccc;
        }

        .inner {
            width: 960px;
            height: 540px;
            background-color: pink;
            overflow: hidden;
            position: relative;
        }

        .inner ul {
            width: 1000%;
            position: absolute;
            top: 0;
            left: 0;
        }

        .inner li {
            float: left;
        }

        #imgs li a {
            width: 960px;
            height: 540px;
            display: block;
        }

        #focusD {
            display: none;
        }

        #focusD span {
            position: absolute; /* inner是relative */
            width: 40px;
            height: 40px;
            left: 5px;
            top: 50%;
            margin-top: -20px;
            background: #000;
            font-family: arial, sans-serif;
            cursor: pointer;
            line-height: 40px;
            text-align: center;
            font-weight: bold;
            font-size: 30px;
            color: #fff;
            opacity: 0.3;
            border: 1px solid #fff;
        }

        #focusD #right {
            right: 5px;
            left: auto;
        }

    </style>
</head>
<body>
<div class="box" id="box">
    <div class="inner">
        <ul id="imgs">
            <li><a href="#"><img src="images/d1.jpg" alt="d1"/></a></li>
            <li><a href="#"><img src="images/d2.jpg" alt="d2"/></a></li>
            <li><a href="#"><img src="images/d3.jpg" alt="d3"/></a></li>
            <li><a href="#"><img src="images/d4.jpg" alt="d4"/></a></li>
            <li><a href="#"><img src="images/d5.jpg" alt="d5"/></a></li>
        </ul>
        <div id="focusD">
            <span id="left">&lt;</span>
            <span id="right">&gt;</span>
        </div>
    </div>
</div>

<script type="text/javascript" src="common.js"></script>
<script type="text/javascript">
    // getElementByID
    function my$(id) {
        return document.getElementById(id);
    }
</script>
<script type="text/javascript">
    var box = my$("box");
    // get slider frame
    var inner = box.children[0];
    // get frame width
    var imgWidth = inner.offsetWidth;
    // get ul
    var ulObj = inner.children[0];
    // get div containing arrows
    var focusD = my$("focusD");

    // show / hide arrows
    box.onmouseover = function () {
        focusD.style.display = "block";
    };
    box.onmouseout = function () {
        focusD.style.display = "none";
    };

    var index = 0;
    // click left arrow
    my$("left").onclick = function () {
        if (index > 0) {
            index--;
            animateX(ulObj, -index * imgWidth, 20);
        }
    };
    // click right arrow
    my$("right").onclick = function () {
        if (index < ulObj.children.length - 1) {
            index++;
            animateX(ulObj, -index * imgWidth, 20);
        }
    };

</script>
</body>
</html>

1 Ответ

0 голосов
/ 19 ноября 2018

Во второй итерации вашей функции вы создаете переменную с именем 'step', имя которой совпадает с именем одного из параметров функции.На третьей итерации вы не создаете копию «stepWidth», необходимую для работы вашей функции.Попробуйте создать переменную с другим именем для хранения вашей копии 'step'.

function animateX(element, target, step) {         
clearInterval(element.timerId);
element.timerId = setInterval(function () {
    var current = element.offsetLeft;
    var stepWidth = step;                          
    stepWidth = current < target ? stepWidth : -stepWidth;
    current += stepWidth;
    if (Math.abs(target - current) > Math.abs(stepWidth)) {
        element.style.left = current + "px";
    } else {
        clearInterval(element.timerId);
        element.style.left = target + "px";
    }
}, 10);

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...