Ответы пользователя по тегу JavaScript
  • Любой символ в маске ввода номера, как сделать?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Да просто доработайте маску и всё:

    $("input[name=phone]").mask("+?99999999999");

    Если прям хотите изощриться, то можно использовать более сложный шаблон:

    $("input[name=phone]").mask("A9999999999", {
      translation: {
        'A': { pattern: /[0-9+]/ }
      }
    });
    Ответ написан
    1 комментарий
  • Как запустить Jquery Sortable по событию touchstart?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">
    	<title>jQuery UI Sortable - Default functionality</title>
    	<link rel="stylesheet" href="https://code.jquery.com/ui/1.14.0/themes/base/jquery-ui.css">
    	<style>
    		#sortable {
    			list-style-type: none;
    			margin: 0;
    			padding: 0;
    			width: 60%;
    		}
    
    		#sortable li {
    			margin: 0 3px 3px 3px;
    			padding: 0.4em;
    			padding-left: 1.5em;
    			font-size: 1.4em;
    			height: 18px;
    		}
    
    		#sortable li span {
    			position: absolute;
    			margin-left: -1.3em;
    		}
    	</style>
    	<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
    	<script src="https://code.jquery.com/ui/1.14.0/jquery-ui.js"></script>
    	<script src="jquery.ui.touch-punch.min.js"></script>
    	<script>
    		$(function () {
    			const $sortable = $("#sortable");
    
    			$sortable.sortable({
    				disabled: true
    			});
    
    			$sortable.on("contextmenu", function (e) {
    				e.preventDefault();
    			});
    
    			$sortable.on("touchstart", function () {
    				$(this).sortable("option", "disabled", false);
    			});
    		});
    	</script>
    </head>
    
    <body>
    
    	<ul id="sortable">
    		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
    		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
    		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
    		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
    		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
    		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 6</li>
    		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 7</li>
    	</ul>
    
    </body>
    
    </html>
    Ответ написан
  • Как создать уникальное событие?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    <html>
    <body onload="bodyload()">
    <button onclick="colorchangerclick()">newcolor</button>
    <script>
    function bodyload() {
      document.body.addEventListener("bodybgcolorchange", () => alert("bodybgcolorchange сработало!"));
    }
    
    function colorchangerclick() {
      document.body.style.background = prompt("Введите новый цвет фона (например, red, #000, rgb(0, 0, 0))");
    
      const bodybgcolorchange = new CustomEvent("bodybgcolorchange", {
        detail: {
          name: "bodybgcolor",
        },
      });
    
      document.body.dispatchEvent(bodybgcolorchange);
    }
    </script>
    </body>
    </html>
    Ответ написан
  • Как отправить запрос на сервер при закрытии вкладки?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Можно установить флаг в sessionStorage для условия перезагрузки страницы:

    useEffect(() => {
      sessionStorage.setItem('isReloading', 'true');
    
      const handleBeforeUnload = (event) => {
        const isReloading = sessionStorage.getItem('isReloading');
        if (isReloading === 'false') {
          QDB.edit(manager.id, { online: 0, logout_date: D_TimeNow(), navigator: navigator.userAgent }, 'users');
        }
      };
    
      const handleUnload = () => {
        sessionStorage.setItem('isReloading', 'false');
      };
    
      window.addEventListener('beforeunload', handleBeforeUnload);
      window.addEventListener('unload', handleUnload);
    
      return () => {
        window.removeEventListener('beforeunload', handleBeforeUnload);
        window.removeEventListener('unload', handleUnload);
      };
    }, []);
    Ответ написан
  • Как сделать автопрокрутку слайдер с swiper без задержек?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    <Swiper
          slidesPerView={4}
          className={style.mySwiper}
          loop={true}
          allowTouchMove={false}
          autoplay={{
            delay: 0,
            disableOnInteraction: false,
          }}
          speed={2000}
          modules={[Autoplay, Loop]}
        >
          {partners.map((partner) => (
            <SwiperSlide key={partner.id}>
              <img
                className={style.partnerImage}
                src={partner.photo}
                alt={`Partner ${partner.id}`}
              />
            </SwiperSlide>
          ))}
        </Swiper>
    Ответ написан
    Комментировать
  • Функция увеличивает ЗП, если ошибка то уведомление админу?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Не проще отделить шаг уведомления сотрудника и отправлять его только в случае успешного завершения всех предыдущих операций?

    function increaseSalary() {
      return api.getEmployees()
        .then(employeeData => {
          const [minSalaryEmployee] = employeeData.reduce(([minEmployee, minSalary], employee) => {
            const { salary } = employee;
            return (salary < minSalary
              ? [employee, salary]
              : [minEmployee, minSalary]
            );
          }, [null, Infinity]);
          const { id, salary: oldSalary } = minSalaryEmployee;
          const newSalary = oldSalary * 1.2;
          return { id, salary: newSalary };
        })
        .then(({ id, salary }) => api.setEmployeeSalary(id, salary)
          .then(updatedEmployee => {
            return api.notifyEmployee(updatedEmployee.id, `Hello, ${updatedEmployee.name}! Congratulations, your new salary is ${salary}!`);
          })
        )
        .catch(e => {
          return api.notifyAdmin(e);
        });
    }
    Ответ написан
  • Как разбить текст в текстареа по строкам?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Ответ написан
    Комментировать
  • Как сделать анимации появления картинок при нажатии на кнопку?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Для вашей задачи достаточно будет использования свойств opacity и transition вместо visibility.

    <div class="knopka">
      <div class="kn">
        <button onclick="showElement()">Показать больше</button>
      </div>
      
      <div class="kn1">
        <button onclick="hideElement()">Скрыть</button>
      </div>
      
      <div class="container" id="imageContainer">
        <div class="scr41">
          <img src="/Untitled (5)/Group 10.png" alt="Image 1">
        </div>
      
        <div class="scr51">
          <img src="/Untitled (5)/Group 11.png" alt="Image 2">
        </div>
    
        <div class="scr51">
          <img src="/Untitled (5)/Group 12.png" alt="Image 3">
        </div>
      </div>
    </div>


    .knopka {
        text-align: end;
    }
    
    .kn {
        margin-top: -55px;
        margin-right: 350px;
    }
    
    .kn button, .kn1 button {
        color: #4E4E4E;
        border-radius: 5px;
        background-color: #F7F7F7;
        font-size: 15px;
        border: none;
        width: 200px;
        height: 40px;
    }
    
    .kn button:hover, .kn1 button:hover {
        background-color: #ffa34857;
        color: rgb(0, 0, 0);
        transition: all 0.6s ease;
    }
    
    .container {
        justify-content: center;
        display: flex;
        opacity: 0;
        transition: opacity 1s ease-in-out;
        pointer-events: none;
    }
    
    .container.show {
        opacity: 1;
        pointer-events: auto;
    }
    
    .scr41 img, .scr51 img {
        margin-top: 70px;
        width: 140px;
    }


    function showElement() {
        const element = document.getElementById('imageContainer');
        element.classList.add('show');
    }
    
    function hideElement() {
        const element = document.getElementById('imageContainer');
        element.classList.remove('show');
    }
    Ответ написан
    Комментировать
  • Возможно ли включить сортировку во время touchstart?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Вместо того чтобы полностью полагаться на touchstart, используйте его для начала подготовки, но инициализируйте сортировку с помощью других событий, например touchmove. При этом стоит ограничить область touchmove, чтобы сортировка не начиналась до явного движения пальцем. Также нужно вручную инициировать сортировку.

    var sortable = new Sortable(listElement, {
        animation: 150,
        onStart: function (evt) {
            console.log('Начало сортировки');
        }
    });
    
    listElement.addEventListener('touchstart', function (e) {
        var touch = e.touches[0];
        var targetElement = document.elementFromPoint(touch.clientX, touch.clientY);
    
        sortable._onDragStart({
            target: targetElement,
            clientX: touch.clientX,
            clientY: touch.clientY,
            type: 'touchstart'
        });
    }, false);
    Ответ написан
  • .toggleClass не анимирует раскрытие и скрытие блока - что не так?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Вы неверно выбрали метод .toggleClass(), он не анимирует изменение высоты элемента.
    Вы можете использовать .slideToggle() в совокупности с .toggleClass():

    $(".show-more").click(function () {
        if($("#text-more").hasClass("expanded")) {
            $(this).text("показать все товары");
        } else {
            $(this).text("скрыть товары");
        }
        $("#text-more").slideToggle(1000).toggleClass("expanded");
    });
    Ответ написан
  • Как удалить Content-Security-Policy?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    Наверное, одним из универсальных вариантов будет использование прокси-сервера, который вам поможет обойти заголовки CSP путем маршрутизации запросов через сервер, где эти заголовки могут быть изменены.

    На node.js он разворачивается довольно просто:

    const http = require('http');
    const httpProxy = require('http-proxy');
    
    const proxy = httpProxy.createProxyServer({});
    
    http.createServer(function(req, res) {
        proxy.web(req, res, {
            target: 'https://game-analytics.ru',
            changeOrigin: true,
            selfHandleResponse: true
        });
    
        proxy.on('proxyRes', function(proxyRes, req, res) {
            let body = [];
    
            proxyRes.on('data', function(chunk) {
                body.push(chunk);
            });
    
            proxyRes.on('end', function() {
                body = Buffer.concat(body);
                res.setHeader('Content-Security-Policy', '');
                res.writeHead(proxyRes.statusCode, proxyRes.headers);
                res.end(body);
            });
        });
    
    }).listen(3000, () => {
        console.log('Прокси-сервер запущен на порту 3000');
    });


    В вашем коде используйте прокси-адрес при создании iframe окна:

    <html lang="ru">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Создание Iframe через JavaScript</title>
    </head>
    <body>
    <div id="iframe-container"></div>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const iframe = document.createElement('iframe');
            iframe.setAttribute('src', 'http://localhost:3000');
            document.getElementById('iframe-container').appendChild(iframe);    
        });
    </script>
    </body>
    </html>
    Ответ написан
  • Как сделать динамическое добавление на ajax, чтобы записи не дублировались?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    1. Используй метод .off() для удаления предыдущих обработчиков событий перед добавлением нового.
    2. Исправь код AJAX, чтобы ограничить количество перерисовок элементов.

    $("#modal").off('submit').on('submit', function (e) { 
        e.preventDefault();
        var form_data = $(this).serialize();
    
        $.ajax({
            type: "POST",
            url: "user/add.php",
            data: form_data,
            success: function (html) {
                document.getElementById("shadow").style.display = "none";
                document.getElementById("modal").style.display = "none";
                $('#modal').trigger('reset');
                $("#main").append(html);
            }
        });
    });


    add.php:

    require "../database/Task.php";
    
    if (isset($_POST['title']) && isset($_POST['description'])) {
        $task_mess = new Task;
        $task_mess->add_task($_POST['title'], $_POST['description']);
    
        $new_task = $task_mess->get_last_task();
    
        echo "<div class='task'>
                <h3>{$new_task['title']}</h3>
                <p>{$new_task['description']}</p>
              </div>";
    }
    Ответ написан
    2 комментария