ホームページ  >  記事  >  ウェブフロントエンド  >  スタートアップ向けのモバイル Web エクスペリエンスの強化

スタートアップ向けのモバイル Web エクスペリエンスの強化

王林
王林オリジナル
2023-08-29 15:29:01621ブラウズ

スタートアップ向けのモバイル Web エクスペリエンスの強化

このチュートリアルは、Envato Tuts の「Build Your Startup with PHP」シリーズの一部です。このシリーズでは、私のミーティング プランナー アプリを実際の例として使用して、スタートアップの立ち上げをコンセプトから現実に至るまでガイドします。あらゆる段階で、Meeting Planner コードをオープンソースのサンプルとしてリリースし、そこから学ぶことができます。また、スタートアップ関連で発生するビジネス上の問題にも対処します。

モバイルアプリとレスポンシブWeb

戦略的には、iOS と Android で Meeting Planner 用のモバイル アプリを構築するのは理にかなっていますが、財務上の観点からは、そのためのリソースをまだ調達していません。マシュー・イングラムは最近フォーチュン誌に、モバイル ユーザーをターゲットにした製品が非常に多いため、「少なくとも統計的に言えば、あなたのアプリをダウンロードする人は誰もいないでしょう」と書いています。リソースを考えると、それを採用する可能性はすぐには意味がありませんでした。

ただし、Meeting Planner がモバイル デバイス上で優れた Web エクスペリエンスを提供することが重要です。

今日のショーでは、これを行うために行った変更を確認し、説明します。つまり、基本的に Web アプリケーションを、モバイル デバイスやタブレットで簡単に使用できる応答性の高い Web サイトに近づけることです。結果を(携帯電話またはタブレットで)確認してください。

今日のエピソードのコーディング上の課題の 1 つは、私がデザイナーでも CSS コーダーでもないことです。時々、自分でコーディングする必要すらないと感じることがあります。マイクロソフトでは、私はチーム プロジェクト マネージャーを務めています。つまり、グラフィック デザイナーがおり、スタッフが常駐するユーザビリティ ラボがあり、CSS は存在しません。

この仕事を始める前は、メディア クエリ、ブレークポイント、特殊な CSS を学習することに怖気づいていました。これは私の得意分野ではなく、非常に時間がかかり、詳細を重視するものです。ただし、48 時間以内にすべてが迅速かつ完璧に完了しました。ストーリーの最後まで参照すると、すべての変更に必要な CSS 行は最終的にわずかであることがわかります。突然、携帯電話で Meeting Planner を閲覧し始めたとき、新しい応答性の高い Web エクスペリエンスがどれほどうまく機能するかに本当に興奮しました。

率直に言って、現時点では専用のモバイルアプリは必要ないと思います。現在、特に今後の重要なアルファおよびベータ段階では、モバイル Web エクスペリエンスを通じて視聴者を引き付けることができます。

一方、Meeting Planner をまだ試していない場合は、携帯電話またはタブレットから最初の会議をスケジュールしてください。私は以下のコメント スレッドに参加していますので、あなたの経験について教えてください。 Twitter @reifman でもご連絡いただけます。私は常に新しい機能のリクエストや推奨されるチュートリアル トピックに興味を持っています。

注意事項として、Meeting Planner のコードはすべて PHP の Yii2 フレームワークを使用して書かれています。 Yii2 についてさらに詳しく知りたい場合は、並行シリーズ「Yii2 によるプログラミング」を参照してください。

現在の移動状況

まず、iOS スマートフォンを使用して Meeting Planner サービスの現在のステータスを参照し、初期アプリケーションのスクリーンショットを撮りました。ひどくはありませんが、素晴らしいものでもありません。私が見つけたものを見直してみましょう。

ホームページ

ホームページは見栄えがしますが、美的には「スケジュールを簡単にする」というタイトルのテキストが少し異なる、つまりほぼ同じ長さの 3 行であることが望ましいと思います。ただし、Bootstrap はドロップダウン メニューを適切に管理し、ページの残りの部分は正常に動作します。

