Maison >interface Web >js tutoriel >Glisser-Déposer sans classes CSS en utilisant ObservableTypes

Glisser-Déposer sans classes CSS en utilisant ObservableTypes

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-09 07:07:02357parcourir

Drag

De nombreuses bibliothèques d'interface utilisateur et frameworks CSS sont utilisés pour activer des fonctionnalités spéciales en recourant à des classes CSS. C'était particulièrement tendance à l'époque des plugins jQuery.

Bien qu'il s'agisse d'un choix très populaire, c'est définitivement un anti-modèle de programmation.

Aujourd'hui, nous avons plusieurs moyens alternatifs. Une approche issue du domaine fonctionnel-réactif permet de simplement « fusionner » une fonctionnalité dans un élément existant. Pas de classes CSS, pas d'abus d'attribut id.

Supposons que nous souhaitions activer le glisser-déposer dans une liste HTML au moyen d'un module réutilisable distinct que nous pouvons ajouter ou supprimer à volonté.

  <ul ...${Sortable({onOrderChange: todoList.move})}>
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
    <li>item 4</li>
    <li>item 5</li>
  </ul>

Sortable va être implémenté dans ce qu'on appelle un Mixin. Ce qu'il fait, c'est exporter des attributs, des styles, des classes, des gestionnaires d'événements dans ce qu'on appelle un "objet DOM": tout ce qu'il contient sera fusionné dans l'élément cible.

// sortable.ts
import { Subject, map, withLatestFrom } from 'rxjs';

export const Sortable = ({ onOrderChange }) => {
  const dragStart = new Subject<HTMLLIElement>();
  const drop = new Subject<HTMLLIElement>();

  drop.pipe(
    withLatestFrom(dragStart),
    map(([dropEvt, dragEvt]) => {
      const list = [...dragEvt.target.closest('ol,ul').children];
      return [ list.indexOf(dragEvt.target), list.indexOf(dropEvt.target.closest('li')) ]
    }),
  ).subscribe(([src, dst])=>onOrderChange(src, dst));

  // Export a DOM Object for a framework or UI library
  // to take care of and merge into the target element
  return {
    ondragstart: dragStart,
    ondragover: e=>e.preventDefault(),
    ondrop: drop,
  };
};

Ainsi, le code final de l'application ressemblera à ceci :

import { rml } from 'rimmel';

const List = () => {

  return rml`
      <ul ...${Sortable({onOrderChange: todoList.move})}>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
        <li>item 5</li>
      </ul>
  `;
}

Jouez avec un exemple entièrement fonctionnel ici :

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn