沒穿方服

首頁

可能在打 12 月商戰,搜尋商品被帶到 momo「店+」的頁面,又被手機版面傷到眼睛。
網址長得像這樣: www.momoshop.com.tw/TP/TP0003616/goodsDetail/TP00036160000057?entpCode=略

在桌面大螢幕看針對 App 做的版面,傷眼 點到行銷頁也會被 App 限定擋住

momo 不尊重桌面版(電腦版)使用者

很久以前點到手機版(.m 開頭)連結就死不做轉向或改善,經查 mo店+ 是今年三月上線的營運模式,APP 限定,現在年底了,網址散布開來了還是不改,你用桌面版點進來是你的問題,沒有要服務你。

更新 user script

更新之前寫的 MOMO 購物網「切換至桌面版」user script,現在會偵測店+ 網址,但無法導到桌面連結(因為不存在),點按鈕只會調整 <body> 寬度,讓版面正常一點點。

也幫按鈕增加一點表情。

一般按鈕 / 偵測到店+ 的按鈕 / 生氣膨脹的按鈕

Web 愛好者應該減少用 momo 買東西。

滑鼠點兩下選取一個字詞(word)的功能,在 Windows 下預設會包含字後面的空白,無視 DOM 元素邊界,還會把全形空白包進去。

平時不太會察覺,發現時往往不舒服,例如:

這個行為在 Chrome 也是一樣,但好像無解,只有 Firefox 可以用 about:config 改掉:

layout.word_select.eat_space_to_next_word 改成 false就可以了,參考


其他跟選取空白有關的選項:

  • layout.word_select.stop_at_punctuation

    不要包含標點符號,預設 true

  • layout.word_select.stop_at_underscore

    不要包含底線,預設 false

  • editor.word_select.delete_space_after_doubleclick_selection

    編輯文字時,點兩下選取後再刪除,會把字前後的空白也刪掉,若不是點兩下選取就沒有效果,預設 false
    參考 Bug 由來

這篇不是什麼新知,只是我第一次處理,覺得比看起來容易,希望改善「看起來比較難」情況。

村里邊界,右下文字部分要自己處理 mouse 事件

整個處理大致都被 GeoJSON 包裝好了

原本沒碰過 GeoJSON,自己想像要處理區塊框線、互動,以為要折磨很多事;但其實在 Leaflet 裡可以看成載入一個 GeoJSON 資源,再用 addTo(map) 掛上去就結束了。

建立與顯示:

const layer = Leaflet.geoJSON(data as GeoJsonObject, options);
layer.addTo(map);

外觀、互動行為等,可以用 options 去調,以下是一個 options 物件:

{
  style: () => ({
    fill: false,
  }),
  onEachFeature: function (feat: Feature, layer: Path) {
    layer.on('mouseover', function () {
      layer.setStyle({ fill: true });
    });
    layer.on('mouseout', function () {
      layer.setStyle({ fill: false });
    });
  },
}

要關閉圖層,就 remove 掉:

layer.removeFrom(map);


取得地圖資料

另一個問題是圖資怎麼來,首選當然是內政部的開放資料:
縣市界:鄉鎮市區界線(TWD97經緯度)、村(里)界:村里界圖(TWD97經緯度)

但要怎麼轉成 GeoJSON 格式?尋找現成整理好的,似乎都失連,或看起來有點年代,幸好裡面原理沒變,參考 jason2506/Taiwan.TopoJSON,它是用 mapshaper 將 .shp 轉為 .geojson。

具體指令例,縣市:

mapshaper raw/COUNTY_MOI_1090820.shp -simplify interval=400 \
  -filter 'COUNTYNAME !== "金門縣" && COUNTYNAME !== "連江縣"' \
  -rename-fields name=COUNTYNAME -filter-fields name \
  -o format=geojson precision=0.0001 \
  counties.geojson

村里:

mapshaper raw/VILLAGE_NLSC_1130807.shp -simplify interval=30 \
  -rename-fields id=VILLCODE \
  -verbose \
  -filter 'COUNTYNAME !== "金門縣" && COUNTYNAME !== "連江縣"' \
  -each 'name=TOWNNAME + " " + VILLNAME' -filter-fields id,name \
  -o format=geojson precision=0.0001 \
  villages.geojson

其中 -simplify interval=precision 參數可以控制產出的精細度,也決定了檔案大小。 上面範例出來的結果是 61.35 KB 和 7.21 MB,後者檔案很大,但其實掛在 Cloudflare R2,在 HTTP/2 和壓縮加持下傳輸量只有 1.7 MB,使用上是沒什麼問題的。

利用植物偽裝。隨便撿一塊黃牌是方便監視用的,下次可以換成狗比較看不見的紅或綠色 據說王太太也是用烤雞捕狗

今年八月鎖定一隻個性激動,愛吠愛淋雨的大白,基於之前動保處人員說他們也會結紮公犬,會比較乖之類的(有這種事?),就蒐證請求處理,結果又回一些沒用的話,爭取後結論是動保處只能出借誘捕籠,民眾要自己捕捉,誘餌也要自己準備。

在「精準捕捉」這個奇葩政策下,就是幾乎已經放棄捕犬。 反正我也沒親身用過(犬)誘捕籠,聽里長說之前放都被人偷開或破壞,就讓我來實驗看看吧。

結果放了將近一個月(通常大概只能借一個禮拜),曾經目睹大白接近,甚至鑽進去把食物叼出來(身手真好),但最後只抓到另一隻近期新來的乖乖狗,近看才確認是已紮母犬,只好放走,放狗混帳竟是我自己。

尖耳黃臉黑,蠻漂亮的 買鹹酥雞的一晚,加菜是意外

以下重點回顧,下次我有信心成功:

  • 位置很重要:隱密、容易監視、降低狗戒心

    這次我優先考量隱密性(防小人),但放一兩天發現狗不靠近,才換到稍微開放的地方,之後接觸率就增加了。

    一個人搬誘捕籠要用背負、扛的,有點難度,但後來看動保處大哥也是扛出去才拆解上車,所以這作法應該正確。

  • 清空餵食者放的食物

    當時有一位隱藏的大餵食者會深夜偷丟大包雞骨,還有一些零星亂餵的人,因為在誘捕我就清得很勤,結果狗的出現率就遞減,這之間要抓一個平衡,在狗絕跡前速戰速決。

  • 投其所好

    當然要針對狗的個性誘捕,這群狗的偏好第一是雞脖子,再來就是雞骨人丟的骨架內臟,至於狗罐頭、貓食甚至鹹酥雞,似乎都激不起衝動,沒有被吃。

  • 關鍵的掛鏈

    這次最飲恨的就是沒有先摸熟這個機關,連結「踏板的掛鏈」和「掉落門的長桿」的部分,決定了踏板的敏感度,如果這個鏈條掛得太靠外面(籠子外面),會變成踩到踏板也不會觸發關門,大白可能就是這樣才逍遙法外。

從 react-masonry-css 示例

註 1:這篇談的是 2020 前的 CSS 解法 (flexbox),且使用 react-masonry-css 這個老套件,並非新的 JS 解或還未定案的 CSS 標準(參考),目前(2024)看來,舊方法還是有適用的地方。

註 2:能調整的前提是每個元素的高度已知。

以 CSS 為主的解法,看中的是單純性和效能,避免頻繁計算每個元素的實際尺寸,而缺點如下:

  • 排序問題,因為以多個 column「直行」為容器,所以元素其實是由上排到下,而不是由左到右。
    這點在 react-masonry-css 是用 JS 硬把元素分配給各個 column 解決。
  • 高度不均。因為根本沒有考慮元素的高度,當然避免不了有的 column 特別長或短的問題。
    具體可以看 issue #73 中的附圖:very different columns height - paulcollett/react-masonry-css

針對高度不均,造成底部有很大落差不齊的情況,折衷辦法是預先給予每個元素「高度」的參考,類似給每個 <img> 賦予已知的 height 值;然後再用 JS 計算累積高度,最後搬動特別突出的元素,直到無法再用搬動方式改善為止。

實作也很單純,主要價值還是知道多做這一小步,就能得到不少改善。

程式碼參考我的 fork: bootleq/react-masonry-css at forker,具體在 balanceColumnsmoveOddItem 兩個函數:
react-masonry-css/src/react-masonry-css.js at 4866d3596#L72