スタートアップ向けのモバイル Web エクスペリエンスの強化

登録ページ

繰り返しになりますが、ヘッダーのレイアウトと左マージンの一貫性を除けば、登録ページは基本的に機能します:

スタートアップ向けのモバイル Web エクスペリエンスの強化

企画会議

その人が会議の計画を立て始めたら、現在のインデックス ページを改善する必要があります。列が多すぎます。被写体が潰れてしまいます。そもそも、ここにどのような情報を表示するかは重要ではないのかもしれません。もちろん、コマンド オプションも表示されません。このページは、モバイル デバイス向けにさらに大幅に調整する必要があります。

スタートアップ向けのモバイル Web エクスペリエンスの強化

トピックに関する新しい会議出席依頼など、他のページは正常に動作しています。ただし、モバイル ユーザーは、会議を紹介する長いメッセージを入力するためのテキスト エリア フィールドを提供したくない場合があります:

スタートアップ向けのモバイル Web エクスペリエンスの強化

私たちが使用しているブートストラップ拡張機能では、アクターの追加も少し機能しなくなります:

スタートアップ向けのモバイル Web エクスペリエンスの強化

場所と時間の計画ビューがクラッシュし始めます。同様に、デスクトップのデザインでは、モバイル デバイス向けに詳細とオプションが多すぎます:

############その他の地域###

「場所」ページは正常に機能しますが、ボタンのレイアウトを改善する必要があります。おそらくモバイル ユーザーにはこの機能は必要ありません。 スタートアップ向けのモバイル Web エクスペリエンスの強化

同様に、モバイル デバイスでもデスクトップのタブと写真のレイアウトに問題があります。まだ再考する必要があります:

スタートアップ向けのモバイル Web エクスペリエンスの強化

開発ソリューション

もちろん、Web サイトには改善の余地がたくさんあります。モバイルデバイス向けに再検討する必要がある領域もあれば、最小限に抑える必要がある領域もあれば、見た目の調整が必要な領域もあります。仕事に取り掛かりましょう。 スタートアップ向けのモバイル Web エクスペリエンスの強化

さまざまな方法

このタスクを開始したとき、私にはメディア クエリとブレークポイントの経験がほとんどありませんでした。ここ数日、私は未知の泥沼に陥るのではないかと心配して先延ばしにしていた。私は編集者をからかうためにメディア クエリを練習することから始めました:

リーリー

冗談は頭の中の氷を解くのに役立ちます。 Envato の編集の神様はいつでも私を見てくれています。

私は多くの分野について考え始めました:

簡素化された機能、特に会議計画プロセス

モバイルデバイスに表示する重要な情報を決定する

    要素、列、メニュー オプションなどのモバイル デバイス上の特定の機能を非表示にする
  • メディアクエリとブレークポイントの使用
  • アルファ版リリースの最も重要な領域に焦点を当てます
  • ウェブ上で頻繁に目にする便利なコンセプトは、「モバイル ファースト デザイン」です。残念ながら、私は古いタイプなので、そんなことはしません。ただし、モバイル ファーストというテーマを持ってすべてのページを再考することが役立ちます。
  • たとえば、テーブル列が 4 つある会議インデックスは削除する必要があり、縦向きの電話では方向感覚を失います。
私はすべてのページを携帯電話で使用できるようにデザインする方法を自問しています。

メディアからの問い合わせウォームアップ

###ドロップダウンメニュー###

CSS を詳しく調べることへの躊躇を克服するのに、少し努力が必要でした。準備を整えるために、ドロップダウン メニューを最小化し、モバイル機能の範囲を簡素化することに取り組み始めました。

今のところ、小型デバイス用の基本的なメディア クエリを作成し、Web サイト全体で使用することにしました。これはfrontend/site.cssです:

リーリー

結局、変更は比較的簡単であることがわかりました。モバイル デバイスで非表示にしたいメニュー項目については、

menuhide

のような CSS プロパティを追加するだけです。

これは、/frontend/views/layouts/main.php に追加された

menuHide

属性です:

リーリー 突然、ドロップダウン メニューが複雑ではなくなりました:

徐々に、モバイル Web の機能を簡素化し、削減することが最高のエクスペリエンスを生み出すことに気づきました。少なくとも現時点では、いつでもデスクトップに戻って他の機能にアクセスできます。これは、アルファおよびベータ段階で人々からフィードバックを収集する機会でもあります。

###パン粉###

Yii のデフォルト レイアウトにはブレッドクラム ウィジェットが含まれていますが、これは Composer を通じて読み込まれるため、カスタマイズが困難です。最初の要素と最初の「/」区切り文字を非表示にする CSS を追加してみました:

スタートアップ向けのモバイル Web エクスペリエンスの強化

これには時間がかかりましたが、n 番目の子要素など、CSS をさらに深く掘り下げることができ、自信がつきました。 リーリー

CSS でコンテンツを変更できるとは知りませんでした。

結果は次のとおりです:

スタートアップ向けのモバイル Web エクスペリエンスの強化

指先ボタンの間隔を広げる

次に、CSS を追加して、モバイル デバイスのボタンに追加のパディングを提供し、指先で押すときにエラーが発生する可能性を減らしました。たとえば、デスクトップ上の送信ボタンとキャンセル ボタンは次のとおりです:

これは私が使用し、サイト内のさまざまなボタンやクリック可能なアイコンに追加し始めた CSS です: スタートアップ向けのモバイル Web エクスペリエンスの強化 リーリー

モバイルでフォームがどのように表示されるかは次のとおりです。

Submit

Cancel

の間の新しいパディングに注目してください:

スタートアップ向けのモバイル Web エクスペリエンスの強化

レスポンシブ テキストの折り返し

ホームページのタイトルを「Scheduling Made Easy」にするのには、実際にはもっと時間がかかります。最終的に、テキストに

スタートアップ向けのモバイル Web エクスペリエンスの強化 タグを追加し、モバイル デバイス以外ではデフォルトで非表示にしました。ただし、

itemHide

クラスを使用して、span タグにスペースを追加する必要もあります。

<h1>
    <?php echo Yii::t('frontend','Scheduling'); ?>
    <br class="rwd-break" />
    <span class="itemHide"> </span>
    <?php echo Yii::t('frontend','Made Easy') ?>
</h1>         

这是 .rwd-break 的 CSS。默认情况下它是隐藏的,并且仅出现在响应式显示中,从而按照我想要的方式破坏标题文本。

.rwd-break {
  display:none;
}
/* ----------- mobile displays ----------- */
@media only screen
  and (min-device-width: 320px)
  and (max-device-width: 667px)
  and (-webkit-min-device-pixel-ratio: 2) {
  ...
    .rwd-break {
      display:block;
    }
}

如果没有 span 标记空间,文本将在没有正确居中的情况下中断。

简化会议列表页面

随着我越来越认为“移动优先”,我意识到基于手机的用户并不需要我页面上的所有功能。他们不需要所有选项卡,不需要有关会议的数据表,也不需要所有图标按钮选项。事实上,对于会议页面,他们只需要能够打开会议(他们可以从会议视图页面本身取消会议)。

我将主题和参与者列合并为一个垂直列,结果看起来好多了。

スタートアップ向けのモバイル Web エクスペリエンスの強化

在 /frontend/views/meeting/index.php 中,我将 .tabHide 添加到两个四个选项卡中的:

<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
  <li class="active"><a href="#planning" role="tab" data-toggle="tab">Planning</a></li>
  <li ><a href="#upcoming" role="tab" data-toggle="tab">Confirmed</a></li>
  <li class="tabHide"><a href="#past" role="tab" data-toggle="tab" >Past</a></li>
  <li class="tabHide"><a href="#canceled" role="tab" data-toggle="tab">Canceled</a></li>
</ul>

并且,在 /frontend/views/meeting/_grid.php 中,我重组了该列以合并主题和参与者:

if ($mode =='upcoming' || $mode =='past') {
  echo GridView::widget([
      'dataProvider' => $dataProvider,
      //'filterModel' => $searchModel,
      'columns' => [
      [
        'label'=>'Details',
          'attribute' => 'meeting_type',
          'format' => 'raw',
          'value' => function ($model) {
              // to do - remove legacy code when subject didn't exist
                if ($model->subject=='') {
                  return '<div><a href="'.Url::to(['meeting/view', 'id' => $model->id]).'">'.$model->getMeetingHeader().'</a><br /><span class="index-participant">'.$model->getMeetingParticipants($model->id).'</span></div>';
                } else {
                  return '<div><a href="'.Url::to(['meeting/view', 'id' => $model->id]).'">'.$model->subject.'</a><br /><span class="index-participant">'.$model->getMeetingParticipants($model->id).'</span></div>';
                }
              },
      ],

隐藏 ActionColumn 需要进行一些研究,但看起来像这样:

['class' => 'yii\grid\ActionColumn','header'=>'Options','template'=>'{view}  {decline}  {cancel}',
    'headerOptions' => ['class' => 'itemHide'],
    'contentOptions' => ['class' => 'itemHide'],
    'buttons'=>[
        'view' => function ($url, $model) {
          return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', $url,
          [
                  'title' => Yii::t('frontend', 'view'),
                  'class' => 'icon-pad',
          ]);
        },
        'decline' => function ($url, $model) {
          return ($model->status==$model::STATUS_SENT ) ? Html::a('<span class="glyphicon glyphicon-thumbs-down"></span>', $url, [
                  'title' => Yii::t('frontend', 'decline'),
                  'class' => 'icon-pad',
          ]) : '';
        },
        'cancel' => function ($url, $model) {
          return ($model->status==$model::STATUS_SENT || $model->status==$model::STATUS_CONFIRMED ) ? Html::a('<span class="glyphicon glyphicon-remove-circle"></span>', $url, [
                  'title' => Yii::t('frontend', 'cancel'),
                  'data-confirm' => Yii::t('frontend', 'Are you sure you want to cancel this meeting?'),
                  'class' => 'icon-pad',
          ]) : '';
        },
      ]
    ],

最终,这些更改在改进移动设备的过程中简化了桌面界面。

最大的挑战:会议安排

スタートアップ向けのモバイル Web エクスペリエンスの強化

到目前为止,对我来说最具挑战性的任务是针对移动设备调整上面的会议安排页面。手机上的情况一团糟,我很害怕。另外,我一直担心将来如何为多个参与者采用这个界面 - 响应性要求可能只会让这变得更加困难。

我对 Yii 的 Kartik Bootstrap Switch Widget 扩展的使用在修改布局方面有其自身的局限性。将这些元素放置在表格列中效果很好,但使表格列响应式对于媒体查询来说并不那么简单。

当然,正如我在上面的会议列表页面中所示,隐藏列很容易,但修改位置就不那么容易了。

我首先从显示时间和地点选项的水平表格设计转向垂直的纵向风格。而且,显然,表和列有自己的能力,可以在没有媒体查询的情况下使用 HTML5 和 CSS 进行包装。

您可以在此处查看改进后的空白会议计划页面:

スタートアップ向けのモバイル Web エクスペリエンスの強化

每个部分视图都需要额外的 css 列才能使预定义的 Bootstrap 网格布局正常工作,例如左 col-xs4 和右 col-xs-8。这是一个例子:

<div class="panel panel-default">
  <!-- Default panel contents -->
  <div class="panel-heading">
    <div class="row">
      <div class="col-lg-4 col-md-4 col-xs-4"><h4>What</h4></div>
      <div class="col-lg-8 col-md-8 col-xs-8"><div style="float:right;">
      <?php
        if ($isOwner) {
            echo Html::a('', ['update', 'id' => $model->id], ['class' => 'btn btn-primary glyphicon glyphicon-pencil','title'=>'Edit']);
          }
        ?>
      </div>
    </div>
    </div>
  </div>

使地点和时间安排表格具有响应性是最困难的。我进行了实验并最终成功地使用了随着内容窗口(或设备)缩小而自然换行的表列。

我还消除了在其自己的列中显示参与者状态并禁用开关的情况 - 您无法更改它们,那么为什么将它们显示为开关呢?相反,我创建了参与者在地点和时间的状态的文本摘要。以下是 getWhenStatus() 的代码:

public static function getWhenStatus($meeting,$viewer_id) {
      // get an array of textual status of meeting times for $viewer_id
      // Acceptable / Rejected / No response:
      $whenStatus['text'] = [];
      $whenStatus['style'] = [];
      foreach ($meeting->meetingTimes as $mt) {
        // build status for each time
        $acceptableChoice=[];
        $rejectedChoice=[];
        $unknownChoice=[];
        // to do - add meeting_id to MeetingTimeChoice for sortable queries
        foreach ($mt->meetingTimeChoices as $mtc) {
          if ($mtc->user_id == $viewer_id) continue;
          switch ($mtc->status) {
            case MeetingTimeChoice::STATUS_UNKNOWN:
              $unknownChoice[]=$mtc->user_id;
            break;
            case MeetingTimeChoice::STATUS_YES:
              $acceptableChoice[]=$mtc->user_id;
            break;
            case MeetingTimeChoice::STATUS_NO:
              $rejectedChoice[]=$mtc->user_id;
            break;
          }
        }
        $temp ='';
        // to do - update for multiple participants
        // to do - integrate current setting for this user in style setting
        if (count($acceptableChoice)>0) {
          $temp.='Acceptable to '.MiscHelpers::getDisplayName($acceptableChoice[0]);
          $whenStatus['style'][$mt->id]='success';
        } else if (count($rejectedChoice)>0) {
          $temp.='Rejected by '.MiscHelpers::getDisplayName($rejectedChoice[0]);
          $whenStatus['style'][$mt->id]='danger';
        } else if (count($unknownChoice)>0) {
          $temp.='No response from '.MiscHelpers::getDisplayName($unknownChoice[0]);
          $whenStatus['style'][$mt->id]='warning';
        }
        $whenStatus['text'][$mt->id]=$temp;
      }
      return $whenStatus;
    }

这是它在桌面上的样子 - 注意文本行和开关的横向布局:

スタートアップ向けのモバイル Web エクスペリエンスの強化

这是移动版本,更加纵向且堆叠,无需媒体查询:

スタートアップ向けのモバイル Web エクスペリエンスの強化

作为示例,以下是我在“时间”面板上对表格列进行编码的 CSS: p>

table.table-list {
  width:100%;
}
table.table-list td.table-list-first {
    float: left;
    display: inline;
    width: auto;
  }
table.table-list td.table-switches {
    width: auto;
    float: right;
    display: inline;
    padding-top: 10px;
  }
.switch-pad {
    padding-left:7px;
  }
.smallStatus {
  font-size:90%;
  color: grey;
  font-style: italic;
}

这是来自 /frontend/views/meeting-time/_list.php 的部分表单的代码:

<?php
use yii\helpers\Html;
use frontend\models\Meeting;
use \kartik\switchinput\SwitchInput;
?>
<tr > <!-- panel row -->
  <td >
    <table class="table-list"> <!-- list of times -->
      <tr>
        <td class="table-list-first"> <!-- time & status -->
          <?= Meeting::friendlyDateFromTimestamp($model->start,$timezone) ?>
          <?php
            if ($whenStatus['text'][$model->id]<>'') {
            ?>
            <br /><span class="smallStatus">
            <?php
            echo $whenStatus['text'][$model->id];
            ?>
          </span><br />
            <?php
            }
          ?>
      </td>
      <td class="table-switches"> <!-- col of switches to float right -->
        <table >
          <tr>
              <td >
                <?php
                   if ($isOwner) {
                     showTimeOwnerStatus($model,$isOwner);
                   } else {
                     showTimeParticipantStatus($model,$isOwner);
                   }
                ?>
              </td>
              <td class="switch-pad">
                  <?php
                  if ($timeCount>1) {
                    if ($model->status == $model::STATUS_SELECTED) {
                        $value = $model->id;
                    }    else {
                      $value = 0;
                    }
                    if ($isOwner || $participant_choose_date_time) {
                      // value has to match for switch to be on
                      echo SwitchInput::widget([
                          'type' => SwitchInput::RADIO,
                          'name' => 'time-chooser',
                          'items' => [
                              [ 'value' => $model->id],
                          ],
                          'value' => $value,
                          'pluginOptions' => [  'size' => 'mini','handleWidth'=>60,'onText' => '<i class="glyphicon glyphicon-ok"></i> choose','onColor' => 'success','offText'=>'<i class="glyphicon glyphicon-remove"></i>'], // $whenStatus['style'][$model->id],
                          'labelOptions' => ['style' => 'font-size: 12px'],
                      ]);
                    }
                  }
                  ?>
              </td>
            </tr>
          </table>
        </td> <!-- end col with table of switches -->
      </tr>
  </table> <!-- end table list of times -->
  </td>
  </tr> <!-- end panel row -->

这些会议视图变化的最大好处是,它们将简化未来有许多参与者的会议的用户体验设计挑战。无论参加会议的人数有多少,观点都会与上述基本相同。从本质上讲,这解决了我扩展到多人会议的最大障碍——用户体验设计。

下一步是什么?

我希望您喜欢跟随我研究响应式网页设计的细节。当网站的代码和视觉变化结合在一起时,我感到非常满意,并且对 CSS 的需要之少印象深刻。综合起来,您可以在这里看到:

.rwd-break {
  display:none;
}
table.table-list {
  width:100%;
}
table.table-list td.table-list-first {
    float: left;
    display: inline;
    width: auto;
  }

table.table-list td.table-switches {
    width: auto;
    float: right;
    display: inline;
    padding-top: 10px;
  }
.switch-pad {
    padding-left:7px;
  }
.smallStatus {
  font-size:90%;
  color: grey;
  font-style: italic;
}
.setting-label label, #preferences label {
  font-weight:normal;
}

/* ----------- mobile displays ----------- */

@media only screen
  and (min-device-width: 320px)
  and (max-device-width: 667px)
  and (-webkit-min-device-pixel-ratio: 2) {
    /* hides drop down menu items and footer items */
    .itemHide,li.menuHide {
      display:none;
      visible:false;
    }
    /* removes home and / from breadcrumb */
    ul.breadcrumb li:first-child, li.tabHide {
      display:none;
      visible:false;
    }
     ul.breadcrumb li:nth-child(2)::before {
       content:'';
    }
    /* fingertip spacing for buttons */
    a.icon-pad {
      padding: 0 5px 0 2px;
    }
    .button-pad {
      padding-left:7px;
    }
    .rwd-break {
      display:block;
    }
}

我未来的设计工作将从“这在移动设备上看起来应该是什么样子?”

如前所述,我目前正在积极准备 Meeting Planner 的 alpha 版本。我主要关注使 alpha 版本顺利发布的关键改进和功能。

我现在正在跟踪 Asana 中的所有内容,我将在另一个教程中对此进行介绍;这非常有帮助。还有一些有趣的新功能仍在开发中。

また、Meeting Planner を通じた今後の投資回収活動にもより注意を払うようになりました。 SEC の新しいクラウドファンディング ルールの実装に伴い、WeFunder を試し始めたところです。プロフィールのフォローをご検討ください。これについては、今後のチュートリアルでも詳しく説明します。

繰り返しますが、さらなるエピソードを待っている間に、最初のミーティングを (電話で!) スケジュールしてください。また、以下のコメント欄であなたの経験を共有していただければ幸いです。私は常にあなたの提案に興味を持っています。 Twitter @reifman で直接私にご連絡いただくこともできます。ミーティング プランナー サポート Web サイトに投稿することもできます。

「Build Your Startup with PHP」シリーズの今後のチュートリアルをご覧ください。

###関連リンク###

会議の計画
  • ミーティングプランナーの「We Fund」ページ
  • Yii2 によるプログラミング: はじめに
  • Yii2 開発者交流会

以上がスタートアップ向けのモバイル Web エクスペリエンスの強化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。